using System; using System.Collections.Generic; using System.Threading; using UnityEngine; [Serializable] public class MegaCacheImage : ScriptableObject { public class MegaCacheOBJTaskInfo { public string name; public AutoResetEvent pauseevent; public Thread _thread; public MegaCacheOBJ objcache; public int end; public int frame; } public List frames = new List(); public int maxsm; public int maxv; public int maxtris; public int[] smfc; public int lastframe = -1; public int preloaded = -1; public int memoryuse; public bool threadupdate; public int Cores = 1; private static bool isRunning; private MegaCacheOBJTaskInfo[] tasks; private void MakeThreads(MegaCacheOBJ cache) { if (Cores > 0) { isRunning = true; tasks = new MegaCacheOBJTaskInfo[Cores]; for (int i = 0; i < Cores; i++) { tasks[i] = new MegaCacheOBJTaskInfo(); tasks[i].objcache = cache; tasks[i].name = "ThreadID " + i; tasks[i].pauseevent = new AutoResetEvent(false); tasks[i]._thread = new Thread(DoWork); tasks[i]._thread.Start(tasks[i]); } } } private void DoWork(object info) { MegaCacheOBJTaskInfo megaCacheOBJTaskInfo = (MegaCacheOBJTaskInfo)info; while (isRunning) { megaCacheOBJTaskInfo.pauseevent.WaitOne(-1, false); if (megaCacheOBJTaskInfo.end > 0) { PreLoad(megaCacheOBJTaskInfo.frame, megaCacheOBJTaskInfo.objcache); } megaCacheOBJTaskInfo.end = 0; } } public void GetNextFrame(MegaCacheOBJ cache, int frame) { if (Cores == 0) { Cores = SystemInfo.processorCount - 1; } if (Cores < 1 || !Application.isPlaying) { return; } if (tasks == null) { MakeThreads(cache); } if (Cores > 0) { for (int i = 0; i < tasks.Length; i++) { tasks[i].objcache = cache; tasks[i].end = 1; tasks[i].frame = frame; } for (int j = 0; j < tasks.Length; j++) { tasks[j].pauseevent.Set(); } } } private void OnDestroy() { if (!Application.isPlaying) { return; } isRunning = false; if (tasks != null) { for (int i = 0; i < tasks.Length; i++) { tasks[i].pauseevent.Set(); while (tasks[i]._thread.IsAlive) { } } } tasks = null; } public void PreLoad(int frame, MegaCacheOBJ cache) { if (frame != preloaded) { preloaded = frame; frames[frame].LoadSection(cache); } } public void GetMesh(Mesh mesh, int frame, MegaCacheOBJ cache) { if (threadupdate && Application.isPlaying) { GetMeshPreLoaded(mesh, frame, cache); } else if (frame != lastframe) { lastframe = frame; frames[frame].GetMesh(mesh, cache); } } public void GetMeshPreLoaded(Mesh mesh, int frame, MegaCacheOBJ cache) { if (frame != lastframe) { if (frame == preloaded) { frames[frame].SetMesh(mesh, cache); } else { frames[frame].GetMesh(mesh, cache); } int num = frame + 1; if (num >= frames.Count) { num = 0; } GetNextFrame(cache, num); lastframe = frame; } } public int CalcMemory() { int num = 0; for (int i = 0; i < frames.Count; i++) { MegaCacheImageFrame megaCacheImageFrame = frames[i]; num += megaCacheImageFrame.verts.Length; num += megaCacheImageFrame.norms.Length; num += megaCacheImageFrame.tangents.Length; num += megaCacheImageFrame.uvs.Length; num += megaCacheImageFrame.tris.Length; num += megaCacheImageFrame.suboffs.Length * 2; num += megaCacheImageFrame.sublen.Length * 2; } memoryuse = num; return num; } public static MegaCacheImageFrame CreateImageFrame(Mesh ms) { MegaCacheImageFrame megaCacheImageFrame = new MegaCacheImageFrame(); Vector3[] vertices = ms.vertices; Vector3[] normals = ms.normals; Vector2[] uv = ms.uv; Vector4[] tangents = ms.tangents; megaCacheImageFrame.vc = vertices.Length; megaCacheImageFrame.nc = normals.Length; megaCacheImageFrame.tc = tangents.Length; megaCacheImageFrame.uvc = uv.Length; megaCacheImageFrame.bmin = ms.bounds.min; Vector3 size = ms.bounds.size; megaCacheImageFrame.bsize = ms.bounds.size * 1.5259022E-05f; Bounds bounds = MegaCacheUtils.GetBounds(uv); megaCacheImageFrame.uvmin = bounds.min; megaCacheImageFrame.uvsize = bounds.size * 0.003921569f; megaCacheImageFrame.verts = new byte[megaCacheImageFrame.vc * 6]; megaCacheImageFrame.norms = new byte[megaCacheImageFrame.nc * 3]; megaCacheImageFrame.tangents = new byte[megaCacheImageFrame.tc * 4]; megaCacheImageFrame.uvs = new byte[megaCacheImageFrame.vc * 2]; megaCacheImageFrame.tris = new byte[ms.triangles.Length * 2]; int num = 0; for (int i = 0; i < vertices.Length; i++) { Vector3 vector = vertices[i]; short value = (short)((vector.x - megaCacheImageFrame.bmin.x) / size.x * 65535f); byte[] bytes = BitConverter.GetBytes(value); megaCacheImageFrame.verts[num++] = bytes[0]; megaCacheImageFrame.verts[num++] = bytes[1]; value = (short)((vector.y - megaCacheImageFrame.bmin.y) / size.y * 65535f); bytes = BitConverter.GetBytes(value); megaCacheImageFrame.verts[num++] = bytes[0]; megaCacheImageFrame.verts[num++] = bytes[1]; value = (short)((vector.z - megaCacheImageFrame.bmin.z) / size.z * 65535f); bytes = BitConverter.GetBytes(value); megaCacheImageFrame.verts[num++] = bytes[0]; megaCacheImageFrame.verts[num++] = bytes[1]; } num = 0; for (int j = 0; j < normals.Length; j++) { Vector3 vector2 = normals[j]; megaCacheImageFrame.norms[num++] = (byte)((vector2.x + 1f) * 127f); megaCacheImageFrame.norms[num++] = (byte)((vector2.y + 1f) * 127f); megaCacheImageFrame.norms[num++] = (byte)((vector2.z + 1f) * 127f); } num = 0; for (int k = 0; k < tangents.Length; k++) { Vector4 vector3 = tangents[k]; megaCacheImageFrame.tangents[num++] = (byte)((vector3.x + 1f) * 127f); megaCacheImageFrame.tangents[num++] = (byte)((vector3.y + 1f) * 127f); megaCacheImageFrame.tangents[num++] = (byte)((vector3.z + 1f) * 127f); megaCacheImageFrame.tangents[num++] = (byte)((vector3.w + 1f) * 127f); } num = 0; for (int l = 0; l < uv.Length; l++) { Vector2 vector4 = uv[l]; megaCacheImageFrame.uvs[num++] = (byte)((vector4.x - bounds.min.x) / bounds.size.x * 255f); megaCacheImageFrame.uvs[num++] = (byte)((vector4.y - bounds.min.y) / bounds.size.y * 255f); } megaCacheImageFrame.subcount = ms.subMeshCount; megaCacheImageFrame.suboffs = new int[megaCacheImageFrame.subcount]; megaCacheImageFrame.sublen = new int[megaCacheImageFrame.subcount]; num = 0; for (int m = 0; m < megaCacheImageFrame.subcount; m++) { int[] triangles = ms.GetTriangles(m); megaCacheImageFrame.suboffs[m] = num; megaCacheImageFrame.sublen[m] = triangles.Length; for (int n = 0; n < triangles.Length; n++) { short value2 = (short)triangles[n]; byte[] bytes = BitConverter.GetBytes(value2); megaCacheImageFrame.tris[num++] = bytes[0]; megaCacheImageFrame.tris[num++] = bytes[1]; } } return megaCacheImageFrame; } }