mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-12 05:48:47 -05:00
Merge pull request #1021 from ousttrue/feature10/UnityObjectManager
UnityObjectDestoyer 改め UnityObjectManager
This commit is contained in:
@@ -21,7 +21,7 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
importer.DrawRemapGUI<AnimationClip>(parser.GLTF.animations.Select(x => new SubAssetKey(typeof(AnimationClip), x.name)));
|
||||
importer.DrawRemapGUI<AnimationClip>(AnimationImporterUtil.EnumerateSubAssetKeys(parser.GLTF));
|
||||
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using VRMShaders;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
@@ -50,20 +48,18 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
loader.InvertAxis = reverseAxis;
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
loader.TransferOwnership(o =>
|
||||
loaded.TransferOwnership((k, o) =>
|
||||
{
|
||||
context.AddObjectToAsset(o.name, o);
|
||||
if (o is GameObject)
|
||||
{
|
||||
// Root GameObject is main object
|
||||
context.SetMainObject(loader.Root);
|
||||
}
|
||||
|
||||
return true;
|
||||
context.AddObjectToAsset(k.Name, o);
|
||||
});
|
||||
var root = loaded.Root;
|
||||
GameObject.DestroyImmediate(loaded);
|
||||
|
||||
context.AddObjectToAsset(root.name, root);
|
||||
context.SetMainObject(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,13 +107,4 @@ namespace UniGLTF
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeyValuePariExtensions
|
||||
{
|
||||
public static void Deconstruct<T, U>(this KeyValuePair<T, U> pair, out T key, out U value)
|
||||
{
|
||||
key = pair.Key;
|
||||
value = pair.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,5 +312,13 @@ namespace UniGLTF
|
||||
}
|
||||
return clip;
|
||||
}
|
||||
|
||||
public static IEnumerable<VRMShaders.SubAssetKey> EnumerateSubAssetKeys(glTF gltf)
|
||||
{
|
||||
foreach (var gltfAnimation in gltf.animations)
|
||||
{
|
||||
yield return new VRMShaders.SubAssetKey(typeof(AnimationClip), gltfAnimation.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace UniGLTF
|
||||
/// <summary>
|
||||
/// GLTF importer
|
||||
/// </summary>
|
||||
public class ImporterContext : IDisposable
|
||||
public class ImporterContext : IResponsibilityForDestroyObjects
|
||||
{
|
||||
public ITextureDescriptorGenerator TextureDescriptorGenerator { get; protected set; }
|
||||
public IMaterialDescriptorGenerator MaterialDescriptorGenerator { get; protected set; }
|
||||
@@ -61,7 +61,7 @@ namespace UniGLTF
|
||||
};
|
||||
|
||||
#region Load. Build unity objects
|
||||
public virtual async Task LoadAsync(IAwaitCaller awaitCaller = null, Func<string, IDisposable> MeasureTime = null)
|
||||
public virtual async Task<RuntimeGltfInstance> LoadAsync(IAwaitCaller awaitCaller = null, Func<string, IDisposable> MeasureTime = null)
|
||||
{
|
||||
if (awaitCaller == null)
|
||||
{
|
||||
@@ -108,6 +108,8 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
await OnLoadHierarchy(awaitCaller, MeasureTime);
|
||||
|
||||
return RuntimeGltfInstance.AttachTo(Root, this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -119,18 +121,17 @@ namespace UniGLTF
|
||||
{
|
||||
if (GLTF.animations != null && GLTF.animations.Any())
|
||||
{
|
||||
for (int i = 0; i < GLTF.animations.Count; ++i)
|
||||
foreach (var (key, gltfAnimation) in Enumerable.Zip(AnimationImporterUtil.EnumerateSubAssetKeys(GLTF), GLTF.animations, (x, y) => (x, y)))
|
||||
{
|
||||
var gltfAnimation = GLTF.animations[i];
|
||||
AnimationClip clip = default;
|
||||
if (_externalObjectMap.TryGetValue(new SubAssetKey(typeof(AnimationClip), gltfAnimation.name), out UnityEngine.Object value))
|
||||
if (_externalObjectMap.TryGetValue(key, out UnityEngine.Object value))
|
||||
{
|
||||
clip = value as AnimationClip;
|
||||
}
|
||||
else
|
||||
{
|
||||
clip = AnimationImporterUtil.ConvertAnimationClip(GLTF, GLTF.animations[i], InvertAxis.Create());
|
||||
AnimationClips.Add(clip);
|
||||
clip = AnimationImporterUtil.ConvertAnimationClip(GLTF, gltfAnimation, InvertAxis.Create());
|
||||
AnimationClips.Add((key, clip));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +151,7 @@ namespace UniGLTF
|
||||
var animation = Root.AddComponent<Animation>();
|
||||
for (int i = 0; i < AnimationClips.Count; ++i)
|
||||
{
|
||||
var clip = AnimationClips[i];
|
||||
var (_, clip) = AnimationClips[i];
|
||||
animation.AddClip(clip, clip.name);
|
||||
if (i == 0)
|
||||
{
|
||||
@@ -275,46 +276,12 @@ namespace UniGLTF
|
||||
#endregion
|
||||
|
||||
#region Imported
|
||||
public GameObject Root;
|
||||
bool m_ownRoot = true;
|
||||
protected GameObject Root;
|
||||
public List<Transform> Nodes = new List<Transform>();
|
||||
|
||||
public List<MeshWithMaterials> Meshes = new List<MeshWithMaterials>();
|
||||
public void ShowMeshes()
|
||||
{
|
||||
foreach (var x in Meshes)
|
||||
{
|
||||
foreach (var y in x.Renderers)
|
||||
{
|
||||
y.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
void RemoveMesh(Mesh mesh)
|
||||
{
|
||||
var index = Meshes.FindIndex(x => x.Mesh == mesh);
|
||||
if (index >= 0)
|
||||
{
|
||||
Meshes.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableUpdateWhenOffscreen()
|
||||
{
|
||||
foreach (var x in Meshes)
|
||||
{
|
||||
foreach (var r in x.Renderers)
|
||||
{
|
||||
var skinnedMeshRenderer = r as SkinnedMeshRenderer;
|
||||
if (skinnedMeshRenderer != null)
|
||||
{
|
||||
skinnedMeshRenderer.updateWhenOffscreen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<AnimationClip> AnimationClips = new List<AnimationClip>();
|
||||
public List<(SubAssetKey, AnimationClip)> AnimationClips = new List<(SubAssetKey, AnimationClip)>();
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -322,101 +289,42 @@ namespace UniGLTF
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
Action<UnityEngine.Object> destroy = UnityResourceDestroyer.DestroyResource();
|
||||
|
||||
foreach (var x in AnimationClips)
|
||||
foreach (var (k, x) in AnimationClips)
|
||||
{
|
||||
#if VRM_DEVELOP
|
||||
// Debug.Log($"Destroy {x}");
|
||||
#endif
|
||||
destroy(x);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(x);
|
||||
}
|
||||
AnimationClips.Clear();
|
||||
|
||||
foreach (var x in Meshes)
|
||||
{
|
||||
#if VRM_DEVELOP
|
||||
// Debug.Log($"Destroy {x.Mesh}");
|
||||
#endif
|
||||
destroy(x.Mesh);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(x.Mesh);
|
||||
}
|
||||
Meshes.Clear();
|
||||
|
||||
MaterialFactory?.Dispose();
|
||||
TextureFactory?.Dispose();
|
||||
|
||||
if (m_ownRoot && Root != null)
|
||||
{
|
||||
#if VRM_DEVELOP
|
||||
// Debug.Log($"Destroy {Root}");
|
||||
#endif
|
||||
destroy(Root);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Root ヒエラルキーで使っているリソース
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual void TransferOwnership(Func<UnityEngine.Object, bool> take)
|
||||
public virtual void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
|
||||
{
|
||||
var list = new List<UnityEngine.Object>();
|
||||
foreach (var mesh in Meshes)
|
||||
foreach (var mesh in Meshes.ToArray())
|
||||
{
|
||||
if (take(mesh.Mesh))
|
||||
{
|
||||
list.Add(mesh.Mesh);
|
||||
}
|
||||
}
|
||||
foreach (var x in list)
|
||||
{
|
||||
RemoveMesh(x as Mesh);
|
||||
take(SubAssetKey.Create(mesh.Mesh), mesh.Mesh);
|
||||
Meshes.Remove(mesh);
|
||||
}
|
||||
|
||||
TextureFactory.TransferOwnership(take);
|
||||
MaterialFactory.TransferOwnership(take);
|
||||
|
||||
list.Clear();
|
||||
foreach (var animation in AnimationClips)
|
||||
foreach (var (key, animation) in AnimationClips.ToArray())
|
||||
{
|
||||
if (take(animation))
|
||||
{
|
||||
list.Add(animation);
|
||||
}
|
||||
take(key, animation);
|
||||
AnimationClips.Remove((key, animation));
|
||||
}
|
||||
foreach (var x in list)
|
||||
{
|
||||
AnimationClips.Remove(x as AnimationClip);
|
||||
}
|
||||
|
||||
if (m_ownRoot && Root != null)
|
||||
{
|
||||
if (take(Root))
|
||||
{
|
||||
// 所有権(Dispose権)
|
||||
m_ownRoot = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RootにUnityResourceDestroyerをアタッチして、
|
||||
/// RootをUnityEngine.Object.Destroyしたときに、
|
||||
/// 関連するUnityEngine.Objectを破棄するようにする。
|
||||
/// Mesh, Material, Texture, AnimationClip, GameObject の所有者が
|
||||
/// ImporterContext から UnityResourceDestroyer に移動する。
|
||||
/// ImporterContext.Dispose の対象から外れる。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UnityResourceDestroyer DisposeOnGameObjectDestroyed()
|
||||
{
|
||||
var destroyer = Root.AddComponent<UnityResourceDestroyer>();
|
||||
TransferOwnership(o =>
|
||||
{
|
||||
destroyer.Resources.Add(o);
|
||||
return true;
|
||||
});
|
||||
return destroyer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace UniGLTF
|
||||
/// <summary>
|
||||
/// Build unity objects from parsed gltf
|
||||
/// </summary>
|
||||
public static void Load(this ImporterContext self)
|
||||
public static RuntimeGltfInstance Load(this ImporterContext self)
|
||||
{
|
||||
var meassureTime = new ImporterContextSpeedLog();
|
||||
var task = self.LoadAsync(default(ImmediateCaller), meassureTime.MeasureTime);
|
||||
@@ -24,6 +24,8 @@ namespace UniGLTF
|
||||
#if VRM_DEVELOP
|
||||
Debug.Log($"{self.Parser.TargetPath}: {meassureTime.GetSpeedLog()}");
|
||||
#endif
|
||||
|
||||
return task.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
70
Assets/UniGLTF/Runtime/UniGLTF/RuntimeGltfInstance.cs
Normal file
70
Assets/UniGLTF/Runtime/UniGLTF/RuntimeGltfInstance.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System.Collections.Generic;
|
||||
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.gameObject;
|
||||
|
||||
List<(SubAssetKey, UnityEngine.Object)> m_resources = new List<(SubAssetKey, UnityEngine.Object)>();
|
||||
|
||||
public static RuntimeGltfInstance AttachTo(GameObject go, ImporterContext context)
|
||||
{
|
||||
var loaded = go.AddComponent<RuntimeGltfInstance>();
|
||||
context.TransferOwnership((k, o) =>
|
||||
{
|
||||
loaded.m_resources.Add((k, o));
|
||||
});
|
||||
return loaded;
|
||||
}
|
||||
|
||||
public void ShowMeshes()
|
||||
{
|
||||
foreach (var r in GetComponentsInChildren<Renderer>())
|
||||
{
|
||||
r.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableUpdateWhenOffscreen()
|
||||
{
|
||||
foreach (var smr in GetComponentsInChildren<SkinnedMeshRenderer>())
|
||||
{
|
||||
smr.updateWhenOffscreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
Debug.Log("UnityResourceDestroyer.OnDestroy");
|
||||
foreach (var (key, x) in m_resources)
|
||||
{
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(x);
|
||||
}
|
||||
}
|
||||
|
||||
public void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
|
||||
{
|
||||
foreach (var (key, x) in m_resources.ToArray())
|
||||
{
|
||||
take(key, x);
|
||||
m_resources.Remove((key, x));
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(this.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93b3af59a4d8b704a883260f2fd40c44
|
||||
guid: 423fb0cccbe420047ac28163cce68db4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// Mesh, Material, Texture などを抱えておいて確実に破棄できるようにする
|
||||
/// </summary>
|
||||
public class UnityResourceDestroyer : MonoBehaviour
|
||||
{
|
||||
List<UnityEngine.Object> m_resources = new List<UnityEngine.Object>();
|
||||
public IList<UnityEngine.Object> Resources => m_resources;
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
Debug.Log("UnityResourceDestroyer.OnDestroy");
|
||||
foreach (var x in Resources)
|
||||
{
|
||||
#if VRM_DEVELOP
|
||||
Debug.Log($"Destroy: {x}");
|
||||
#endif
|
||||
Destroy(x);
|
||||
}
|
||||
}
|
||||
|
||||
public static Action<UnityEngine.Object> DestroyResource()
|
||||
{
|
||||
Action<UnityEngine.Object> des = (UnityEngine.Object o) => UnityEngine.Object.Destroy(o);
|
||||
Action<UnityEngine.Object> desi = (UnityEngine.Object o) => UnityEngine.Object.DestroyImmediate(o);
|
||||
Action<UnityEngine.Object> func = Application.isPlaying
|
||||
? des
|
||||
: desi
|
||||
;
|
||||
return func;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,27 +93,27 @@ namespace UniGLTF
|
||||
{
|
||||
try
|
||||
{
|
||||
loader.Load();
|
||||
var loaded = loader.Load();
|
||||
if (loaded == null)
|
||||
{
|
||||
Debug.LogWarning($"root is null: ${gltf}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Skip.Contains(gltf.Directory.Parent.Name))
|
||||
{
|
||||
// Export issue:
|
||||
// skip
|
||||
return;
|
||||
}
|
||||
|
||||
Export(loaded.gameObject);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Message(gltf.FullName.Substring(subStrStart), ex);
|
||||
}
|
||||
|
||||
if (Skip.Contains(gltf.Directory.Parent.Name))
|
||||
{
|
||||
// Export issue:
|
||||
// skip
|
||||
return;
|
||||
}
|
||||
|
||||
if (loader.Root == null)
|
||||
{
|
||||
Debug.LogWarning($"root is null: ${gltf}");
|
||||
return;
|
||||
}
|
||||
|
||||
Export(loader.Root);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,9 +120,9 @@ namespace UniGLTF
|
||||
|
||||
// import
|
||||
using (var context = new ImporterContext(parser))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
context.Load();
|
||||
AssertAreEqual(go.transform, context.Root.transform);
|
||||
AssertAreEqual(go.transform, loaded.transform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,16 +557,14 @@ namespace UniGLTF
|
||||
parser.ParseJson(json, new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024])));
|
||||
|
||||
using (var context = new ImporterContext(parser))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
//Debug.LogFormat("{0}", context.Json);
|
||||
context.Load();
|
||||
|
||||
var importedRed = context.Root.transform.GetChild(0);
|
||||
var importedRed = loaded.transform.GetChild(0);
|
||||
var importedRedMaterial = importedRed.GetComponent<Renderer>().sharedMaterial;
|
||||
Assert.AreEqual("red", importedRedMaterial.name);
|
||||
Assert.AreEqual(Color.red, importedRedMaterial.color);
|
||||
|
||||
var importedBlue = context.Root.transform.GetChild(1);
|
||||
var importedBlue = loaded.transform.GetChild(1);
|
||||
var importedBlueMaterial = importedBlue.GetComponent<Renderer>().sharedMaterial;
|
||||
Assert.AreEqual("blue", importedBlueMaterial.name);
|
||||
Assert.AreEqual(Color.blue, importedBlueMaterial.color);
|
||||
@@ -579,15 +577,14 @@ namespace UniGLTF
|
||||
parser.ParseJson(json, new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024])));
|
||||
//Debug.LogFormat("{0}", context.Json);
|
||||
using (var context = new ImporterContext(parser))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
context.Load();
|
||||
|
||||
var importedRed = context.Root.transform.GetChild(0);
|
||||
var importedRed = loaded.transform.GetChild(0);
|
||||
var importedRedMaterial = importedRed.GetComponent<Renderer>().sharedMaterial;
|
||||
Assert.AreEqual("red", importedRedMaterial.name);
|
||||
Assert.AreEqual(Color.red, importedRedMaterial.color);
|
||||
|
||||
var importedBlue = context.Root.transform.GetChild(1);
|
||||
var importedBlue = loaded.transform.GetChild(1);
|
||||
var importedBlueMaterial = importedBlue.GetComponent<Renderer>().sharedMaterial;
|
||||
Assert.AreEqual("blue", importedBlueMaterial.name);
|
||||
Assert.AreEqual(Color.blue, importedBlueMaterial.color);
|
||||
@@ -633,13 +630,11 @@ namespace UniGLTF
|
||||
parser.ParseJson(json, new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024])));
|
||||
|
||||
using (var context = new ImporterContext(parser))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
context.Load();
|
||||
|
||||
Assert.AreEqual(1, context.Root.transform.GetChildren().Count());
|
||||
|
||||
Assert.AreEqual(1, loaded.transform.GetChildren().Count());
|
||||
{
|
||||
var child = context.Root.transform.GetChild(0);
|
||||
var child = loaded.transform.GetChild(0);
|
||||
Assert.IsNull(child.GetSharedMesh());
|
||||
}
|
||||
}
|
||||
@@ -700,18 +695,17 @@ namespace UniGLTF
|
||||
parser.ParseJson(json, new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024])));
|
||||
|
||||
using (var context = new ImporterContext(parser))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
context.Load();
|
||||
|
||||
Assert.AreEqual(2, context.Root.transform.GetChildren().Count());
|
||||
Assert.AreEqual(2, loaded.transform.GetChildren().Count());
|
||||
|
||||
{
|
||||
var child = context.Root.transform.GetChild(0);
|
||||
var child = loaded.transform.GetChild(0);
|
||||
Assert.IsNull(child.GetSharedMesh());
|
||||
}
|
||||
|
||||
{
|
||||
var child = context.Root.transform.GetChild(1);
|
||||
var child = loaded.transform.GetChild(1);
|
||||
Assert.IsNull(child.GetSharedMesh());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,152 +47,144 @@ namespace VRM.Samples
|
||||
parser.ParseGlb(File.ReadAllBytes(path));
|
||||
|
||||
using (var context = new VRMImporterContext(parser))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
|
||||
var destroyer = context.DisposeOnGameObjectDestroyed();
|
||||
try
|
||||
// mesh
|
||||
{
|
||||
// mesh
|
||||
foreach (var renderer in loaded.GetComponentsInChildren<Renderer>())
|
||||
{
|
||||
foreach (var renderer in destroyer.GetComponentsInChildren<Renderer>())
|
||||
Mesh mesh = default;
|
||||
if (renderer is MeshRenderer)
|
||||
{
|
||||
Mesh mesh = default;
|
||||
if (renderer is MeshRenderer)
|
||||
var f = renderer.GetComponent<MeshFilter>();
|
||||
mesh = f.sharedMesh;
|
||||
}
|
||||
else if (renderer is SkinnedMeshRenderer smr)
|
||||
{
|
||||
mesh = smr.sharedMesh;
|
||||
}
|
||||
|
||||
var gltfMesh = parser.GLTF.meshes.Find(x => x.name == mesh.name);
|
||||
Assert.AreEqual(gltfMesh.name, mesh.name);
|
||||
|
||||
// materials
|
||||
foreach (var material in renderer.sharedMaterials)
|
||||
{
|
||||
var gltfMaterial = parser.GLTF.materials.Find(x => x.name == material.name);
|
||||
Assert.AreEqual(gltfMaterial.name, material.name);
|
||||
|
||||
var materialIndex = parser.GLTF.materials.IndexOf(gltfMaterial);
|
||||
var vrmMaterial = context.VRM.materialProperties[materialIndex];
|
||||
// Debug.Log($"shaderName: '{vrmMaterial.shader}'");
|
||||
if (vrmMaterial.shader == "VRM/MToon")
|
||||
{
|
||||
var f = renderer.GetComponent<MeshFilter>();
|
||||
mesh = f.sharedMesh;
|
||||
// MToon
|
||||
// Debug.Log($"{material.name} is MToon");
|
||||
foreach (var kv in vrmMaterial.textureProperties)
|
||||
{
|
||||
var texture = material.GetTexture(kv.Key);
|
||||
// Debug.Log($"{kv.Key}: {texture}");
|
||||
Assert.NotNull(texture);
|
||||
}
|
||||
}
|
||||
else if (renderer is SkinnedMeshRenderer smr)
|
||||
else if (glTF_KHR_materials_unlit.IsEnable(gltfMaterial))
|
||||
{
|
||||
mesh = smr.sharedMesh;
|
||||
// Unlit
|
||||
// Debug.Log($"{material.name} is unlit");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
var gltfMesh = parser.GLTF.meshes.Find(x => x.name == mesh.name);
|
||||
Assert.AreEqual(gltfMesh.name, mesh.name);
|
||||
|
||||
// materials
|
||||
foreach (var material in renderer.sharedMaterials)
|
||||
else
|
||||
{
|
||||
var gltfMaterial = parser.GLTF.materials.Find(x => x.name == material.name);
|
||||
Assert.AreEqual(gltfMaterial.name, material.name);
|
||||
|
||||
var materialIndex = parser.GLTF.materials.IndexOf(gltfMaterial);
|
||||
var vrmMaterial = context.VRM.materialProperties[materialIndex];
|
||||
// Debug.Log($"shaderName: '{vrmMaterial.shader}'");
|
||||
if (vrmMaterial.shader == "VRM/MToon")
|
||||
{
|
||||
// MToon
|
||||
// Debug.Log($"{material.name} is MToon");
|
||||
foreach (var kv in vrmMaterial.textureProperties)
|
||||
{
|
||||
var texture = material.GetTexture(kv.Key);
|
||||
// Debug.Log($"{kv.Key}: {texture}");
|
||||
Assert.NotNull(texture);
|
||||
}
|
||||
}
|
||||
else if (glTF_KHR_materials_unlit.IsEnable(gltfMaterial))
|
||||
{
|
||||
// Unlit
|
||||
// Debug.Log($"{material.name} is unlit");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
// PBR
|
||||
// Debug.Log($"{material.name} is PBR");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// PBR
|
||||
// Debug.Log($"{material.name} is PBR");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// meta
|
||||
{
|
||||
var meta = destroyer.GetComponent<VRMMeta>();
|
||||
}
|
||||
|
||||
// humanoid
|
||||
{
|
||||
var animator = destroyer.GetComponent<Animator>();
|
||||
}
|
||||
|
||||
|
||||
// blendshape
|
||||
{
|
||||
var blendshapeProxy = destroyer.GetComponent<VRMBlendShapeProxy>();
|
||||
for (int i = 0; i < context.VRM.blendShapeMaster.blendShapeGroups.Count; ++i)
|
||||
{
|
||||
var gltfBlendShapeClip = context.VRM.blendShapeMaster.blendShapeGroups[i];
|
||||
var unityBlendShapeClip = blendshapeProxy.BlendShapeAvatar.Clips[i];
|
||||
Assert.AreEqual(Enum.Parse(typeof(BlendShapePreset), gltfBlendShapeClip.presetName, true), unityBlendShapeClip.Preset);
|
||||
}
|
||||
}
|
||||
|
||||
var importedJson = JsonParser.Parse(context.Json);
|
||||
importedJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION, (f, x) => f.Value(x));
|
||||
importedJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION, (f, x) => f.Value(x));
|
||||
importedJson.SetValue("/scene", 0, (f, x) => f.Value(x));
|
||||
importedJson.SetValue("/materials/*/doubleSided", false, (f, x) => f.Value(x));
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/roughnessFactor", 0);
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/baseColorFactor", new float[] { 1, 1, 1, 1 });
|
||||
importedJson.SetValue("/accessors/*/normalized", false, (f, x) => f.Value(x));
|
||||
importedJson.RemoveValue(Utf8String.From("/nodes/*/extras"));
|
||||
/*
|
||||
importJson.SetValue("/bufferViews/12/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/13/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/14/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/15/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/22/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/29/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/45/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/46/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/47/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/201/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/202/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/203/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/204/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/211/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/212/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/213/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/214/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/215/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/243/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/247/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/248/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/249/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/250/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/251/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/252/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/253/byteStride", 64);
|
||||
*/
|
||||
importedJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride"));
|
||||
|
||||
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root, new EditorTextureSerializer());
|
||||
|
||||
// TODO: Check contents in JSON
|
||||
/*var exportJson = */
|
||||
JsonParser.Parse(vrm.ToJson());
|
||||
|
||||
// TODO: Check contents in JSON
|
||||
/*var newExportedJson = */
|
||||
// JsonParser.Parse(JsonSchema.FromType<glTF>().Serialize(vrm));
|
||||
|
||||
/*
|
||||
foreach (var kv in importJson.Diff(exportJson))
|
||||
{
|
||||
Debug.Log(kv);
|
||||
}
|
||||
|
||||
Assert.AreEqual(importJson, exportJson);
|
||||
*/
|
||||
}
|
||||
finally
|
||||
|
||||
// meta
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(destroyer.gameObject);
|
||||
var meta = loaded.GetComponent<VRMMeta>();
|
||||
}
|
||||
|
||||
// humanoid
|
||||
{
|
||||
var animator = loaded.GetComponent<Animator>();
|
||||
}
|
||||
|
||||
|
||||
// blendshape
|
||||
{
|
||||
var blendshapeProxy = loaded.GetComponent<VRMBlendShapeProxy>();
|
||||
for (int i = 0; i < context.VRM.blendShapeMaster.blendShapeGroups.Count; ++i)
|
||||
{
|
||||
var gltfBlendShapeClip = context.VRM.blendShapeMaster.blendShapeGroups[i];
|
||||
var unityBlendShapeClip = blendshapeProxy.BlendShapeAvatar.Clips[i];
|
||||
Assert.AreEqual(Enum.Parse(typeof(BlendShapePreset), gltfBlendShapeClip.presetName, true), unityBlendShapeClip.Preset);
|
||||
}
|
||||
}
|
||||
|
||||
var importedJson = JsonParser.Parse(context.Json);
|
||||
importedJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION, (f, x) => f.Value(x));
|
||||
importedJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION, (f, x) => f.Value(x));
|
||||
importedJson.SetValue("/scene", 0, (f, x) => f.Value(x));
|
||||
importedJson.SetValue("/materials/*/doubleSided", false, (f, x) => f.Value(x));
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/roughnessFactor", 0);
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/baseColorFactor", new float[] { 1, 1, 1, 1 });
|
||||
importedJson.SetValue("/accessors/*/normalized", false, (f, x) => f.Value(x));
|
||||
importedJson.RemoveValue(Utf8String.From("/nodes/*/extras"));
|
||||
/*
|
||||
importJson.SetValue("/bufferViews/12/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/13/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/14/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/15/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/22/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/29/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/45/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/46/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/47/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/201/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/202/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/203/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/204/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/211/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/212/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/213/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/214/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/215/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/243/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/247/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/248/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/249/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/250/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/251/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/252/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/253/byteStride", 64);
|
||||
*/
|
||||
importedJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride"));
|
||||
|
||||
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, loaded.gameObject, new EditorTextureSerializer());
|
||||
|
||||
// TODO: Check contents in JSON
|
||||
/*var exportJson = */
|
||||
JsonParser.Parse(vrm.ToJson());
|
||||
|
||||
// TODO: Check contents in JSON
|
||||
/*var newExportedJson = */
|
||||
// JsonParser.Parse(JsonSchema.FromType<glTF>().Serialize(vrm));
|
||||
|
||||
/*
|
||||
foreach (var kv in importJson.Diff(exportJson))
|
||||
{
|
||||
Debug.Log(kv);
|
||||
}
|
||||
|
||||
Assert.AreEqual(importJson, exportJson);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,10 +196,10 @@ namespace VRM.Samples
|
||||
parser.ParseGlb(File.ReadAllBytes(path));
|
||||
|
||||
using (var context = new VRMImporterContext(parser))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
foreach (var mesh in context.Meshes)
|
||||
{
|
||||
var src = mesh.Mesh;
|
||||
|
||||
@@ -59,13 +59,12 @@ namespace VRM.Samples
|
||||
Debug.LogFormat("meta: title:{0}", meta.Title);
|
||||
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
await context.LoadAsync();
|
||||
var loaded = await context.LoadAsync();
|
||||
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
var destroyer = context.DisposeOnGameObjectDestroyed();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
|
||||
OnLoaded(destroyer.gameObject);
|
||||
OnLoaded(loaded.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,16 +97,17 @@ namespace VRM.Samples
|
||||
Debug.LogFormat("meta: title:{0}", meta.Title);
|
||||
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
var loaded = default(RuntimeGltfInstance);
|
||||
if (m_loadAsync)
|
||||
{
|
||||
await context.LoadAsync();
|
||||
loaded = await context.LoadAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Load();
|
||||
loaded = context.Load();
|
||||
}
|
||||
|
||||
OnLoaded(context);
|
||||
OnLoaded(loaded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,15 +136,16 @@ namespace VRM.Samples
|
||||
parser.ParseGlb(bytes);
|
||||
|
||||
var context = new VRMImporterContext(parser);
|
||||
var loaded = default(RuntimeGltfInstance);
|
||||
if (m_loadAsync)
|
||||
{
|
||||
await context.LoadAsync();
|
||||
loaded = await context.LoadAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Load();
|
||||
loaded = context.Load();
|
||||
}
|
||||
OnLoaded(context);
|
||||
OnLoaded(loaded);
|
||||
}
|
||||
|
||||
void LoadBVHClicked()
|
||||
@@ -165,15 +167,14 @@ namespace VRM.Samples
|
||||
#endif
|
||||
}
|
||||
|
||||
void OnLoaded(VRMImporterContext context)
|
||||
void OnLoaded(RuntimeGltfInstance loaded)
|
||||
{
|
||||
var root = context.Root;
|
||||
var root = loaded.gameObject;
|
||||
|
||||
root.transform.SetParent(transform, false);
|
||||
|
||||
//メッシュを表示します
|
||||
context.ShowMeshes();
|
||||
context.DisposeOnGameObjectDestroyed();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
// add motion
|
||||
var humanPoseTransfer = root.AddComponent<UniHumanoid.HumanPoseTransfer>();
|
||||
|
||||
@@ -317,11 +317,10 @@ namespace VRM.Samples
|
||||
using (var context = new VRMImporterContext(parser))
|
||||
{
|
||||
await m_texts.UpdateMetaAsync(context);
|
||||
await context.LoadAsync();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
context.DisposeOnGameObjectDestroyed();
|
||||
SetModel(context.Root);
|
||||
var loaded = await context.LoadAsync();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -333,11 +332,10 @@ namespace VRM.Samples
|
||||
parser.ParseGlb(file);
|
||||
|
||||
var context = new UniGLTF.ImporterContext(parser);
|
||||
context.Load();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
context.DisposeOnGameObjectDestroyed();
|
||||
SetModel(context.Root);
|
||||
var loaded = context.Load();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
SetModel(loaded.gameObject);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -348,11 +346,10 @@ namespace VRM.Samples
|
||||
parser.ParsePath(path);
|
||||
|
||||
var context = new UniGLTF.ImporterContext(parser);
|
||||
context.Load();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
context.DisposeOnGameObjectDestroyed();
|
||||
SetModel(context.Root);
|
||||
var loaded = context.Load();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
SetModel(loaded.gameObject);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,61 +108,51 @@ namespace VRM
|
||||
TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), m_context.TextureDescriptorGenerator, subAssets, (_x, _y) => { }, onTextureReloaded);
|
||||
}
|
||||
|
||||
bool SaveAsAsset(UnityEngine.Object o)
|
||||
void SaveAsAsset(SubAssetKey _, UnityEngine.Object o)
|
||||
{
|
||||
if (o is GameObject)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(o)))
|
||||
{
|
||||
// already exists. not dispose
|
||||
#if VRM_DEVELOP
|
||||
Debug.Log($"Loaded. skip: {o}");
|
||||
// 来ない?
|
||||
Debug.LogWarning($"{o} already exists. skip write");
|
||||
#endif
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
var assetPath = GetAssetPath(m_prefabPath, o);
|
||||
if (assetPath.IsNull)
|
||||
if (!assetPath.IsNull)
|
||||
{
|
||||
// not dispose
|
||||
return true;
|
||||
// アセットとして書き込む
|
||||
assetPath.Parent.EnsureFolder();
|
||||
assetPath.CreateAsset(o);
|
||||
m_paths.Add(assetPath);
|
||||
}
|
||||
|
||||
// アセットとして書き込む
|
||||
assetPath.Parent.EnsureFolder();
|
||||
assetPath.CreateAsset(o);
|
||||
m_paths.Add(assetPath);
|
||||
|
||||
// 所有権が移動
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SaveAsAsset()
|
||||
public void SaveAsAsset(UniGLTF.RuntimeGltfInstance loaded)
|
||||
{
|
||||
m_context.ShowMeshes();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
//
|
||||
// save sub assets
|
||||
//
|
||||
m_paths.Clear();
|
||||
m_paths.Add(m_prefabPath);
|
||||
m_context.TransferOwnership(SaveAsAsset);
|
||||
loaded.TransferOwnership(SaveAsAsset);
|
||||
var root = loaded.Root;
|
||||
GameObject.DestroyImmediate(loaded);
|
||||
|
||||
// Create or update Main Asset
|
||||
if (m_prefabPath.IsFileExists)
|
||||
{
|
||||
Debug.LogFormat("replace prefab: {0}", m_prefabPath);
|
||||
var prefab = m_prefabPath.LoadAsset<GameObject>();
|
||||
PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, m_prefabPath.Value, InteractionMode.AutomatedAction);
|
||||
|
||||
PrefabUtility.SaveAsPrefabAssetAndConnect(root, m_prefabPath.Value, InteractionMode.AutomatedAction);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogFormat("create prefab: {0}", m_prefabPath);
|
||||
PrefabUtility.SaveAsPrefabAssetAndConnect(m_context.Root, m_prefabPath.Value, InteractionMode.AutomatedAction);
|
||||
PrefabUtility.SaveAsPrefabAssetAndConnect(root, m_prefabPath.Value, InteractionMode.AutomatedAction);
|
||||
}
|
||||
|
||||
foreach (var x in m_paths)
|
||||
|
||||
@@ -50,11 +50,10 @@ namespace VRM
|
||||
|
||||
using (var context = new VRMImporterContext(parser))
|
||||
{
|
||||
context.Load();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
context.DisposeOnGameObjectDestroyed();
|
||||
Selection.activeGameObject = context.Root;
|
||||
var loaded = context.Load();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
loaded.ShowMeshes();
|
||||
Selection.activeGameObject = loaded.gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,8 +87,8 @@ namespace VRM
|
||||
{
|
||||
VRMShaders.TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures);
|
||||
}
|
||||
context.Load();
|
||||
editor.SaveAsAsset();
|
||||
var loaded = context.Load();
|
||||
editor.SaveAsAsset(loaded);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ namespace VRM
|
||||
{
|
||||
VRMShaders.TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures);
|
||||
}
|
||||
context.Load();
|
||||
editor.SaveAsAsset();
|
||||
var loaded = context.Load();
|
||||
editor.SaveAsAsset(loaded);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -317,36 +317,30 @@ namespace VRM
|
||||
return meta;
|
||||
}
|
||||
|
||||
public override void TransferOwnership(Func<UnityEngine.Object, bool> take)
|
||||
public override void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
|
||||
{
|
||||
// VRM-0 は SubAssetKey を使っていないので default で済ます
|
||||
|
||||
// VRM 固有のリソース(ScriptableObject)
|
||||
if (take(HumanoidAvatar))
|
||||
{
|
||||
HumanoidAvatar = null;
|
||||
}
|
||||
take(default, HumanoidAvatar);
|
||||
HumanoidAvatar = null;
|
||||
|
||||
if (take(Meta))
|
||||
{
|
||||
Meta = null;
|
||||
}
|
||||
take(default, Meta);
|
||||
Meta = null;
|
||||
|
||||
if (take(AvatarDescription))
|
||||
{
|
||||
AvatarDescription = null;
|
||||
}
|
||||
take(default, AvatarDescription);
|
||||
AvatarDescription = null;
|
||||
|
||||
foreach (var x in BlendShapeAvatar.Clips)
|
||||
{
|
||||
if (take(x))
|
||||
take(default, x);
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
if (take(BlendShapeAvatar))
|
||||
{
|
||||
BlendShapeAvatar = null;
|
||||
}
|
||||
take(default, BlendShapeAvatar);
|
||||
BlendShapeAvatar = null;
|
||||
|
||||
// GLTF のリソース
|
||||
base.TransferOwnership(take);
|
||||
@@ -354,28 +348,26 @@ namespace VRM
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Action<UnityEngine.Object> destroy = UnityResourceDestroyer.DestroyResource();
|
||||
|
||||
// VRM specific
|
||||
if (HumanoidAvatar != null)
|
||||
{
|
||||
destroy(HumanoidAvatar);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(HumanoidAvatar);
|
||||
}
|
||||
if (Meta != null)
|
||||
{
|
||||
destroy(Meta);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(Meta);
|
||||
}
|
||||
if (AvatarDescription != null)
|
||||
{
|
||||
destroy(AvatarDescription);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(AvatarDescription);
|
||||
}
|
||||
if (BlendShapeAvatar != null)
|
||||
{
|
||||
foreach (var clip in BlendShapeAvatar.Clips)
|
||||
{
|
||||
destroy(clip);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(clip);
|
||||
}
|
||||
destroy(BlendShapeAvatar);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(BlendShapeAvatar);
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
|
||||
@@ -74,8 +74,7 @@ namespace VRM
|
||||
{
|
||||
using (var importer = new VRMImporterContext(parser))
|
||||
{
|
||||
importer.Load();
|
||||
return importer.DisposeOnGameObjectDestroyed().gameObject;
|
||||
return importer.Load().gameObject;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -24,11 +24,11 @@ namespace VRM
|
||||
parser.ParsePath(AliciaPath);
|
||||
byte[] bytes = default;
|
||||
using (var loader = new VRMImporterContext(parser))
|
||||
using (var loaded = loader.Load())
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
var go = loader.Root;
|
||||
var go = loaded.gameObject;
|
||||
var fp = go.GetComponent<VRMFirstPerson>();
|
||||
GameObject.DestroyImmediate(go.GetComponent<VRMLookAtBoneApplyer>());
|
||||
var lookAt = go.AddComponent<VRMLookAtBlendShapeApplyer>();
|
||||
@@ -54,11 +54,11 @@ namespace VRM
|
||||
byte[] bytes = default;
|
||||
CurveMapper horizontalInner = default;
|
||||
using (var loader = new VRMImporterContext(parser))
|
||||
using (var loaded = loader.Load())
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
var go = loader.Root;
|
||||
var go = loaded.gameObject;
|
||||
var fp = go.GetComponent<VRMFirstPerson>();
|
||||
var lookAt = go.GetComponent<VRMLookAtBoneApplyer>();
|
||||
horizontalInner = lookAt.HorizontalInner;
|
||||
@@ -71,11 +71,11 @@ namespace VRM
|
||||
var parser2 = new GltfParser();
|
||||
parser2.Parse(AliciaPath, bytes);
|
||||
using (var loader = new VRMImporterContext(parser2))
|
||||
using (var loaded = loader.Load())
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
var lookAt = loader.Root.GetComponent<VRMLookAtBoneApplyer>();
|
||||
var lookAt = loaded.GetComponent<VRMLookAtBoneApplyer>();
|
||||
Assert.AreEqual(horizontalInner.CurveXRangeDegree, lookAt.HorizontalInner.CurveXRangeDegree);
|
||||
Assert.AreEqual(horizontalInner.CurveYRangeDegree, lookAt.HorizontalInner.CurveYRangeDegree);
|
||||
}
|
||||
@@ -89,11 +89,11 @@ namespace VRM
|
||||
byte[] bytes = default;
|
||||
CurveMapper horizontalInner = default;
|
||||
using (var loader = new VRMImporterContext(parser))
|
||||
using (var loaded = loader.Load())
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
var go = loader.Root;
|
||||
var go = loaded.gameObject;
|
||||
var fp = go.GetComponent<VRMFirstPerson>();
|
||||
var lookAt = go.GetComponent<VRMLookAtBoneApplyer>();
|
||||
horizontalInner = lookAt.HorizontalInner;
|
||||
@@ -106,11 +106,11 @@ namespace VRM
|
||||
var parser2 = new GltfParser();
|
||||
parser2.Parse(AliciaPath, bytes);
|
||||
using (var loader = new VRMImporterContext(parser2))
|
||||
using (var loaded = loader.Load())
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
var lookAt = loader.Root.GetComponent<VRMLookAtBoneApplyer>();
|
||||
var lookAt = loaded.GetComponent<VRMLookAtBoneApplyer>();
|
||||
Assert.AreEqual(horizontalInner.CurveXRangeDegree, lookAt.HorizontalInner.CurveXRangeDegree);
|
||||
Assert.AreEqual(horizontalInner.CurveYRangeDegree, lookAt.HorizontalInner.CurveYRangeDegree);
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ namespace VRM
|
||||
|
||||
using (var loader = new VRMImporterContext(parser))
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
return loader.DisposeOnGameObjectDestroyed().gameObject;
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
return loaded.gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -308,18 +308,17 @@ namespace UniVRM10.Samples
|
||||
{
|
||||
case ".vrm":
|
||||
{
|
||||
if(!Vrm10Parser.TryParseOrMigrate(path, doMigrate: true, out Vrm10Parser.Result result, out string error))
|
||||
if (!Vrm10Parser.TryParseOrMigrate(path, doMigrate: true, out Vrm10Parser.Result result, out string error))
|
||||
{
|
||||
Debug.LogError(error);
|
||||
return;
|
||||
}
|
||||
using (var loader = new Vrm10Importer(result.Parser, result.Vrm))
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loader.EnableUpdateWhenOffscreen();
|
||||
var destroyer = loader.DisposeOnGameObjectDestroyed();
|
||||
SetModel(destroyer.gameObject);
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -332,12 +331,10 @@ namespace UniVRM10.Samples
|
||||
|
||||
using (var loader = new UniGLTF.ImporterContext(parser))
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loader.EnableUpdateWhenOffscreen();
|
||||
loader.ShowMeshes();
|
||||
var destroyer = loader.DisposeOnGameObjectDestroyed();
|
||||
SetModel(destroyer.gameObject);
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -350,12 +347,10 @@ namespace UniVRM10.Samples
|
||||
|
||||
using (var loader = new UniGLTF.ImporterContext(parser))
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loader.EnableUpdateWhenOffscreen();
|
||||
loader.ShowMeshes();
|
||||
var destroyer = loader.DisposeOnGameObjectDestroyed();
|
||||
SetModel(destroyer.gameObject);
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
SetModel(loaded.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -15,18 +15,6 @@ namespace UniVRM10
|
||||
{
|
||||
public static class EditorVrm
|
||||
{
|
||||
static ExpressionKey CreateKey(UniGLTF.Extensions.VRMC_vrm.Expression expression)
|
||||
{
|
||||
if (expression.Preset == UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
|
||||
{
|
||||
return ExpressionKey.CreateCustom(expression.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ExpressionKey.CreateFromPreset(expression.Preset);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnGUI(ScriptedImporter importer, GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm)
|
||||
{
|
||||
var hasExternal = importer.GetExternalObjectMap().Any(x => x.Value is VRM10MetaObject || x.Value is VRM10ExpressionAvatar || x.Value is VRM10Expression);
|
||||
@@ -42,7 +30,7 @@ namespace UniVRM10
|
||||
importer.DrawRemapGUI<VRM10MetaObject>(new SubAssetKey[] { VRM10MetaObject.SubAssetKey });
|
||||
|
||||
// expressions
|
||||
importer.DrawRemapGUI<VRM10Expression>(vrm.Expressions.Select(x => CreateKey(x).SubAssetKey));
|
||||
importer.DrawRemapGUI<VRM10Expression>(vrm.Expressions.Select(x => ExpressionKey.CreateFromVrm10(x).SubAssetKey));
|
||||
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
|
||||
@@ -42,20 +42,18 @@ namespace UniVRM10
|
||||
VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures);
|
||||
}
|
||||
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
|
||||
loader.TransferOwnership(o =>
|
||||
loaded.TransferOwnership((key, o) =>
|
||||
{
|
||||
context.AddObjectToAsset(o.name, o);
|
||||
if (o is GameObject)
|
||||
{
|
||||
// Root GameObject is main object
|
||||
context.SetMainObject(loader.Root);
|
||||
}
|
||||
|
||||
return true;
|
||||
context.AddObjectToAsset(key.Name, o);
|
||||
});
|
||||
var root = loaded.Root;
|
||||
GameObject.DestroyImmediate(loaded);
|
||||
|
||||
context.AddObjectToAsset(root.name, root);
|
||||
context.SetMainObject(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,18 @@ namespace UniVRM10
|
||||
return new ExpressionKey(clip.Preset, clip.ExpressionName);
|
||||
}
|
||||
|
||||
public static ExpressionKey CreateFromVrm10(UniGLTF.Extensions.VRMC_vrm.Expression expression)
|
||||
{
|
||||
if (expression.Preset == UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
|
||||
{
|
||||
return ExpressionKey.CreateCustom(expression.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ExpressionKey.CreateFromPreset(expression.Preset);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _id.Replace(UnknownPresetPrefix, "");
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UniGLTF;
|
||||
using UnityEngine;
|
||||
using VrmLib;
|
||||
using VRMShaders;
|
||||
|
||||
|
||||
@@ -16,7 +14,7 @@ namespace UniVRM10
|
||||
/// </summary>
|
||||
public class Vrm10Importer : UniGLTF.ImporterContext
|
||||
{
|
||||
readonly Model m_model;
|
||||
readonly VrmLib.Model m_model;
|
||||
|
||||
UniGLTF.Extensions.VRMC_vrm.VRMC_vrm m_vrm;
|
||||
|
||||
@@ -54,61 +52,61 @@ namespace UniVRM10
|
||||
// assign humanoid bones
|
||||
if (m_vrm.Humanoid != null)
|
||||
{
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Hips, HumanoidBones.hips);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftUpperLeg, HumanoidBones.leftUpperLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightUpperLeg, HumanoidBones.rightUpperLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLowerLeg, HumanoidBones.leftLowerLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLowerLeg, HumanoidBones.rightLowerLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftFoot, HumanoidBones.leftFoot);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightFoot, HumanoidBones.rightFoot);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Spine, HumanoidBones.spine);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Chest, HumanoidBones.chest);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Neck, HumanoidBones.neck);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Head, HumanoidBones.head);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftShoulder, HumanoidBones.leftShoulder);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightShoulder, HumanoidBones.rightShoulder);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftUpperArm, HumanoidBones.leftUpperArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightUpperArm, HumanoidBones.rightUpperArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLowerArm, HumanoidBones.leftLowerArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLowerArm, HumanoidBones.rightLowerArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftHand, HumanoidBones.leftHand);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightHand, HumanoidBones.rightHand);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftToes, HumanoidBones.leftToes);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightToes, HumanoidBones.rightToes);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftEye, HumanoidBones.leftEye);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightEye, HumanoidBones.rightEye);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Jaw, HumanoidBones.jaw);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftThumbProximal, HumanoidBones.leftThumbProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftThumbIntermediate, HumanoidBones.leftThumbIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftThumbDistal, HumanoidBones.leftThumbDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftIndexProximal, HumanoidBones.leftIndexProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftIndexIntermediate, HumanoidBones.leftIndexIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftIndexDistal, HumanoidBones.leftIndexDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftMiddleProximal, HumanoidBones.leftMiddleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftMiddleIntermediate, HumanoidBones.leftMiddleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftMiddleDistal, HumanoidBones.leftMiddleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftRingProximal, HumanoidBones.leftRingProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftRingIntermediate, HumanoidBones.leftRingIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftRingDistal, HumanoidBones.leftRingDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLittleProximal, HumanoidBones.leftLittleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLittleIntermediate, HumanoidBones.leftLittleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLittleDistal, HumanoidBones.leftLittleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightThumbProximal, HumanoidBones.rightThumbProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightThumbIntermediate, HumanoidBones.rightThumbIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightThumbDistal, HumanoidBones.rightThumbDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightIndexProximal, HumanoidBones.rightIndexProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightIndexIntermediate, HumanoidBones.rightIndexIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightIndexDistal, HumanoidBones.rightIndexDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightMiddleProximal, HumanoidBones.rightMiddleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightMiddleIntermediate, HumanoidBones.rightMiddleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightMiddleDistal, HumanoidBones.rightMiddleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightRingProximal, HumanoidBones.rightRingProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightRingIntermediate, HumanoidBones.rightRingIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightRingDistal, HumanoidBones.rightRingDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLittleProximal, HumanoidBones.rightLittleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLittleIntermediate, HumanoidBones.rightLittleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLittleDistal, HumanoidBones.rightLittleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.UpperChest, HumanoidBones.upperChest);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Hips, VrmLib.HumanoidBones.hips);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftUpperLeg, VrmLib.HumanoidBones.leftUpperLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightUpperLeg, VrmLib.HumanoidBones.rightUpperLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLowerLeg, VrmLib.HumanoidBones.leftLowerLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLowerLeg, VrmLib.HumanoidBones.rightLowerLeg);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftFoot, VrmLib.HumanoidBones.leftFoot);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightFoot, VrmLib.HumanoidBones.rightFoot);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Spine, VrmLib.HumanoidBones.spine);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Chest, VrmLib.HumanoidBones.chest);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Neck, VrmLib.HumanoidBones.neck);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Head, VrmLib.HumanoidBones.head);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftShoulder, VrmLib.HumanoidBones.leftShoulder);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightShoulder, VrmLib.HumanoidBones.rightShoulder);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftUpperArm, VrmLib.HumanoidBones.leftUpperArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightUpperArm, VrmLib.HumanoidBones.rightUpperArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLowerArm, VrmLib.HumanoidBones.leftLowerArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLowerArm, VrmLib.HumanoidBones.rightLowerArm);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftHand, VrmLib.HumanoidBones.leftHand);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightHand, VrmLib.HumanoidBones.rightHand);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftToes, VrmLib.HumanoidBones.leftToes);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightToes, VrmLib.HumanoidBones.rightToes);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftEye, VrmLib.HumanoidBones.leftEye);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightEye, VrmLib.HumanoidBones.rightEye);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.Jaw, VrmLib.HumanoidBones.jaw);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftThumbProximal, VrmLib.HumanoidBones.leftThumbProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftThumbIntermediate, VrmLib.HumanoidBones.leftThumbIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftThumbDistal, VrmLib.HumanoidBones.leftThumbDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftIndexProximal, VrmLib.HumanoidBones.leftIndexProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftIndexIntermediate, VrmLib.HumanoidBones.leftIndexIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftIndexDistal, VrmLib.HumanoidBones.leftIndexDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftMiddleProximal, VrmLib.HumanoidBones.leftMiddleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftMiddleIntermediate, VrmLib.HumanoidBones.leftMiddleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftMiddleDistal, VrmLib.HumanoidBones.leftMiddleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftRingProximal, VrmLib.HumanoidBones.leftRingProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftRingIntermediate, VrmLib.HumanoidBones.leftRingIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftRingDistal, VrmLib.HumanoidBones.leftRingDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLittleProximal, VrmLib.HumanoidBones.leftLittleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLittleIntermediate, VrmLib.HumanoidBones.leftLittleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.LeftLittleDistal, VrmLib.HumanoidBones.leftLittleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightThumbProximal, VrmLib.HumanoidBones.rightThumbProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightThumbIntermediate, VrmLib.HumanoidBones.rightThumbIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightThumbDistal, VrmLib.HumanoidBones.rightThumbDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightIndexProximal, VrmLib.HumanoidBones.rightIndexProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightIndexIntermediate, VrmLib.HumanoidBones.rightIndexIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightIndexDistal, VrmLib.HumanoidBones.rightIndexDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightMiddleProximal, VrmLib.HumanoidBones.rightMiddleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightMiddleIntermediate, VrmLib.HumanoidBones.rightMiddleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightMiddleDistal, VrmLib.HumanoidBones.rightMiddleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightRingProximal, VrmLib.HumanoidBones.rightRingProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightRingIntermediate, VrmLib.HumanoidBones.rightRingIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightRingDistal, VrmLib.HumanoidBones.rightRingDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLittleProximal, VrmLib.HumanoidBones.rightLittleProximal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLittleIntermediate, VrmLib.HumanoidBones.rightLittleIntermediate);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.RightLittleDistal, VrmLib.HumanoidBones.rightLittleDistal);
|
||||
AssignHumanoid(m_model.Nodes, m_vrm.Humanoid.HumanBones.UpperChest, VrmLib.HumanoidBones.upperChest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +122,7 @@ namespace UniVRM10
|
||||
/// <returns></returns>
|
||||
readonly ModelMap m_map = new ModelMap();
|
||||
|
||||
static void AssignHumanoid(List<Node> nodes, UniGLTF.Extensions.VRMC_vrm.HumanBone humanBone, VrmLib.HumanoidBones key)
|
||||
static void AssignHumanoid(List<VrmLib.Node> nodes, UniGLTF.Extensions.VRMC_vrm.HumanBone humanBone, VrmLib.HumanoidBones key)
|
||||
{
|
||||
if (humanBone != null && humanBone.Node.HasValue)
|
||||
{
|
||||
@@ -620,28 +618,22 @@ namespace UniVRM10
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public override void TransferOwnership(Func<UnityEngine.Object, bool> take)
|
||||
public override void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
|
||||
{
|
||||
// VRM 固有のリソース(ScriptableObject)
|
||||
if (take(m_humanoid))
|
||||
{
|
||||
m_humanoid = null;
|
||||
}
|
||||
take(SubAssetKey.Create(m_humanoid), m_humanoid);
|
||||
m_humanoid = null;
|
||||
|
||||
if (m_meta != null)
|
||||
{
|
||||
if (take(m_meta))
|
||||
{
|
||||
m_meta = null;
|
||||
}
|
||||
take(VRM10MetaObject.SubAssetKey, m_meta);
|
||||
m_meta = null;
|
||||
}
|
||||
|
||||
foreach (var x in m_expressions)
|
||||
{
|
||||
if (take(x))
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
take(ExpressionKey.CreateFromClip(x).SubAssetKey, x);
|
||||
// do nothing
|
||||
}
|
||||
m_expressions.Clear();
|
||||
|
||||
@@ -651,21 +643,19 @@ namespace UniVRM10
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Action<UnityEngine.Object> destroy = UnityResourceDestroyer.DestroyResource();
|
||||
|
||||
// VRM specific
|
||||
if (m_humanoid != null)
|
||||
{
|
||||
destroy(m_humanoid);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(m_humanoid);
|
||||
}
|
||||
if (m_meta != null)
|
||||
{
|
||||
destroy(m_meta);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(m_meta);
|
||||
}
|
||||
|
||||
foreach (var clip in m_expressions)
|
||||
{
|
||||
destroy(clip);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(clip);
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace UniVRM10.Sample
|
||||
|
||||
using (var loader = new Vrm10Importer(result.Parser, result.Vrm))
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
return loader.DisposeOnGameObjectDestroyed().gameObject;
|
||||
var loaded = loader.Load();
|
||||
loaded.ShowMeshes();
|
||||
return loaded.gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace UniVRM10.Test
|
||||
private (GameObject, IReadOnlyList<VRMShaders.MaterialFactory.MaterialLoadInfo>) ToUnity(byte[] bytes)
|
||||
{
|
||||
// Vrm => Model
|
||||
if(!Vrm10Parser.TryParseOrMigrate("tpm.vrm", bytes, true, out Vrm10Parser.Result result, out string error))
|
||||
if (!Vrm10Parser.TryParseOrMigrate("tpm.vrm", bytes, true, out Vrm10Parser.Result result, out string error))
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
@@ -44,9 +44,8 @@ namespace UniVRM10.Test
|
||||
// Model => Unity
|
||||
using (var loader = new Vrm10Importer(parser, vrm))
|
||||
{
|
||||
loader.Load();
|
||||
loader.DisposeOnGameObjectDestroyed();
|
||||
return (loader.Root, loader.MaterialFactory.Materials);
|
||||
var loaded = loader.Load();
|
||||
return (loaded.gameObject, loader.MaterialFactory.Materials);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ namespace UniVRM10.Test
|
||||
{
|
||||
using (var loader = new Vrm10Importer(parser, vrm))
|
||||
{
|
||||
loader.Load();
|
||||
var loaded = loader.Load();
|
||||
if (showMesh)
|
||||
{
|
||||
loader.ShowMeshes();
|
||||
loaded.ShowMeshes();
|
||||
}
|
||||
loader.EnableUpdateWhenOffscreen();
|
||||
return loader.DisposeOnGameObjectDestroyed().gameObject;
|
||||
loaded.EnableUpdateWhenOffscreen();
|
||||
return loaded.gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
public delegate void TakeResponsibilityForDestroyObjectFunc(SubAssetKey key, UnityEngine.Object obj);
|
||||
|
||||
/// <summary>
|
||||
/// UnityObjectを破棄する責務。
|
||||
///
|
||||
/// この interface を実装するクラスは、利用後に破棄すべき UnityObject を保持する可能性があるので
|
||||
/// Dispose により解放すること。
|
||||
///
|
||||
/// TransferOwnership により、破棄責任を移譲することができる。
|
||||
///
|
||||
/// </summary>
|
||||
public interface IResponsibilityForDestroyObjects : IDisposable
|
||||
{
|
||||
void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93ab2216c7e8c684d84873bd2ae72c6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
13
Assets/VRMShaders/GLTF/IO/Runtime/KeyValuePariExtensions.cs
Normal file
13
Assets/VRMShaders/GLTF/IO/Runtime/KeyValuePariExtensions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
public static class KeyValuePariExtensions
|
||||
{
|
||||
public static void Deconstruct<T, U>(this KeyValuePair<T, U> pair, out T key, out U value)
|
||||
{
|
||||
key = pair.Key;
|
||||
value = pair.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dd6ef3302d21eb4b83c4f8f2c1e47cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -9,7 +8,7 @@ namespace VRMShaders
|
||||
{
|
||||
public delegate Task<Texture> GetTextureAsyncFunc(TextureDescriptor texDesc);
|
||||
|
||||
public class MaterialFactory : IDisposable
|
||||
public class MaterialFactory : IResponsibilityForDestroyObjects
|
||||
{
|
||||
private readonly IReadOnlyDictionary<SubAssetKey, Material> m_externalMap;
|
||||
|
||||
@@ -30,13 +29,15 @@ namespace VRMShaders
|
||||
|
||||
public struct MaterialLoadInfo
|
||||
{
|
||||
public SubAssetKey Key;
|
||||
public readonly Material Asset;
|
||||
public readonly bool UseExternal;
|
||||
|
||||
public bool IsSubAsset => !UseExternal;
|
||||
|
||||
public MaterialLoadInfo(Material asset, bool useExternal)
|
||||
public MaterialLoadInfo(SubAssetKey key, Material asset, bool useExternal)
|
||||
{
|
||||
Key = key;
|
||||
Asset = asset;
|
||||
UseExternal = useExternal;
|
||||
}
|
||||
@@ -64,7 +65,7 @@ namespace VRMShaders
|
||||
#if VRM_DEVELOP
|
||||
// Debug.Log($"Destroy {x.Asset}");
|
||||
#endif
|
||||
UnityEngine.Object.DestroyImmediate(x.Asset, false);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(x.Asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,24 +80,17 @@ namespace VRMShaders
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="take"></param>
|
||||
public void TransferOwnership(Func<UnityEngine.Object, bool> take)
|
||||
public void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
|
||||
{
|
||||
var list = new List<Material>();
|
||||
foreach (var x in m_materials)
|
||||
foreach (var x in m_materials.ToArray())
|
||||
{
|
||||
if (!x.UseExternal)
|
||||
{
|
||||
// 外部の '.asset' からロードしていない
|
||||
if (take(x.Asset))
|
||||
{
|
||||
list.Add(x.Asset);
|
||||
}
|
||||
take(x.Key, x.Asset);
|
||||
m_materials.Remove(x);
|
||||
}
|
||||
}
|
||||
foreach (var x in list)
|
||||
{
|
||||
Remove(x);
|
||||
}
|
||||
}
|
||||
|
||||
public Material GetMaterial(int index)
|
||||
@@ -110,7 +104,7 @@ namespace VRMShaders
|
||||
{
|
||||
if (m_externalMap.TryGetValue(matDesc.SubAssetKey, out Material material))
|
||||
{
|
||||
m_materials.Add(new MaterialLoadInfo(material, true));
|
||||
m_materials.Add(new MaterialLoadInfo(matDesc.SubAssetKey, material, true));
|
||||
return material;
|
||||
}
|
||||
|
||||
@@ -174,7 +168,7 @@ namespace VRMShaders
|
||||
action(material);
|
||||
}
|
||||
|
||||
m_materials.Add(new MaterialLoadInfo(material, false));
|
||||
m_materials.Add(new MaterialLoadInfo(matDesc.SubAssetKey, material, false));
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRMShaders
|
||||
@@ -7,15 +6,16 @@ namespace VRMShaders
|
||||
/// <summary>
|
||||
/// UnityEditor.Experimental.AssetImporter.SourceAssetIdentifier に対応する
|
||||
///
|
||||
/// * SourceAssetIdentifier が UnityEditor なので、 Runtime でも使えるように
|
||||
/// * SourceAssetIdentifier が UnityEditor なので、 Runtime でも使えるように作成
|
||||
/// * Type が違うが Name が同じだと警告が出る。例えば、Material と 同じ名前の Texture がある場合。
|
||||
/// Identifier uniqueness violation: 'Alicia_body'. Scripted Importers do not guarantee that subsequent imports of this asset will properly re-link to these targets.
|
||||
/// * なので、SourceAssetIdentifier は、$"{Type.Name}.{UnityObject.name}" のように強制的に Unique にするのが良さそう
|
||||
/// * 一方で、Extract したファイル名に $"{Type.Name}." が付属するのは煩わしいのでこれは無しにしたい。
|
||||
///
|
||||
/// public void AddRemap(SourceAssetIdentifier identifier, UnityEngine.Object externalObject);
|
||||
///
|
||||
/// の呼び出し時に、identifier.name と externalObject.name が同じでない運用にしてみる。
|
||||
/// scriptedImporter.GetExternalObjectMap
|
||||
///
|
||||
/// に関係する。
|
||||
///
|
||||
/// SubAssetKey を新しく作る場所は集約して、不一致が起こらないように注意する
|
||||
///
|
||||
/// </summary>
|
||||
public readonly struct SubAssetKey : IEquatable<SubAssetKey>
|
||||
@@ -48,6 +48,11 @@ namespace VRMShaders
|
||||
Name = obj.name;
|
||||
}
|
||||
|
||||
public static SubAssetKey Create<T>(T obj) where T : UnityEngine.Object
|
||||
{
|
||||
return new SubAssetKey(typeof(T), obj.name);
|
||||
}
|
||||
|
||||
public SubAssetKey(Type type, string name)
|
||||
{
|
||||
if (type == null || string.IsNullOrEmpty(name))
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
public class TextureFactory : IDisposable
|
||||
public class TextureFactory : IResponsibilityForDestroyObjects
|
||||
{
|
||||
private readonly ITextureDeserializer _textureDeserializer;
|
||||
private readonly IReadOnlyDictionary<SubAssetKey, Texture> _externalMap;
|
||||
@@ -33,7 +33,7 @@ namespace VRMShaders
|
||||
{
|
||||
foreach (var kv in _temporaryTextures)
|
||||
{
|
||||
DestroyResource(kv.Value);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(kv.Value);
|
||||
}
|
||||
_temporaryTextures.Clear();
|
||||
_textureCache.Clear();
|
||||
@@ -43,20 +43,12 @@ namespace VRMShaders
|
||||
/// 所有権(Dispose権)を移譲する
|
||||
/// </summary>
|
||||
/// <param name="take"></param>
|
||||
public void TransferOwnership(Func<UnityEngine.Object, bool> take)
|
||||
public void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
|
||||
{
|
||||
var transferredAssets = new HashSet<SubAssetKey>();
|
||||
foreach (var x in _textureCache)
|
||||
foreach (var (k, v) in _textureCache.ToArray())
|
||||
{
|
||||
if (take(x.Value))
|
||||
{
|
||||
transferredAssets.Add(x.Key);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var key in transferredAssets)
|
||||
{
|
||||
_textureCache.Remove(key);
|
||||
take(k, v);
|
||||
_textureCache.Remove(k);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,80 +73,68 @@ namespace VRMShaders
|
||||
switch (texDesc.TextureType)
|
||||
{
|
||||
case TextureImportTypes.NormalMap:
|
||||
{
|
||||
// no conversion. Unity's normal map is same with glTF's.
|
||||
//
|
||||
// > contrary to Unity’s usual convention of using Y as “up”
|
||||
// https://docs.unity3d.com/2018.4/Documentation/Manual/StandardShaderMaterialParameterNormalMap.html
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
rawTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
return rawTexture;
|
||||
}
|
||||
{
|
||||
// no conversion. Unity's normal map is same with glTF's.
|
||||
//
|
||||
// > contrary to Unity’s usual convention of using Y as “up”
|
||||
// https://docs.unity3d.com/2018.4/Documentation/Manual/StandardShaderMaterialParameterNormalMap.html
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
rawTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
return rawTexture;
|
||||
}
|
||||
|
||||
case TextureImportTypes.StandardMap:
|
||||
{
|
||||
Texture2D metallicRoughnessTexture = default;
|
||||
Texture2D occlusionTexture = default;
|
||||
|
||||
if (texDesc.Index0 != null)
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
metallicRoughnessTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
}
|
||||
if (texDesc.Index1 != null)
|
||||
{
|
||||
var data1 = await texDesc.Index1();
|
||||
occlusionTexture = await _textureDeserializer.LoadTextureAsync(data1, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
}
|
||||
Texture2D metallicRoughnessTexture = default;
|
||||
Texture2D occlusionTexture = default;
|
||||
|
||||
var combinedTexture = OcclusionMetallicRoughnessConverter.Import(metallicRoughnessTexture,
|
||||
texDesc.MetallicFactor, texDesc.RoughnessFactor, occlusionTexture);
|
||||
combinedTexture.name = subAssetKey.Name;
|
||||
combinedTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, combinedTexture);
|
||||
DestroyResource(metallicRoughnessTexture);
|
||||
DestroyResource(occlusionTexture);
|
||||
return combinedTexture;
|
||||
}
|
||||
if (texDesc.Index0 != null)
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
metallicRoughnessTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
}
|
||||
if (texDesc.Index1 != null)
|
||||
{
|
||||
var data1 = await texDesc.Index1();
|
||||
occlusionTexture = await _textureDeserializer.LoadTextureAsync(data1, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
}
|
||||
|
||||
var combinedTexture = OcclusionMetallicRoughnessConverter.Import(metallicRoughnessTexture,
|
||||
texDesc.MetallicFactor, texDesc.RoughnessFactor, occlusionTexture);
|
||||
combinedTexture.name = subAssetKey.Name;
|
||||
combinedTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, combinedTexture);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(metallicRoughnessTexture);
|
||||
UnityObjectDestoyer.DestroyRuntimeOrEditor(occlusionTexture);
|
||||
return combinedTexture;
|
||||
}
|
||||
|
||||
case TextureImportTypes.sRGB:
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.sRGB);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
rawTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
return rawTexture;
|
||||
}
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.sRGB);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
rawTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
return rawTexture;
|
||||
}
|
||||
case TextureImportTypes.Linear:
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
rawTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
return rawTexture;
|
||||
}
|
||||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await _textureDeserializer.LoadTextureAsync(data0, texDesc.Sampler.EnableMipMap, ColorSpace.Linear);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
rawTexture.SetSampler(texDesc.Sampler);
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
return rawTexture;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static void DestroyResource(UnityEngine.Object o)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
UnityEngine.Object.Destroy(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
Assets/VRMShaders/GLTF/IO/Runtime/UnityObjectDestroyer.cs
Normal file
19
Assets/VRMShaders/GLTF/IO/Runtime/UnityObjectDestroyer.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRMShaders
|
||||
{
|
||||
public static class UnityObjectDestoyer
|
||||
{
|
||||
public static void DestroyRuntimeOrEditor(UnityEngine.Object o)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
UnityEngine.Object.Destroy(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b4d1043455aa2c489e9ad8250a80fc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user