using System; using System.Collections.Generic; using UnityEngine; namespace UltimateWater.Internal { [Serializable] public abstract class WaterPrimitiveBase { protected class CachedMeshSet { public Mesh[] Meshes; public int LastFrameUsed; public CachedMeshSet(Mesh[] meshes) { Meshes = meshes; Update(); } public void Update() { LastFrameUsed = Time.frameCount; } } protected Water _Water; protected Dictionary _Cache = new Dictionary(Int32EqualityComparer.Default); private List _KeysToRemove; public virtual Mesh[] GetTransformedMeshes(Camera camera, out Matrix4x4 matrix, int vertexCount, bool volume) { matrix = ((!(camera != null)) ? Matrix4x4.identity : GetMatrix(camera)); int num = vertexCount; if (volume) { num = -num; } CachedMeshSet value; if (!_Cache.TryGetValue(num, out value)) { value = (_Cache[num] = new CachedMeshSet(CreateMeshes(vertexCount, volume))); } else { value.Update(); } return value.Meshes; } public void Dispose() { foreach (CachedMeshSet value in _Cache.Values) { Mesh[] meshes = value.Meshes; foreach (Mesh obj in meshes) { if (Application.isPlaying) { UnityEngine.Object.Destroy(obj); } else { UnityEngine.Object.DestroyImmediate(obj); } } } _Cache.Clear(); } protected abstract Matrix4x4 GetMatrix(Camera camera); protected abstract Mesh[] CreateMeshes(int vertexCount, bool volume); protected Mesh CreateMesh(Vector3[] vertices, int[] indices, string name, bool triangular = false) { Mesh mesh = new Mesh(); mesh.hideFlags = HideFlags.DontSave; mesh.name = name; mesh.vertices = vertices; Mesh mesh2 = mesh; mesh2.SetIndices(indices, (!triangular) ? MeshTopology.Quads : MeshTopology.Triangles, 0); mesh2.RecalculateBounds(); mesh2.UploadMeshData(true); return mesh2; } internal void Update() { int frameCount = Time.frameCount; if (_KeysToRemove == null) { _KeysToRemove = new List(); } Dictionary.Enumerator enumerator = _Cache.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; if (frameCount - current.Value.LastFrameUsed <= 27) { continue; } _KeysToRemove.Add(current.Key); Mesh[] meshes = current.Value.Meshes; foreach (Mesh obj in meshes) { if (Application.isPlaying) { UnityEngine.Object.Destroy(obj); } else { UnityEngine.Object.DestroyImmediate(obj); } } } enumerator.Dispose(); for (int j = 0; j < _KeysToRemove.Count; j++) { _Cache.Remove(_KeysToRemove[j]); } _KeysToRemove.Clear(); } internal virtual void OnEnable(Water water) { _Water = water; } internal virtual void OnDisable() { Dispose(); } internal virtual void AddToMaterial(Water water) { } internal virtual void RemoveFromMaterial(Water water) { } } }