177 lines
6.6 KiB
C#
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);
|
|
}
|
|
}
|
|
} |