212 lines
6.2 KiB
C#
212 lines
6.2 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.HLODSystem.Cache
|
|
{
|
|
class SimplifiedCache
|
|
{
|
|
private const string k_CachePath = "Assets/HLODSystem/Cache/";
|
|
|
|
struct GeneratingInfo
|
|
{
|
|
public Type Type;
|
|
public Mesh Mesh;
|
|
public float Quality;
|
|
};
|
|
|
|
List<GeneratingInfo> m_GeneratingInfos = new List<GeneratingInfo>();
|
|
|
|
#region Interface
|
|
public static void Clear()
|
|
{
|
|
Instance.ClearImpl();
|
|
}
|
|
|
|
public static void MarkGenerating(Type type, Mesh mesh, float quality)
|
|
{
|
|
Instance.m_GeneratingInfos.Add(new GeneratingInfo()
|
|
{
|
|
Type = type,
|
|
Mesh = mesh,
|
|
Quality = quality,
|
|
});
|
|
}
|
|
|
|
public static bool IsGenerating(Type type, Mesh mesh, float quality)
|
|
{
|
|
for (int i = 0; i < Instance.m_GeneratingInfos.Count; ++i)
|
|
{
|
|
if (Instance.m_GeneratingInfos[i].Type == type &&
|
|
Instance.m_GeneratingInfos[i].Mesh == mesh &&
|
|
Mathf.Abs(Instance.m_GeneratingInfos[i].Quality - quality) < 0.0001f )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void Update(Type simplifierType, Mesh originalMesh, Mesh simplifiedMesh, float qualtiy)
|
|
{
|
|
Instance.UpdateImpl(simplifierType, originalMesh, simplifiedMesh, qualtiy);
|
|
}
|
|
public static Mesh Get(Type simplifierType, Mesh mesh, float quality)
|
|
{
|
|
return Instance.GetImpl(simplifierType, mesh, quality);
|
|
}
|
|
#endregion
|
|
|
|
#region Singleton
|
|
private static SimplifiedCache s_Instance;
|
|
|
|
private static SimplifiedCache Instance
|
|
{
|
|
get
|
|
{
|
|
if (s_Instance == null)
|
|
s_Instance = new SimplifiedCache();
|
|
return s_Instance;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
private void ClearImpl()
|
|
{
|
|
DeleteDirectory(k_CachePath);
|
|
}
|
|
private void UpdateImpl(Type simplifiedType, Mesh originalMesh, Mesh simplifiedMesh, float quality)
|
|
{
|
|
string path = AssetDatabase.GetAssetPath(originalMesh);
|
|
string guid = AssetDatabase.AssetPathToGUID(path);
|
|
|
|
if (string.IsNullOrEmpty(guid) == true)
|
|
return;
|
|
|
|
DateTime time = System.IO.File.GetLastWriteTime(path);
|
|
SimplifiedMeshList meshList = GetMeshList(guid, time.ToFileTimeUtc());
|
|
var mesh = meshList.GetMesh(quality, simplifiedType);
|
|
if (mesh != null)
|
|
{
|
|
mesh.Mesh = simplifiedMesh;
|
|
}
|
|
else
|
|
{
|
|
meshList.AddMesh(quality, simplifiedType, simplifiedMesh);
|
|
}
|
|
|
|
AssetDatabase.AddObjectToAsset(simplifiedMesh, meshList);
|
|
EditorUtility.SetDirty(meshList);
|
|
|
|
for (int i = 0; i < m_GeneratingInfos.Count; ++i)
|
|
{
|
|
if (m_GeneratingInfos[i].Type == simplifiedType &&
|
|
m_GeneratingInfos[i].Mesh == originalMesh &&
|
|
Mathf.Abs(Instance.m_GeneratingInfos[i].Quality - quality) < 0.0001f)
|
|
{
|
|
m_GeneratingInfos.RemoveAt(i);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
private Mesh GetImpl(Type simplifierType, Mesh mesh, float quality)
|
|
{
|
|
string path = AssetDatabase.GetAssetPath(mesh);
|
|
string guid = AssetDatabase.AssetPathToGUID(path);
|
|
|
|
if (string.IsNullOrEmpty(guid) == true)
|
|
return null;
|
|
|
|
DateTime time = System.IO.File.GetLastWriteTime(path);
|
|
|
|
return GetMesh(simplifierType, mesh, quality, guid, time.ToFileTimeUtc());
|
|
}
|
|
|
|
private Mesh GetMesh(Type simplifiedType, Mesh source, float quality, string guid, long time)
|
|
{
|
|
SimplifiedMeshList meshList = GetMeshList(guid, time);
|
|
|
|
var mesh = meshList.GetMesh(quality, simplifiedType);
|
|
if (mesh != null)
|
|
{
|
|
return mesh.Mesh;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private SimplifiedMeshList GetMeshList(string guid, long time)
|
|
{
|
|
var meshList = LoadMeshList(guid);
|
|
if (meshList == null || meshList.Timestamp != time)
|
|
{
|
|
RemoveMeshList(guid);
|
|
meshList = NewMeshList(guid, time);
|
|
}
|
|
|
|
return meshList;
|
|
}
|
|
|
|
private SimplifiedMeshList NewMeshList(string guid, long time)
|
|
{
|
|
SimplifiedMeshList meshList = SimplifiedMeshList.CreateInstance<SimplifiedMeshList>();
|
|
meshList.Timestamp = time;
|
|
meshList.name = guid;
|
|
|
|
string path = GetAssetPath(guid);
|
|
string dir = Path.GetDirectoryName(path);
|
|
if (Directory.Exists(dir) == false)
|
|
{
|
|
Directory.CreateDirectory(dir);
|
|
}
|
|
|
|
AssetDatabase.CreateAsset(meshList, path);
|
|
return meshList;
|
|
}
|
|
private SimplifiedMeshList LoadMeshList(string guid)
|
|
{
|
|
string path = GetAssetPath(guid);
|
|
if (System.IO.File.Exists(path) == false)
|
|
return null;
|
|
|
|
return AssetDatabase.LoadAssetAtPath<SimplifiedMeshList>(path);
|
|
}
|
|
|
|
private void RemoveMeshList(string guid)
|
|
{
|
|
string path = GetAssetPath(guid);
|
|
AssetDatabase.DeleteAsset(path);
|
|
}
|
|
|
|
|
|
private string GetAssetPath(string guid)
|
|
{
|
|
return k_CachePath + guid + ".asset";
|
|
}
|
|
|
|
public static void DeleteDirectory(string path)
|
|
{
|
|
if (Directory.Exists(path) == false)
|
|
return;
|
|
|
|
DirectoryInfo di = new DirectoryInfo(path);
|
|
|
|
foreach (FileInfo file in di.GetFiles())
|
|
{
|
|
file.Delete();
|
|
}
|
|
|
|
foreach (DirectoryInfo dir in di.GetDirectories())
|
|
{
|
|
DeleteDirectory(dir.FullName);
|
|
}
|
|
|
|
di.Delete();
|
|
|
|
}
|
|
}
|
|
}
|