Files
2026-02-21 16:45:37 +08:00

147 lines
3.0 KiB
C#

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<int, CachedMeshSet> _Cache = new Dictionary<int, CachedMeshSet>(Int32EqualityComparer.Default);
private List<int> _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<int>();
}
Dictionary<int, CachedMeshSet>.Enumerator enumerator = _Cache.GetEnumerator();
while (enumerator.MoveNext())
{
KeyValuePair<int, CachedMeshSet> 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)
{
}
}
}