189 lines
6.0 KiB
C#
189 lines
6.0 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using VRMShaders;
|
|
|
|
namespace UniGLTF
|
|
{
|
|
/// <summary>
|
|
/// ImporterContext の Load 結果の GltfModel
|
|
///
|
|
/// Runtime でモデルを Destory したときに関連リソース(Texture, Material...などの UnityEngine.Object)を自動的に Destroy する。
|
|
/// </summary>
|
|
public class RuntimeGltfInstance : MonoBehaviour, IResponsibilityForDestroyObjects
|
|
{
|
|
/// <summary>
|
|
/// this is UniGLTF root gameObject
|
|
/// </summary>
|
|
public GameObject Root => (this != null) ? this.gameObject : null;
|
|
|
|
/// <summary>
|
|
/// Transforms with gltf node index.
|
|
/// </summary>
|
|
public IReadOnlyList<Transform> Nodes => _nodes;
|
|
|
|
/// <summary>
|
|
/// Runtime resources.
|
|
/// ex. Material, Texture, AnimationClip, Mesh.
|
|
/// </summary>
|
|
public IReadOnlyList<(SubAssetKey, UnityEngine.Object)> RuntimeResources => _resources;
|
|
|
|
/// <summary>
|
|
/// Materials.
|
|
/// </summary>
|
|
public IReadOnlyList<Material> Materials => _materials;
|
|
|
|
/// <summary>
|
|
/// Textures.
|
|
/// </summary>
|
|
public IReadOnlyList<Texture> Textures => _textures;
|
|
|
|
/// <summary>
|
|
/// Animation Clips.
|
|
/// </summary>
|
|
public IReadOnlyList<AnimationClip> AnimationClips => _animationClips;
|
|
|
|
/// <summary>
|
|
/// Meshes.
|
|
/// </summary>
|
|
public IReadOnlyList<Mesh> Meshes => _meshes;
|
|
|
|
/// <summary>
|
|
/// Renderers.
|
|
/// ex. MeshRenderer, SkinnedMeshRenderer.
|
|
/// </summary>
|
|
public IReadOnlyList<Renderer> Renderers => _renderers;
|
|
|
|
/// <summary>
|
|
/// Mesh Renderers.
|
|
/// </summary>
|
|
public IReadOnlyList<MeshRenderer> MeshRenderers => _meshRenderers;
|
|
|
|
/// <summary>
|
|
/// Skinned Mesh Renderers.
|
|
/// </summary>
|
|
public IReadOnlyList<SkinnedMeshRenderer> SkinnedMeshRenderers => _skinnedMeshRenderers;
|
|
|
|
/// <summary>
|
|
/// ShowMeshes の対象になる Renderer。
|
|
/// Destroy対象とは無関係なので、自由に操作して OK。
|
|
/// </summary>
|
|
/// <typeparam name="Renderer"></typeparam>
|
|
/// <returns></returns>
|
|
public IList<Renderer> VisibleRenderers => _visibleRenderers;
|
|
|
|
private readonly List<Transform> _nodes = new List<Transform>();
|
|
private readonly List<(SubAssetKey, UnityEngine.Object)> _resources = new List<(SubAssetKey, UnityEngine.Object)>();
|
|
private readonly List<Material> _materials = new List<Material>();
|
|
private readonly List<Texture> _textures = new List<Texture>();
|
|
private readonly List<AnimationClip> _animationClips = new List<AnimationClip>();
|
|
private readonly List<Mesh> _meshes = new List<Mesh>();
|
|
private readonly List<Renderer> _renderers = new List<Renderer>();
|
|
private readonly List<MeshRenderer> _meshRenderers = new List<MeshRenderer>();
|
|
private readonly List<SkinnedMeshRenderer> _skinnedMeshRenderers = new List<SkinnedMeshRenderer>();
|
|
|
|
private readonly List<Renderer> _visibleRenderers = new List<Renderer>();
|
|
|
|
public static RuntimeGltfInstance AttachTo(GameObject go, ImporterContext context)
|
|
{
|
|
var loaded = go.AddComponent<RuntimeGltfInstance>();
|
|
|
|
foreach (var node in context.Nodes)
|
|
{
|
|
// Maintain index order.
|
|
loaded._nodes.Add(node);
|
|
}
|
|
|
|
context.TransferOwnership((k, o) =>
|
|
{
|
|
if (o == null) return;
|
|
|
|
loaded._resources.Add((k, o));
|
|
|
|
|
|
switch (o)
|
|
{
|
|
case Material material:
|
|
loaded._materials.Add(material);
|
|
break;
|
|
case Texture texture:
|
|
loaded._textures.Add(texture);
|
|
break;
|
|
case AnimationClip animationClip:
|
|
loaded._animationClips.Add(animationClip);
|
|
break;
|
|
case Mesh mesh:
|
|
loaded._meshes.Add(mesh);
|
|
break;
|
|
}
|
|
});
|
|
|
|
foreach (var renderer in go.GetComponentsInChildren<Renderer>())
|
|
{
|
|
loaded.AddRenderer(renderer);
|
|
}
|
|
|
|
return loaded;
|
|
}
|
|
|
|
public void AddRenderer(Renderer renderer)
|
|
{
|
|
_renderers.Add(renderer);
|
|
|
|
VisibleRenderers.Add(renderer);
|
|
|
|
switch (renderer)
|
|
{
|
|
case MeshRenderer meshRenderer:
|
|
_meshRenderers.Add(meshRenderer);
|
|
break;
|
|
case SkinnedMeshRenderer skinnedMeshRenderer:
|
|
_skinnedMeshRenderers.Add(skinnedMeshRenderer);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void ShowMeshes()
|
|
{
|
|
foreach (var r in VisibleRenderers)
|
|
{
|
|
r.enabled = true;
|
|
}
|
|
}
|
|
|
|
public void EnableUpdateWhenOffscreen()
|
|
{
|
|
foreach (var skinnedMeshRenderer in SkinnedMeshRenderers)
|
|
{
|
|
skinnedMeshRenderer.updateWhenOffscreen = true;
|
|
}
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
Debug.Log("UnityResourceDestroyer.OnDestroy");
|
|
foreach (var (_, obj) in _resources)
|
|
{
|
|
UnityObjectDestoyer.DestroyRuntimeOrEditor(obj);
|
|
}
|
|
}
|
|
|
|
public void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
|
|
{
|
|
foreach (var (key, x) in _resources.ToArray())
|
|
{
|
|
take(key, x);
|
|
_resources.Remove((key, x));
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (this != null && this.gameObject != null)
|
|
{
|
|
UnityObjectDestoyer.DestroyRuntimeOrEditor(this.gameObject);
|
|
}
|
|
}
|
|
}
|
|
}
|