Files
Studio/Assets/Scripts/XED/AssetTool/CustomAssetData.cs
2025-02-19 17:24:26 +09:00

177 lines
6.6 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TriLibCore;
using UnityEngine;
using UnityEngine.Events;
namespace XED.Util
{
public class CustomAssetData : UnityEngine.MonoBehaviour
{
public string assetName;
public string folderName;
public string localFBXPath;
public string localDataPath;
public string remoteFBXPath;
public string remoteDataPath;
public GameObject loadedObject;
public bool isLoadComplete = false;
public bool isLoadError = false;
public bool isLoading = false;
public float progress;
public List<Transform> drawTransforms = new List<Transform>();
public UnityEvent<float> onLoadProgress = new UnityEvent<float>();
private AssetLoaderOptions assetLoaderOptions;
private MatrixConverter matrixConverter;
private List<AssetMeshData> meshDatas = new List<AssetMeshData>();
private Matrix4x4[] matrices = new Matrix4x4[0];
private Bounds combinedBounds = new Bounds(new Vector3(0, 0.5f, 0), Vector3.one);
// Start is called before the first frame update
void Start()
{
assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions(false, true);
matrixConverter = new MatrixConverter();
}
// Update is called once per frame
//void Update()
//{
// DrawMeshInstancedOnUpdate();
//}
private void OnDestroy()
{
Destroy(loadedObject);
}
private void DrawMeshInstancedOnUpdate()
{
if (matrices.Length > 0 && meshDatas.Count > 0)
{
for (int i = 0; i < meshDatas.Count; i++)
{
AssetMeshData data = meshDatas[i];
for (int submeshIndex = 0; submeshIndex < data.mesh.subMeshCount; submeshIndex++)
{
if (submeshIndex < data.materials.Length)
{
Graphics.DrawMeshInstanced(data.mesh, submeshIndex, data.materials[submeshIndex], matrixConverter.ConvertToMatrixArray(data.meshMatrix, matrices));
}
}
}
}
}
private void OnError(IContextualizedError obj)
{
isLoadError = true;
Debug.LogError($"An error occurred while loading your Model: {obj.GetInnerException()}");
}
private void OnProgress(AssetLoaderContext assetLoaderContext, float progress)
{
isLoading = true;
this.progress = progress;
if (isLoadComplete == false && progress < 1.0f)
{
onLoadProgress?.Invoke(progress);
}
Debug.Log($"Loading Model. Progress: {progress:P}");
}
private void OnMaterialsLoad(AssetLoaderContext assetLoaderContext)
{
loadedObject = assetLoaderContext.RootGameObject;
OnLoadComplete();
onLoadProgress?.Invoke(1.0f);
Debug.Log("Materials loaded. Model fully loaded.");
}
private void OnLoad(AssetLoaderContext assetLoaderContext)
{
Debug.Log("Model loaded. Loading materials.");
}
public void OnLoadComplete()
{
isLoadComplete = true;
MeshFilter[] meshFilters = loadedObject.GetComponentsInChildren<MeshFilter>();
for (int i = 0; i < meshFilters.Length; i++)
{
MeshFilter filter = meshFilters[i];
MeshRenderer renderer = filter.GetComponent<MeshRenderer>();
if (i == 0)
{
combinedBounds = renderer.bounds;
}
else
{
combinedBounds.Encapsulate(renderer.bounds);
}
List<Material> materials = new List<Material>();
for (int k = 0; k < renderer.sharedMaterials.Length; k++)
{
Material mat = renderer.sharedMaterials[k];
if (mat.name.EndsWith("_alpha"))
{
string baseMaterialName = mat.name.Replace("_alpha", "");
if (renderer.sharedMaterials.Any(mat => mat.name == baseMaterialName))
{
continue;
}
}
mat.enableInstancing = true;
materials.Add(mat);
}
renderer.sharedMaterials = materials.ToArray();
AssetMeshData meshData = new AssetMeshData(filter.mesh, renderer.sharedMaterials, filter.transform);
meshDatas.Add(meshData);
}
loadedObject.SetActive(false);
}
public void LoadLocalFBX(string path)
{
localFBXPath = path;
AssetLoader.LoadModelFromFile(localFBXPath, OnLoad, OnMaterialsLoad, OnProgress, OnError, null, assetLoaderOptions);
}
public void AddTransformToRender(Transform transform)
{
if (drawTransforms.Contains(transform))
{
return;
}
drawTransforms.Add(transform);
matrices = matrixConverter.ConvertToMatrixArray(drawTransforms.ToArray());
}
public void RemoveTransform(Transform transform)
{
drawTransforms.Remove(transform);
matrices = matrixConverter.ConvertToMatrixArray(drawTransforms.ToArray());
}
public void OnTransformDataChanged()
{
matrices = matrixConverter.ConvertToMatrixArray(drawTransforms.ToArray());
}
public Bounds GetCombinedBoundary()
{
return combinedBounds;
}
public GameObject InstantiateLoadedObject(Transform parent)
{
if (loadedObject == null)
{
return null;
}
GameObject loadedObjectInstance = Instantiate(loadedObject, parent);
loadedObjectInstance.SetActive(true);
return loadedObjectInstance;
}
}
public class AssetMeshData
{
public Mesh mesh;
public Material[] materials;
public Matrix4x4 meshMatrix;
public AssetMeshData(Mesh mesh, Material[] materials, Transform meshTransform)
{
this.mesh = mesh;
this.materials = materials;
this.meshMatrix = Matrix4x4.TRS(meshTransform.position, meshTransform.rotation, meshTransform.lossyScale);
}
}
}