274 lines
6.9 KiB
C#
274 lines
6.9 KiB
C#
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<MegaCacheImageFrame> frames = new List<MegaCacheImageFrame>();
|
|
|
|
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;
|
|
}
|
|
}
|