From f199c593b7d099c94d545ab9897c1c21910d8065 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 5 Apr 2022 12:48:43 +0900 Subject: [PATCH 1/3] detect dividedVertexBuffer --- Assets/VRM10/Runtime/Migration/MeshUpdater.cs | 156 ++++++++++-------- 1 file changed, 89 insertions(+), 67 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs index aeb8611f5..c6148e3c4 100644 --- a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs +++ b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs @@ -75,74 +75,13 @@ namespace UniVRM10 image.bufferView = AddBuffer(bytes); } - // update Mesh - foreach (var (gltfMesh, mesh) in Enumerable.Zip(gltf.meshes, model.MeshGroups, (l, r) => (l, r.Meshes[0]))) + if (model.MeshGroups.All(x => x.Meshes.Count == 1)) { - NativeArray indices; - switch (mesh.IndexBuffer.Stride) - { - case 1: - { - // byte - var byte_indices = mesh.IndexBuffer.GetSpan(); - indices = _data.NativeArrayManager.Convert(byte_indices, (byte x) => (uint)x); - break; - } - - case 2: - { - // ushort - var ushort_indices = mesh.IndexBuffer.GetSpan(); - indices = _data.NativeArrayManager.Convert(ushort_indices, (ushort x) => (uint)x); - break; - } - - case 4: - { - // uint - indices = mesh.IndexBuffer.GetSpan(); - break; - } - - default: - throw new NotImplementedException(); - } - var position = AddAccessor(mesh.VertexBuffer.Positions); - var normal = AddAccessor(mesh.VertexBuffer.Normals); - var uv = AddAccessor(mesh.VertexBuffer.TexCoords); - var weights = AddAccessor(mesh.VertexBuffer.Weights); - var joints = AddAccessor(mesh.VertexBuffer.Joints); - var color = AddAccessor(mesh.VertexBuffer.Colors); - - var morphTargets = new MorphAccessor[] { }; - if (mesh.MorphTargets != null) - { - morphTargets = mesh.MorphTargets.Select(x => new MorphAccessor - { - Position = AddAccessor(x.VertexBuffer.Positions), - Normal = AddAccessor(x.VertexBuffer.Normals), - }).ToArray(); - } - - foreach (var (gltfPrim, submesh) in Enumerable.Zip(gltfMesh.primitives, mesh.Submeshes, (l, r) => (l, r))) - { - var subIndices = indices.GetSubArray(submesh.Offset, submesh.DrawCount); - gltfPrim.indices = AddAccessor(subIndices); - gltfPrim.attributes.POSITION = position.Value; - gltfPrim.attributes.NORMAL = normal.GetValueOrDefault(-1); // たぶん、ありえる - gltfPrim.attributes.TANGENT = -1; - gltfPrim.attributes.COLOR_0 = color.GetValueOrDefault(-1); - gltfPrim.attributes.TEXCOORD_0 = uv.GetValueOrDefault(-1); // ありえる? - gltfPrim.attributes.TEXCOORD_1 = -1; - gltfPrim.attributes.WEIGHTS_0 = weights.GetValueOrDefault(-1); - gltfPrim.attributes.JOINTS_0 = joints.GetValueOrDefault(-1); - foreach (var (gltfMorph, morph) in Enumerable.Zip(gltfPrim.targets, morphTargets, (l, r) => (l, r))) - { - gltfMorph.POSITION = morph.Position.GetValueOrDefault(-1); - gltfMorph.NORMAL = morph.Normal.GetValueOrDefault(-1); - gltfMorph.TANGENT = -1; - } - } + UpdateSharedVertexBuffer(model); + } + else + { + UpdateDividedVertexBuffer(model); } // update nodes and remove unused skin @@ -212,6 +151,89 @@ namespace UniVRM10 gltf.accessors = _accessors; return (gltf, _buffer.Bytes); + + } + + void UpdateSharedVertexBuffer(VrmLib.Model model) + { + var gltf = _data.GLTF; + + // update Mesh + foreach (var (gltfMesh, mesh) in Enumerable.Zip(gltf.meshes, model.MeshGroups, (l, r) => (l, r.Meshes[0]))) + { + NativeArray indices; + switch (mesh.IndexBuffer.Stride) + { + case 1: + { + // byte + var byte_indices = mesh.IndexBuffer.GetSpan(); + indices = _data.NativeArrayManager.Convert(byte_indices, (byte x) => (uint)x); + break; + } + + case 2: + { + // ushort + var ushort_indices = mesh.IndexBuffer.GetSpan(); + indices = _data.NativeArrayManager.Convert(ushort_indices, (ushort x) => (uint)x); + break; + } + + case 4: + { + // uint + indices = mesh.IndexBuffer.GetSpan(); + break; + } + + default: + throw new NotImplementedException(); + } + var position = AddAccessor(mesh.VertexBuffer.Positions); + var normal = AddAccessor(mesh.VertexBuffer.Normals); + var uv = AddAccessor(mesh.VertexBuffer.TexCoords); + var weights = AddAccessor(mesh.VertexBuffer.Weights); + var joints = AddAccessor(mesh.VertexBuffer.Joints); + var color = AddAccessor(mesh.VertexBuffer.Colors); + + var morphTargets = new MorphAccessor[] { }; + if (mesh.MorphTargets != null) + { + morphTargets = mesh.MorphTargets.Select(x => new MorphAccessor + { + Position = AddAccessor(x.VertexBuffer.Positions), + Normal = AddAccessor(x.VertexBuffer.Normals), + }).ToArray(); + } + + foreach (var (gltfPrim, submesh) in Enumerable.Zip(gltfMesh.primitives, mesh.Submeshes, (l, r) => (l, r))) + { + var subIndices = indices.GetSubArray(submesh.Offset, submesh.DrawCount); + gltfPrim.indices = AddAccessor(subIndices); + gltfPrim.attributes.POSITION = position.Value; + gltfPrim.attributes.NORMAL = normal.GetValueOrDefault(-1); // たぶん、ありえる + gltfPrim.attributes.TANGENT = -1; + gltfPrim.attributes.COLOR_0 = color.GetValueOrDefault(-1); + gltfPrim.attributes.TEXCOORD_0 = uv.GetValueOrDefault(-1); // ありえる? + gltfPrim.attributes.TEXCOORD_1 = -1; + gltfPrim.attributes.WEIGHTS_0 = weights.GetValueOrDefault(-1); + gltfPrim.attributes.JOINTS_0 = joints.GetValueOrDefault(-1); + foreach (var (gltfMorph, morph) in Enumerable.Zip(gltfPrim.targets, morphTargets, (l, r) => (l, r))) + { + gltfMorph.POSITION = morph.Position.GetValueOrDefault(-1); + gltfMorph.NORMAL = morph.Normal.GetValueOrDefault(-1); + gltfMorph.TANGENT = -1; + } + } + } + } + + void UpdateDividedVertexBuffer(VrmLib.Model model) + { + var gltf = _data.GLTF; + + throw new NotImplementedException(); } } } From dadf35c8020acd0a6bcc1a94bb5d35d5b50389d5 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 5 Apr 2022 13:13:09 +0900 Subject: [PATCH 2/3] implement UpdateDividedVertexBuffer --- Assets/VRM10/Runtime/Migration/MeshUpdater.cs | 91 ++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs index c6148e3c4..389d441e3 100644 --- a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs +++ b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs @@ -64,6 +64,12 @@ namespace UniVRM10 public int? Normal; }; + /// + /// bufferView, accessor を push することで bin を再構築する + /// (meshの右手左手変換結果の適用など) + /// + /// + /// public (glTF, ArraySegment) Update(VrmLib.Model model) { var gltf = _data.GLTF; @@ -75,6 +81,7 @@ namespace UniVRM10 image.bufferView = AddBuffer(bytes); } + // copy mesh if (model.MeshGroups.All(x => x.Meshes.Count == 1)) { UpdateSharedVertexBuffer(model); @@ -154,11 +161,16 @@ namespace UniVRM10 } + /// + /// model はひとつのノードに複数の mesh をぶら下げることができる(meshGroup) + /// gltf.meshes[i].primitives[j] <-> model.meshGroups[i].meshes[0].submeshes[j] + /// + /// void UpdateSharedVertexBuffer(VrmLib.Model model) { var gltf = _data.GLTF; - // update Mesh + // gltfMeshes[i] <=> MeshGroups[i].Meshes[0] ( MeshGroups[i].Meshes.Count == 1 ) foreach (var (gltfMesh, mesh) in Enumerable.Zip(gltf.meshes, model.MeshGroups, (l, r) => (l, r.Meshes[0]))) { NativeArray indices; @@ -207,6 +219,7 @@ namespace UniVRM10 }).ToArray(); } + // gltfPrim[j] <=> mesh.Submeshes[j] foreach (var (gltfPrim, submesh) in Enumerable.Zip(gltfMesh.primitives, mesh.Submeshes, (l, r) => (l, r))) { var subIndices = indices.GetSubArray(submesh.Offset, submesh.DrawCount); @@ -229,11 +242,85 @@ namespace UniVRM10 } } + /// + /// model はひとつのノードに複数の mesh をぶら下げることができる(meshGroup) + /// gltf.meshes[i].primitives[j] <-> model.meshGroups[i].meshes[j].submeshes[0] + /// + /// void UpdateDividedVertexBuffer(VrmLib.Model model) { var gltf = _data.GLTF; - throw new NotImplementedException(); + // gltfMesh[i] <=> meshGroups[i] + foreach (var (gltfMesh, meshGroup) in Enumerable.Zip(gltf.meshes, model.MeshGroups, (l, r) => (l, r))) + { + // gltfPrimitives[j] <=> meshGroup.Meshes[j] (meshGroup.Meshes[j].Submeshes.Count==1) + foreach (var (gltfPrim, mesh) in Enumerable.Zip(gltfMesh.primitives, meshGroup.Meshes, (l, r) => (l, r))) + { + NativeArray indices; + switch (mesh.IndexBuffer.Stride) + { + case 1: + { + // byte + var byte_indices = mesh.IndexBuffer.GetSpan(); + indices = _data.NativeArrayManager.Convert(byte_indices, (byte x) => (uint)x); + break; + } + + case 2: + { + // ushort + var ushort_indices = mesh.IndexBuffer.GetSpan(); + indices = _data.NativeArrayManager.Convert(ushort_indices, (ushort x) => (uint)x); + break; + } + + case 4: + { + // uint + indices = mesh.IndexBuffer.GetSpan(); + break; + } + + default: + throw new NotImplementedException(); + } + + var position = AddAccessor(mesh.VertexBuffer.Positions); + var normal = AddAccessor(mesh.VertexBuffer.Normals); + var uv = AddAccessor(mesh.VertexBuffer.TexCoords); + var weights = AddAccessor(mesh.VertexBuffer.Weights); + var joints = AddAccessor(mesh.VertexBuffer.Joints); + var color = AddAccessor(mesh.VertexBuffer.Colors); + + var morphTargets = new MorphAccessor[] { }; + if (mesh.MorphTargets != null) + { + morphTargets = mesh.MorphTargets.Select(x => new MorphAccessor + { + Position = AddAccessor(x.VertexBuffer.Positions), + Normal = AddAccessor(x.VertexBuffer.Normals), + }).ToArray(); + } + + gltfPrim.indices = AddAccessor(indices); + gltfPrim.attributes.POSITION = position.Value; + gltfPrim.attributes.NORMAL = normal.GetValueOrDefault(-1); // たぶん、ありえる + gltfPrim.attributes.TANGENT = -1; + gltfPrim.attributes.COLOR_0 = color.GetValueOrDefault(-1); + gltfPrim.attributes.TEXCOORD_0 = uv.GetValueOrDefault(-1); // ありえる? + gltfPrim.attributes.TEXCOORD_1 = -1; + gltfPrim.attributes.WEIGHTS_0 = weights.GetValueOrDefault(-1); + gltfPrim.attributes.JOINTS_0 = joints.GetValueOrDefault(-1); + foreach (var (gltfMorph, morph) in Enumerable.Zip(gltfPrim.targets, morphTargets, (l, r) => (l, r))) + { + gltfMorph.POSITION = morph.Position.GetValueOrDefault(-1); + gltfMorph.NORMAL = morph.Normal.GetValueOrDefault(-1); + gltfMorph.TANGENT = -1; + } + } + } } } } From 53c928227301e8ed0e321069fa4961fc79ddec66 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 5 Apr 2022 17:42:22 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=E5=94=AF=E4=B8=80=E3=81=AE=20public?= =?UTF-8?q?=E3=80=81=20MeshUpdater.Execute?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/VRM10/Runtime/Migration/MeshUpdater.cs | 27 ++++++++++++++----- .../VRM10/Runtime/Migration/MigrationVrm.cs | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs index 389d441e3..1ca4c8d10 100644 --- a/Assets/VRM10/Runtime/Migration/MeshUpdater.cs +++ b/Assets/VRM10/Runtime/Migration/MeshUpdater.cs @@ -10,7 +10,12 @@ namespace UniVRM10 { /// /// 座標系を変換した Model により、Mesh, Node, BindMatrices を更新する。 - /// buffer, bufferAccessor の更新もある。 + /// + /// * gltf.images の参照する bufferView + /// * gltf.meshes の参照する index, VERTEX, MorphTarget の accessor, bufferView + /// * gltf.nodes の参照する skin の inverseBindMatrices 向けの accessor, bufferView + /// + /// を詰め込みなすことで bin を再構築する /// class MeshUpdater { @@ -19,12 +24,23 @@ namespace UniVRM10 List _bufferViews = new List(); List _accessors = new List(); - public MeshUpdater(GltfData data) + MeshUpdater(GltfData data) { _data = data; _buffer = new ArrayByteBuffer(new byte[data.Bin.Length]); } + /// + /// data を model で更新する + /// + /// 更新前のオリジナル + /// 座標系の変換などの操作済み + /// + public static (glTF, ArraySegment) Execute(GltfData data, VrmLib.Model model) + { + return new MeshUpdater(data).Update(model); + } + int AddBuffer(NativeArray bytes) { var bufferView = _buffer.Extend(bytes); @@ -66,11 +82,10 @@ namespace UniVRM10 /// /// bufferView, accessor を push することで bin を再構築する - /// (meshの右手左手変換結果の適用など) /// - /// + /// meshの右手左手変換結果 /// - public (glTF, ArraySegment) Update(VrmLib.Model model) + (glTF, ArraySegment) Update(VrmLib.Model model) { var gltf = _data.GLTF; @@ -165,7 +180,6 @@ namespace UniVRM10 /// model はひとつのノードに複数の mesh をぶら下げることができる(meshGroup) /// gltf.meshes[i].primitives[j] <-> model.meshGroups[i].meshes[0].submeshes[j] /// - /// void UpdateSharedVertexBuffer(VrmLib.Model model) { var gltf = _data.GLTF; @@ -246,7 +260,6 @@ namespace UniVRM10 /// model はひとつのノードに複数の mesh をぶら下げることができる(meshGroup) /// gltf.meshes[i].primitives[j] <-> model.meshGroups[i].meshes[j].submeshes[0] /// - /// void UpdateDividedVertexBuffer(VrmLib.Model model) { var gltf = _data.GLTF; diff --git a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs index 6311ccb2f..68584cc5b 100644 --- a/Assets/VRM10/Runtime/Migration/MigrationVrm.cs +++ b/Assets/VRM10/Runtime/Migration/MigrationVrm.cs @@ -38,7 +38,7 @@ namespace UniVRM10 // Unity -> VRM1 model.ConvertCoordinate(VrmLib.Coordinates.Vrm1); - var (gltf, bin) = new MeshUpdater(data).Update(model); + var (gltf, bin) = MeshUpdater.Execute(data, model); gltf.extensions = null; return MigrateVrm(gltf, bin, data.Json.ParseAsJson()["extensions"]["VRM"]); }