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);
- }
- }
- }
|