| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 | using System;using System.Collections.Generic;using System.Reflection;using UnityEngine;using Object = UnityEngine.Object;namespace Coffee.UIParticleExtensions{    internal static class SpriteExtensions    {#if UNITY_EDITOR        private static Type tSpriteEditorExtension =            Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")            ?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");        private static MethodInfo miGetActiveAtlasTexture = tSpriteEditorExtension            .GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);        public static Texture2D GetActualTexture(this Sprite self)        {            if (!self) return null;            if (Application.isPlaying) return self.texture;            var ret = miGetActiveAtlasTexture.Invoke(null, new[] {self}) as Texture2D;            return ret ? ret : self.texture;        }#else        internal static Texture2D GetActualTexture(this Sprite self)        {            return self ? self.texture : null;        }#endif    }    internal static class ListExtensions    {        public static bool SequenceEqualFast(this List<bool> self, List<bool> value)        {            if (self.Count != value.Count) return false;            for (var i = 0; i < self.Count; ++i)            {                if (self[i] != value[i]) return false;            }            return true;        }        public static int CountFast(this List<bool> self)        {            var count = 0;            for (var i = 0; i < self.Count; ++i)            {                if (self[i]) count++;            }            return count;        }        public static bool AnyFast<T>(this List<T> self) where T : Object        {            for (var i = 0; i < self.Count; ++i)            {                if (self[i]) return true;            }            return false;        }        public static bool AnyFast<T>(this List<T> self, Predicate<T> predicate) where T : Object        {            for (var i = 0; i < self.Count; ++i)            {                if (self[i] && predicate(self[i])) return true;            }            return false;        }    }    internal static class MeshExtensions    {        // static readonly List<Color32> s_Colors = new List<Color32>();        // public static void ModifyColorSpaceToLinear(this Mesh self)        // {        //     self.GetColors(s_Colors);        //        //     for (var i = 0; i < s_Colors.Count; i++)        //         s_Colors[i] = ((Color) s_Colors[i]).gamma;        //        //     self.SetColors(s_Colors);        //     s_Colors.Clear();        // }        public static void Clear(this CombineInstance[] self)        {            for (var i = 0; i < self.Length; i++)            {                MeshPool.Return(self[i].mesh);                self[i].mesh = null;            }        }    }    internal static class MeshPool    {        private static readonly Stack<Mesh> s_Pool = new Stack<Mesh>(32);        private static readonly HashSet<int> s_HashPool = new HashSet<int>();        public static void Init()        {        }        static MeshPool()        {            for (var i = 0; i < 32; i++)            {                var m = new Mesh();                m.MarkDynamic();                s_Pool.Push(m);                s_HashPool.Add(m.GetInstanceID());            }        }        public static Mesh Rent()        {            Mesh m;            while (0 < s_Pool.Count)            {                m = s_Pool.Pop();                if (m)                {                    s_HashPool.Remove(m.GetInstanceID());                    return m;                }            }            m = new Mesh();            m.MarkDynamic();            return m;        }        public static void Return(Mesh mesh)        {            if (!mesh) return;            var id = mesh.GetInstanceID();            if (s_HashPool.Contains(id)) return;            mesh.Clear(false);            s_Pool.Push(mesh);            s_HashPool.Add(id);        }    }    internal static class CombineInstanceArrayPool    {        private static readonly Dictionary<int, CombineInstance[]> s_Pool;        public static void Init()        {            s_Pool.Clear();        }        static CombineInstanceArrayPool()        {            s_Pool = new Dictionary<int, CombineInstance[]>();        }        public static CombineInstance[] Get(List<CombineInstance> src)        {            CombineInstance[] dst;            var count = src.Count;            if (!s_Pool.TryGetValue(count, out dst))            {                dst = new CombineInstance[count];                s_Pool.Add(count, dst);            }            for (var i = 0; i < src.Count; i++)            {                dst[i].mesh = src[i].mesh;                dst[i].transform = src[i].transform;            }            return dst;        }        public static CombineInstance[] Get(List<CombineInstanceEx> src, int count)        {            CombineInstance[] dst;            if (!s_Pool.TryGetValue(count, out dst))            {                dst = new CombineInstance[count];                s_Pool.Add(count, dst);            }            for (var i = 0; i < count; i++)            {                dst[i].mesh = src[i].mesh;                dst[i].transform = src[i].transform;            }            return dst;        }    }    internal static class ParticleSystemExtensions    {        public static void SortForRendering(this List<ParticleSystem> self, Transform transform, bool sortByMaterial)        {            self.Sort((a, b) =>            {                var tr = transform;                var aRenderer = a.GetComponent<ParticleSystemRenderer>();                var bRenderer = b.GetComponent<ParticleSystemRenderer>();                // Render queue: ascending                var aMat = aRenderer.sharedMaterial ?? aRenderer.trailMaterial;                var bMat = bRenderer.sharedMaterial ?? bRenderer.trailMaterial;                if (!aMat && !bMat) return 0;                if (!aMat) return -1;                if (!bMat) return 1;                if (sortByMaterial)                    return aMat.GetInstanceID() - bMat.GetInstanceID();                if (aMat.renderQueue != bMat.renderQueue)                    return aMat.renderQueue - bMat.renderQueue;                // Sorting layer: ascending                if (aRenderer.sortingLayerID != bRenderer.sortingLayerID)                    return aRenderer.sortingLayerID - bRenderer.sortingLayerID;                // Sorting order: ascending                if (aRenderer.sortingOrder != bRenderer.sortingOrder)                    return aRenderer.sortingOrder - bRenderer.sortingOrder;                // Z position & sortingFudge: descending                var aTransform = a.transform;                var bTransform = b.transform;                var aPos = tr.InverseTransformPoint(aTransform.position).z + aRenderer.sortingFudge;                var bPos = tr.InverseTransformPoint(bTransform.position).z + bRenderer.sortingFudge;                if (!Mathf.Approximately(aPos, bPos))                    return (int) Mathf.Sign(bPos - aPos);                return (int) Mathf.Sign(GetIndex(self, a) - GetIndex(self, b));            });        }        private static int GetIndex(IList<ParticleSystem> list, Object ps)        {            for (var i = 0; i < list.Count; i++)            {                if (list[i].GetInstanceID() == ps.GetInstanceID()) return i;            }            return 0;        }        public static long GetMaterialHash(this ParticleSystem self, bool trail)        {            if (!self) return 0;            var r = self.GetComponent<ParticleSystemRenderer>();            var mat = trail ? r.trailMaterial : r.sharedMaterial;            if (!mat) return 0;            var tex = trail ? null : self.GetTextureForSprite();            return ((long) mat.GetHashCode() << 32) + (tex ? tex.GetHashCode() : 0);        }        public static Texture2D GetTextureForSprite(this ParticleSystem self)        {            if (!self) return null;            // Get sprite's texture.            var tsaModule = self.textureSheetAnimation;            if (!tsaModule.enabled || tsaModule.mode != ParticleSystemAnimationMode.Sprites) return null;            for (var i = 0; i < tsaModule.spriteCount; i++)            {                var sprite = tsaModule.GetSprite(i);                if (!sprite) continue;                return sprite.GetActualTexture();            }            return null;        }        public static void Exec(this List<ParticleSystem> self, Action<ParticleSystem> action)        {            self.RemoveAll(p => !p);            self.ForEach(action);        }    }}
 |