143 lines
5.7 KiB
C#
143 lines
5.7 KiB
C#
#nullable enable
|
|
using GLTFast;
|
|
using UnityEngine;
|
|
using System;
|
|
using System.Threading;
|
|
using Cysharp.Threading.Tasks;
|
|
using System.Collections.Generic;
|
|
|
|
namespace UVC.GLTF
|
|
{
|
|
public static class GLTFImporter
|
|
{
|
|
/// <summary>
|
|
/// glTF/glb 파일을 로드합니다.
|
|
/// </summary>
|
|
/// <param name="filePath">파일 경로</param>
|
|
/// <param name="parentTransform">부모 Transform</param>
|
|
/// <param name="useMsftLod">MSFT_lod 확장을 LODGroup으로 변환할지 여부</param>
|
|
public static async UniTask<GameObject?> ImportFromFile(string filePath, Transform parentTransform)
|
|
{
|
|
if (string.IsNullOrEmpty(filePath)) return null;
|
|
|
|
Debug.Log($"ImportFromFile {filePath}");
|
|
var gltf = new GltfImport();
|
|
var importSettings = new ImportSettings();
|
|
|
|
var success = await gltf.Load(filePath, importSettings);
|
|
|
|
if (!success)
|
|
{
|
|
Debug.LogError($"glTFast Load failed: {filePath}");
|
|
return null;
|
|
}
|
|
|
|
// MSFT_lod 사용 시 커스텀 인스턴시에이터 사용
|
|
GameObjectInstantiator instantiator;
|
|
// if (useMsftLod)
|
|
// {
|
|
// // glb/gltf 파일에서 MSFT_lod 정보 파싱
|
|
// var lodInfos = MsftLodParser.ParseFromFile(filePath);
|
|
// Debug.Log($"ImportFromFile: Found {lodInfos.Count} LOD definitions in {filePath}");
|
|
|
|
// var lodInstantiator = new LODGameObjectInstantiator(gltf, parentTransform);
|
|
// lodInstantiator.SetLodInfo(lodInfos);
|
|
// instantiator = lodInstantiator;
|
|
// }
|
|
// else
|
|
// {
|
|
instantiator = new GameObjectInstantiator(gltf, parentTransform);
|
|
// }
|
|
|
|
var sceneOk = await gltf.InstantiateMainSceneAsync(instantiator);
|
|
if (!sceneOk)
|
|
{
|
|
Debug.LogError($"InstantiateMainSceneAsync failed: {filePath}");
|
|
return null;
|
|
}
|
|
|
|
return instantiator.SceneTransform != null ? instantiator.SceneTransform.gameObject : null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 LOD 레벨의 glTF/glb 파일을 로드하고 LODGroup으로 설정합니다. 사용않함
|
|
/// </summary>
|
|
/// <param name="paths"></param>
|
|
/// <param name="parentTransform"></param>
|
|
/// <returns></returns>
|
|
public static async UniTask<GameObject?> ImportWithLOD(List<string> paths, Transform parentTransform)
|
|
{
|
|
if (paths == null || paths.Count == 0) return null;
|
|
|
|
// 1. 부모 객체 생성 (여기에 LODGroup 컴포넌트가 붙습니다)
|
|
GameObject rootObject = new GameObject("Loaded_LOD_Model");
|
|
rootObject.transform.position = Vector3.zero;
|
|
|
|
bool successAll = true;
|
|
List<GameObject> loadedObjects = new List<GameObject>();
|
|
|
|
foreach (var path in paths)
|
|
{
|
|
if (string.IsNullOrEmpty(path)) continue;
|
|
|
|
Debug.Log($"ImportFromWithLOD Loading {path}");
|
|
var gltf = new GltfImport();
|
|
var importSettings = new ImportSettings();
|
|
var success = await gltf.Load(path, importSettings);
|
|
if (!success)
|
|
{
|
|
Debug.LogError($"glTFast Load failed: {path}");
|
|
successAll = false;
|
|
break;
|
|
}
|
|
//path 이름만
|
|
string lodName = System.IO.Path.GetFileNameWithoutExtension(path);
|
|
GameObject gameObject = new GameObject(lodName);
|
|
gameObject.transform.SetParent(rootObject.transform, false);
|
|
var instantiator = new GameObjectInstantiator(gltf, gameObject.transform);
|
|
var sceneOk = await gltf.InstantiateMainSceneAsync(instantiator);
|
|
if (!sceneOk)
|
|
{
|
|
Debug.LogError($"InstantiateMainSceneAsync failed: {path}");
|
|
successAll = false;
|
|
break;
|
|
}
|
|
if(instantiator.SceneTransform != null){
|
|
loadedObjects.Add(gameObject);
|
|
}
|
|
}
|
|
|
|
if (successAll)
|
|
{
|
|
// 3. LODGroup 설정
|
|
var lodGroup = rootObject.AddComponent<LODGroup>();
|
|
LOD[] lods = new LOD[loadedObjects.Count];
|
|
float[] lodScreenPercentages = new float[] { 0.5f, 0.25f, 0.1f, 0f}; // 예시로 LOD 전환 비율 설정
|
|
for (int i = 0; i < loadedObjects.Count; i++)
|
|
{
|
|
Renderer? renderer = loadedObjects[i].GetComponent<Renderer>();
|
|
if(renderer == null)
|
|
{
|
|
renderer = loadedObjects[i].GetComponentInChildren<Renderer>();
|
|
}
|
|
|
|
float screenRelativeTransitionHeight = lodScreenPercentages[Mathf.Min(i, lodScreenPercentages.Length - 1)]; // LOD 전환 비율 설정 사용
|
|
Debug.Log($"{loadedObjects[i].name} LOD {i}: screenRelativeTransitionHeight={screenRelativeTransitionHeight}");
|
|
lods[i] = new LOD(screenRelativeTransitionHeight, new Renderer[]{renderer!});
|
|
}
|
|
lodGroup.SetLODs(lods);
|
|
lodGroup.RecalculateBounds(); // 바운딩 박스 재계산 (필수)
|
|
rootObject.transform.SetParent(parentTransform, false);
|
|
return rootObject;
|
|
}
|
|
else
|
|
{
|
|
GameObject.Destroy(rootObject);
|
|
return null;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
} |