From 5d3c66513cbd20ce71feb47b65a83e0a0defc857 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 26 Aug 2024 20:41:06 +0900 Subject: [PATCH] =?UTF-8?q?mesh=20export=20=E6=99=82=E3=81=AE=20byteLength?= =?UTF-8?q?=20=E7=A2=BA=E8=AA=8D=E3=83=86=E3=82=B9=E3=83=88=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #2413 --- Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs | 36 ++++++ .../VRM10/Runtime/IO/Material/URP/Export.meta | 8 ++ .../URP/Export/UrpVrm10MaterialExporter.cs | 19 ++++ .../Export/UrpVrm10MaterialExporter.cs.meta | 11 ++ .../Material/Vrm10MaterialExporterUtility.cs | 2 +- Assets/VRM10/Tests/LoadTests.cs | 107 ++++++++++++++++++ 6 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 Assets/VRM10/Runtime/IO/Material/URP/Export.meta create mode 100644 Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs create mode 100644 Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs.meta diff --git a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs index a96368fc3..1368a4fbd 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/UniGLTFTests.cs @@ -741,6 +741,42 @@ namespace UniGLTF } } + // + // https://github.com/vrm-c/UniVRM/pull/2413 + // + [Test] + public void ExportingMeshByteLengthTest() + { + var validator = ScriptableObject.CreateInstance(); + var root = new GameObject("root"); + try + { + { + var child = TestGltf.CreatePrimitiveAsBuiltInRP(PrimitiveType.Cube); + child.transform.SetParent(root.transform); + } + // export + var data = TestGltf.ExportAsBuiltInRP(root); + var gltf = data.Gltf; + // cube + var expected = + // pos + (4*3)*24 + // normal + +(4*3)*24 + // uv + +(4*2)*24 + // indices + + 4 * 36; + Assert.AreEqual(expected, gltf.buffers[0].byteLength); + } + finally + { + GameObject.DestroyImmediate(root); + ScriptableObject.DestroyImmediate(validator); + } + } + [Serializable] class CantConstruct { diff --git a/Assets/VRM10/Runtime/IO/Material/URP/Export.meta b/Assets/VRM10/Runtime/IO/Material/URP/Export.meta new file mode 100644 index 000000000..110719821 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Material/URP/Export.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a6506c50290f7fb48984c1c5e83929e4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs b/Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs new file mode 100644 index 000000000..f4795e313 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs @@ -0,0 +1,19 @@ +using UniGLTF; +using UnityEngine; + +namespace UniVRM10 +{ + public class UrpVrm10MaterialExporter : IMaterialExporter + { + public glTFMaterial ExportMaterial(Material m, ITextureExporter textureExporter, GltfExportSettings settings) + { + #if UNITY_EDITOR + return new glTFMaterial{ + name = "dummyForTest", + }; + #else + throw new System.NotImplementedException(); + #endif + } + } +} diff --git a/Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs.meta b/Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs.meta new file mode 100644 index 000000000..1678788b4 --- /dev/null +++ b/Assets/VRM10/Runtime/IO/Material/URP/Export/UrpVrm10MaterialExporter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95b7c97505db9d747b04136aa1505204 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialExporterUtility.cs b/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialExporterUtility.cs index 5f8e61397..2ba387126 100644 --- a/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialExporterUtility.cs +++ b/Assets/VRM10/Runtime/IO/Material/Vrm10MaterialExporterUtility.cs @@ -8,7 +8,7 @@ namespace UniVRM10 { return RenderPipelineUtility.GetRenderPipelineType() switch { - RenderPipelineTypes.UniversalRenderPipeline => throw new System.NotImplementedException(), + RenderPipelineTypes.UniversalRenderPipeline => new UrpVrm10MaterialExporter(), RenderPipelineTypes.BuiltinRenderPipeline => new BuiltInVrm10MaterialExporter(), _ => new BuiltInVrm10MaterialExporter(), }; diff --git a/Assets/VRM10/Tests/LoadTests.cs b/Assets/VRM10/Tests/LoadTests.cs index 02e1deee2..18caa14f7 100644 --- a/Assets/VRM10/Tests/LoadTests.cs +++ b/Assets/VRM10/Tests/LoadTests.cs @@ -1,5 +1,8 @@ +using System.IO; +using System.Linq; using NUnit.Framework; using UniGLTF; +using UnityEngine; namespace UniVRM10.Test { @@ -25,5 +28,109 @@ namespace UniVRM10.Test } } } + + static string ModelPath + { + get + { + // submodule + return Path.GetFullPath(Application.dataPath + "/../vrm-specification/samples/Seed-san/vrm/Seed-san.vrm") + .Replace("\\", "/"); + } + } + + static int getByteLength(glTF gltf, int accessorIndex) + { + if (accessorIndex < 0) { return 0; } + var accessor = gltf.accessors[accessorIndex]; + return accessor.CalcByteSize(); + } + + static int getByteLength(glTF gltf, glTFPrimitives prim) + { + var l = 0; + l += getByteLength(gltf, prim.indices); + l += getByteLength(gltf, prim.attributes.POSITION); + l += getByteLength(gltf, prim.attributes.NORMAL); + l += getByteLength(gltf, prim.attributes.TANGENT); + l += getByteLength(gltf, prim.attributes.TEXCOORD_0); + l += getByteLength(gltf, prim.attributes.JOINTS_0); + l += getByteLength(gltf, prim.attributes.WEIGHTS_0); + foreach (var morph in prim.targets) + { + l += getByteLength(gltf, morph.POSITION); + l += getByteLength(gltf, morph.NORMAL); + l += getByteLength(gltf, morph.TANGENT); + } + return l; + } + + static int getByteLength(glTF gltf, glTFMesh mesh) + { + var l = 0; + foreach (var prim in mesh.primitives) + { + l += getByteLength(gltf, prim); + } + return l; + } + + [Test] + public void NoTexture() + { + if (!File.Exists(ModelPath)) + { + return; + } + + // load model + var task = Vrm10.LoadPathAsync(ModelPath, awaitCaller: new ImmediateCaller()); + var instance = task.Result; + + // remove textures + instance.Vrm.Meta.Thumbnail = null; + var m = new Material(Shader.Find("Unlit/Color")); + foreach (var r in instance.GetComponentsInChildren()) + { + r.sharedMaterials = r.sharedMaterials.Select(x => m).ToArray(); + } + + // export as vrm1 + using (var arrayManager = new NativeArrayManager()) + { + var converter = new UniVRM10.ModelExporter(); + var model = converter.Export(arrayManager, instance.gameObject); + + // 右手系に変換 + Debug.Log($"convert to right handed coordinate..."); + model.ConvertCoordinate(VrmLib.Coordinates.Vrm1, ignoreVrm: false); + + // export vrm-1.0 + var exporter = new Vrm10Exporter(new GltfExportSettings()); + exporter.Export(instance.gameObject, model, converter, new VrmLib.ExportArgs + { + sparse = false, + }); + + var gltf = exporter.Storage.Gltf; + + var last = gltf.bufferViews.Last(); + // https://github.com/vrm-c/UniVRM/pull/2413 + Assert.AreEqual(last.byteOffset + last.byteLength, exporter.Storage.Gltf.buffers[0].byteLength); + + // check byteLength + var expected = 0; + foreach (var mesh in gltf.meshes) + { + expected += getByteLength(gltf, mesh); + } + foreach (var skin in gltf.skins) + { + expected += getByteLength(gltf, skin.inverseBindMatrices); + } + // alighment ? + // Assert.AreEqual(expected, exporter.Storage.Gltf.buffers[0].byteLength); + } + } } }