diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs index 49a134bf6..c53a9c105 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfParser.cs @@ -285,7 +285,7 @@ namespace UniGLTF if (used.Add(material.name)) { #if VRM_DEVELOP - Debug.Log($"Material: {material.name}"); + // Debug.Log($"Material: {material.name}"); #endif break; } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index 991ce537c..1537b1880 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -252,7 +252,7 @@ namespace UniGLTF foreach (var x in Meshes) { #if VRM_DEVELOP - Debug.Log($"Destroy {x}"); + Debug.Log($"Destroy {x.Mesh}"); #endif destroy(x.Mesh); } diff --git a/Assets/UniGLTF/Tests/UniGLTF/AssetTests.cs b/Assets/UniGLTF/Tests/UniGLTF/AssetTests.cs new file mode 100644 index 000000000..50b0a6867 --- /dev/null +++ b/Assets/UniGLTF/Tests/UniGLTF/AssetTests.cs @@ -0,0 +1,41 @@ +using NUnit.Framework; +using UnityEditor; +using UnityEngine; + +namespace UniGLTF +{ + public class AssetTests + { + [Test] + public void TestAsset() + { + var mesh = new Mesh(); + var assetPath = AssetDatabase.GenerateUniqueAssetPath("Assets/test_mesh.asset"); + var loaded = default(Mesh); + + try + { + Assert.IsFalse(AssetDatabase.IsMainAsset(mesh)); + Assert.IsFalse(AssetDatabase.IsSubAsset(mesh)); + + AssetDatabase.CreateAsset(mesh, assetPath); + + Assert.IsTrue(AssetDatabase.IsMainAsset(mesh)); + Assert.IsFalse(AssetDatabase.IsSubAsset(mesh)); + + loaded = AssetDatabase.LoadAssetAtPath(assetPath); + Assert.AreEqual(mesh, loaded); + } + finally + { + // remove assetPath + UnityEngine.Object.DestroyImmediate(loaded, true); + + var tmp = AssetDatabase.LoadAssetAtPath(assetPath); + Assert.Null(tmp); + } + + AssetDatabase.Refresh(); + } + } +} diff --git a/Assets/UniGLTF/Tests/UniGLTF/AssetTests.cs.meta b/Assets/UniGLTF/Tests/UniGLTF/AssetTests.cs.meta new file mode 100644 index 000000000..327b66aa6 --- /dev/null +++ b/Assets/UniGLTF/Tests/UniGLTF/AssetTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 513b70f5eb05a53479b2b12a85139cbe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs b/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs index 852ae2b2c..e484e372f 100644 --- a/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs +++ b/Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs @@ -51,63 +51,147 @@ namespace VRM.Samples context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); - 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); - - // TODO: Check contents in JSON - /*var exportJson = */ - JsonParser.Parse(vrm.ToJson()); - - // TODO: Check contents in JSON - /*var newExportedJson = */ - // JsonParser.Parse(JsonSchema.FromType().Serialize(vrm)); - - /* - foreach (var kv in importJson.Diff(exportJson)) + var destroyer = context.DisposeOnGameObjectDestroyed(); + try { - Debug.Log(kv); - } + // mesh + { + foreach (var renderer in destroyer.GetComponentsInChildren()) + { + Mesh mesh = default; + if (renderer is MeshRenderer) + { + var f = renderer.GetComponent(); + mesh = f.sharedMesh; + } + else if (renderer is SkinnedMeshRenderer smr) + { + mesh = smr.sharedMesh; + } - Assert.AreEqual(importJson, exportJson); - */ + 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") + { + // 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(); + } + } + } + } + + // meta + { + var meta = destroyer.GetComponent(); + } + + // humanoid + { + var animator = destroyer.GetComponent(); + } + + + // blendshape + { + var blendshapeProxy = destroyer.GetComponent(); + 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); + + // TODO: Check contents in JSON + /*var exportJson = */ + JsonParser.Parse(vrm.ToJson()); + + // TODO: Check contents in JSON + /*var newExportedJson = */ + // JsonParser.Parse(JsonSchema.FromType().Serialize(vrm)); + + /* + foreach (var kv in importJson.Diff(exportJson)) + { + Debug.Log(kv); + } + + Assert.AreEqual(importJson, exportJson); + */ + } + finally + { + UnityEngine.Object.DestroyImmediate(destroyer.gameObject); + } } } diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index 8279fc9cf..3c59f3ecd 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -324,18 +324,13 @@ namespace VRM AvatarDescription = null; } - var list = new List(); foreach (var x in BlendShapeAvatar.Clips) { if (take(x)) { - list.Add(x); + // do nothing } } - foreach (var x in list) - { - BlendShapeAvatar.Clips.Remove(x); - } if (take(BlendShapeAvatar)) { @@ -345,5 +340,34 @@ namespace VRM // GLTF のリソース base.TransferOwnership(take); } + + public override void Dispose() + { + Action destroy = UnityResourceDestroyer.DestroyResource(); + + // VRM specific + if (HumanoidAvatar != null) + { + destroy(HumanoidAvatar); + } + if (Meta != null) + { + destroy(Meta); + } + if (AvatarDescription != null) + { + destroy(AvatarDescription); + } + if (BlendShapeAvatar != null) + { + foreach (var clip in BlendShapeAvatar.Clips) + { + destroy(clip); + } + destroy(BlendShapeAvatar); + } + + base.Dispose(); + } } }