diff --git a/Assets/VRM10/Runtime/IO/Model/ModelReader.cs b/Assets/VRM10/Runtime/IO/Model/ModelReader.cs index daa2f7742..d03c2d3be 100644 --- a/Assets/VRM10/Runtime/IO/Model/ModelReader.cs +++ b/Assets/VRM10/Runtime/IO/Model/ModelReader.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using System.Linq; using VrmLib; @@ -72,6 +73,55 @@ namespace UniVRM10 } } + // boneWeight の付与 + foreach (var meshGroup in model.MeshGroups) + { + if (meshGroup.Skin == null && meshGroup.Meshes.Any(mesh => mesh.MorphTargets.Count > 0)) + { + // Skinning が無くて MorphTarget が有る場合に実施する + var nodes = model.Nodes.Where(node => node.MeshGroup == meshGroup).ToArray(); + if (nodes.Length != 1) + { + // throw new NotImplementedException(); + // このメッシュが複数のノードから共有されている場合は、 + // 個別に Skin を作成する必要があり、 + // 異なる bindPoses が必要になるため mesh の複製が必要になる! + // 稀にあるかもしれない。 + continue; + } + var node = nodes[0]; + + // add bone weight + foreach (var mesh in meshGroup.Meshes) + { + // all (1, 0, 0, 0) + var weights = storage.Data.NativeArrayManager.CreateNativeArray(mesh.VertexBuffer.Count); + for (int i = 0; i < weights.Length; ++i) + { + weights[i] = new UnityEngine.Vector4(1, 0, 0, 0); + } + mesh.VertexBuffer.Add(VertexBuffer.WeightKey, new UniGLTF.BufferAccessor(storage.Data.NativeArrayManager, weights.Reinterpret(16), UniGLTF.AccessorValueType.FLOAT, UniGLTF.AccessorVectorType.VEC4, weights.Length)); + + // all zero + var joints = storage.Data.NativeArrayManager.CreateNativeArray(mesh.VertexBuffer.Count); + mesh.VertexBuffer.Add(VertexBuffer.JointKey, new UniGLTF.BufferAccessor(storage.Data.NativeArrayManager, joints.Reinterpret(8), UniGLTF.AccessorValueType.UNSIGNED_SHORT, UniGLTF.AccessorVectorType.VEC4, joints.Length)); + } + + // bind matrix + var bindMatrices = storage.Data.NativeArrayManager.CreateNativeArray(1); + bindMatrices[0] = node.Matrix.inverse; + + // skinning + meshGroup.Skin = new Skin + { + GltfIndex = -1, + Joints = new System.Collections.Generic.List { node }, + Root = node, + InverseMatrices = new UniGLTF.BufferAccessor(storage.Data.NativeArrayManager, bindMatrices.Reinterpret(64), UniGLTF.AccessorValueType.FLOAT, UniGLTF.AccessorVectorType.MAT4, bindMatrices.Length), + }; + } + } + return model; } diff --git a/Assets/VRM10/vrmlib/Runtime/MeshGroup.cs b/Assets/VRM10/vrmlib/Runtime/MeshGroup.cs index ddeef6e33..01f0079cd 100644 --- a/Assets/VRM10/vrmlib/Runtime/MeshGroup.cs +++ b/Assets/VRM10/vrmlib/Runtime/MeshGroup.cs @@ -39,5 +39,15 @@ namespace VrmLib { Name = name; } + + /// + /// VRM-0.X 様式の共有頂点バッファを持っているか? + /// + /// * vrm-1.0 の Export では共有頂点バッファを使用しない + /// * UniVRMの vrm-0.x => vrm-1.0 へのマイグレーション処理では、頂点バッファの様式変更はしない + /// + /// マイグレーションしたときのみtrueになる想定 + /// + public bool HasSharedBuffer => Meshes.Count == 1 && Meshes[0].Submeshes.Count > 1; } } diff --git a/Assets/VRM10/vrmlib/Runtime/Model.cs b/Assets/VRM10/vrmlib/Runtime/Model.cs index 8ed53b0f6..55e895a6d 100644 --- a/Assets/VRM10/vrmlib/Runtime/Model.cs +++ b/Assets/VRM10/vrmlib/Runtime/Model.cs @@ -43,10 +43,6 @@ namespace VrmLib public Node Root { get => m_root; - private set - { - - } } public void SetRoot(Node root) {