ImporterContext.LoadAsync が UnityObjectManager を戻すようにインタフェースを変更

This commit is contained in:
ousttrue 2021-06-10 19:42:10 +09:00
parent aa6b826cb3
commit a17c789a02
27 changed files with 390 additions and 451 deletions

View File

@ -48,20 +48,17 @@ namespace UniGLTF
}
loader.InvertAxis = reverseAxis;
loader.Load();
loader.ShowMeshes();
var loaded = loader.Load();
loaded.ShowMeshes();
loader.TransferOwnership((k, o) =>
{
context.AddObjectToAsset(k.Name, o);
if (o is GameObject)
{
// Root GameObject is main object
context.SetMainObject(loader.Root);
}
return true;
});
context.AddObjectToAsset(loaded.name, loaded.gameObject);
context.SetMainObject(loaded.gameObject);
}
}
}

View File

@ -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<UnityObjectManager> LoadAsync(IAwaitCaller awaitCaller = null, Func<string, IDisposable> MeasureTime = null)
{
if (awaitCaller == null)
{
@ -108,6 +108,8 @@ namespace UniGLTF
}
await OnLoadHierarchy(awaitCaller, MeasureTime);
return UnityObjectManager.AttachTo(Root, this);
}
/// <summary>
@ -274,36 +276,10 @@ 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;
}
}
}
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<(SubAssetKey, AnimationClip)> AnimationClips = new List<(SubAssetKey, AnimationClip)>();
#endregion
@ -313,36 +289,20 @@ namespace UniGLTF
/// </summary>
public virtual void Dispose()
{
Action<UnityEngine.Object> destroy = UnityObjectManager.DestroyResource();
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>
@ -370,36 +330,6 @@ namespace UniGLTF
AnimationClips.Remove((key, animation));
}
}
if (m_ownRoot && Root != null)
{
// GameObject の extract は無いので SubAssetKey を使わない
if (take(default, 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 UnityObjectManager DisposeOnGameObjectDestroyed()
{
var destroyer = Root.AddComponent<UnityObjectManager>();
TransferOwnership((k, o) =>
{
destroyer.Resources.Add(o);
return true;
});
return destroyer;
}
}
}

View File

@ -8,7 +8,7 @@ namespace UniGLTF
/// <summary>
/// Build unity objects from parsed gltf
/// </summary>
public static void Load(this ImporterContext self)
public static UnityObjectManager 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;
}
}
}

View File

@ -1,39 +1,64 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using VRMShaders;
namespace UniGLTF
{
/// <summary>
/// Mesh, Material, Texture などを抱えておいて確実に破棄できるようにする
/// </summary>
public class UnityObjectManager : MonoBehaviour
public class UnityObjectManager : MonoBehaviour, IResponsibilityForDestroyObjects
{
List<UnityEngine.Object> m_resources = new List<UnityEngine.Object>();
public IList<UnityEngine.Object> Resources => m_resources;
List<(SubAssetKey, UnityEngine.Object)> m_resources = new List<(SubAssetKey, UnityEngine.Object)>();
public static UnityObjectManager AttachTo(GameObject go, ImporterContext context)
{
var loaded = go.AddComponent<UnityObjectManager>();
context.TransferOwnership((k, o) =>
{
loaded.m_resources.Add((k, o));
return true;
});
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 x in Resources)
{
#if VRM_DEVELOP
Debug.Log($"Destroy: {x}");
#endif
Destroy(x);
}
Dispose();
}
public static Action<UnityEngine.Object> DestroyResource()
public void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take)
{
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;
throw new NotImplementedException();
}
public void Dispose()
{
foreach (var (key, x) in m_resources)
{
#if VRM_DEVELOP
// Debug.Log($"Destroy: {x}");
#endif
UnityObjectDestoyer.DestroyRuntimeOrEditor(x);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -97,16 +97,17 @@ namespace VRM.Samples
Debug.LogFormat("meta: title:{0}", meta.Title);
// ParseしたJSONをシーンオブジェクトに変換していく
var loaded = default(UnityObjectManager);
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(UnityObjectManager);
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(UnityObjectManager 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>();

View File

@ -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;
}

View File

@ -140,29 +140,29 @@ namespace VRM
return true;
}
public void SaveAsAsset()
public void SaveAsAsset(UniGLTF.UnityObjectManager loaded)
{
m_context.ShowMeshes();
loaded.ShowMeshes();
//
// save sub assets
//
m_paths.Clear();
m_paths.Add(m_prefabPath);
m_context.TransferOwnership(SaveAsAsset);
loaded.TransferOwnership(SaveAsAsset);
// 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(loaded.gameObject, 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(loaded.gameObject, m_prefabPath.Value, InteractionMode.AutomatedAction);
}
foreach (var x in m_paths)

View File

@ -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);
}
};

View File

@ -63,8 +63,8 @@ namespace VRM
{
VRMShaders.TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures);
}
context.Load();
editor.SaveAsAsset();
var loaded = context.Load();
editor.SaveAsAsset(loaded);
}
};

View File

@ -356,28 +356,26 @@ namespace VRM
public override void Dispose()
{
Action<UnityEngine.Object> destroy = UnityObjectManager.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();

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -42,20 +42,17 @@ namespace UniVRM10
VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures);
}
loader.Load();
loader.ShowMeshes();
var loaded = loader.Load();
loaded.ShowMeshes();
loader.TransferOwnership((key, o) =>
{
context.AddObjectToAsset(key.Name, o);
if (o is GameObject)
{
// Root GameObject is main object
context.SetMainObject(loader.Root);
}
return true;
});
context.AddObjectToAsset(loaded.name, loaded.gameObject);
context.SetMainObject(loaded.gameObject);
}
}
}

View File

@ -649,21 +649,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();

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
@ -66,7 +65,7 @@ namespace VRMShaders
#if VRM_DEVELOP
// Debug.Log($"Destroy {x.Asset}");
#endif
UnityEngine.Object.DestroyImmediate(x.Asset, false);
UnityObjectDestoyer.DestroyRuntimeOrEditor(x.Asset);
}
}
}

View File

@ -33,7 +33,7 @@ namespace VRMShaders
{
foreach (var kv in _temporaryTextures)
{
DestroyResource(kv.Value);
UnityObjectDestoyer.DestroyRuntimeOrEditor(kv.Value);
}
_temporaryTextures.Clear();
_textureCache.Clear();
@ -81,80 +81,68 @@ namespace VRMShaders
switch (texDesc.TextureType)
{
case TextureImportTypes.NormalMap:
{
// no conversion. Unity's normal map is same with glTF's.
//
// > contrary to Unitys 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 Unitys 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);
}
}
}
}

View 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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0b4d1043455aa2c489e9ad8250a80fc4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: