diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs index da5b5c4a4..b8f88a748 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using UnityEngine; using UnityEngine.Profiling; using UnityEngine.Rendering; @@ -10,6 +11,7 @@ namespace UniGLTF internal class MeshContext { private readonly List _vertices = new List(); + private readonly List _skinnedMeshVertices = new List(); private readonly List _indices = new List(); private readonly List _subMeshes = new List(); private readonly List _materialIndices = new List(); @@ -28,9 +30,30 @@ namespace UniGLTF /// public void UploadMeshVertices(Mesh mesh) { - mesh.SetVertexBufferParams(_vertices.Count, MeshVertex.GetVertexAttributeDescriptor()); + var vertexAttributeDescriptor = MeshVertex.GetVertexAttributeDescriptor(); + + // Weight情報等は存在しないパターンがあり、かつこの存在の有無によって内部的に条件分岐が走ってしまうため、 + // Streamを分けて必要に応じてアップロードする + if (_skinnedMeshVertices.Count > 0) + { + vertexAttributeDescriptor = vertexAttributeDescriptor.Concat(SkinnedMeshVertex + .GetVertexAttributeDescriptor().Select( + attr => + { + attr.stream = 1; + return attr; + })).ToArray(); + } + + mesh.SetVertexBufferParams(_vertices.Count, vertexAttributeDescriptor); + mesh.SetVertexBufferData(_vertices, 0, 0, _vertices.Count); + if (_skinnedMeshVertices.Count > 0) + { + mesh.SetVertexBufferData(_skinnedMeshVertices, 0, 0, _skinnedMeshVertices.Count, 1); + } } + /// /// インデックス情報をMeshに対して送る /// @@ -149,7 +172,11 @@ namespace UniGLTF normal, texCoord0, texCoord1, - color, + color + )); + if (jointsGetter != null) + { + _skinnedMeshVertices.Add(new SkinnedMeshVertex( joints.x, joints.y, joints.z, @@ -157,8 +184,8 @@ namespace UniGLTF weights.x, weights.y, weights.z, - weights.w - )); + weights.w)); + } } // blendshape @@ -213,7 +240,8 @@ namespace UniGLTF else { var indexOffset = _indices.Count; - _indices.AddRange(TriangleUtil.FlipTriangle(Enumerable.Range(0, _vertices.Count)).Select(index => index + vertexOffset)); + _indices.AddRange(TriangleUtil.FlipTriangle(Enumerable.Range(0, _vertices.Count)) + .Select(index => index + vertexOffset)); _subMeshes.Add(new SubMeshDescriptor(indexOffset, _vertices.Count)); } @@ -284,16 +312,20 @@ namespace UniGLTF normal, texCoord0, texCoord1, - color, - joints.x, - joints.y, - joints.z, - joints.w, - weights.x, - weights.y, - weights.z, - weights.w + color )); + if (jointsGetter != null) + { + _skinnedMeshVertices.Add(new SkinnedMeshVertex( + joints.x, + joints.y, + joints.z, + joints.w, + weights.x, + weights.y, + weights.z, + weights.w)); + } } // blendshape @@ -403,6 +435,7 @@ namespace UniGLTF Truncate(blendShape.Normals, maxIndex); Truncate(blendShape.Tangents, maxIndex); } + Profiler.EndSample(); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs index 4bb6d1d35..0b282ad91 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.Rendering; @@ -6,8 +6,8 @@ using UnityEngine.Rendering; namespace UniGLTF { /// - /// インターリーブされたメッシュの頂点情報を表す構造体 - /// そのままGPUにアップロードされる + /// インターリーブされたメッシュの頂点情報のうち、基本的なものを表す構造体 + /// 必要に応じてSkinnedMeshVertexとあわせてGPUにアップロードされる /// [Serializable, StructLayout(LayoutKind.Sequential)] internal readonly struct MeshVertex @@ -17,53 +17,27 @@ namespace UniGLTF private readonly Color _color; private readonly Vector2 _texCoord0; private readonly Vector2 _texCoord1; - private readonly float _boneWeight0; - private readonly float _boneWeight1; - private readonly float _boneWeight2; - private readonly float _boneWeight3; - private readonly ushort _boneIndex0; - private readonly ushort _boneIndex1; - private readonly ushort _boneIndex2; - private readonly ushort _boneIndex3; public MeshVertex( Vector3 position, Vector3 normal, Vector2 texCoord0, Vector2 texCoord1, - Color color, - ushort boneIndex0, - ushort boneIndex1, - ushort boneIndex2, - ushort boneIndex3, - float boneWeight0, - float boneWeight1, - float boneWeight2, - float boneWeight3) + Color color) { _position = position; _normal = normal; _texCoord0 = texCoord0; _texCoord1 = texCoord1; _color = color; - _boneIndex0 = boneIndex0; - _boneIndex1 = boneIndex1; - _boneIndex2 = boneIndex2; - _boneIndex3 = boneIndex3; - _boneWeight0 = boneWeight0; - _boneWeight1 = boneWeight1; - _boneWeight2 = boneWeight2; - _boneWeight3 = boneWeight3; } public static VertexAttributeDescriptor[] GetVertexAttributeDescriptor() => new[] { new VertexAttributeDescriptor(VertexAttribute.Position), - new VertexAttributeDescriptor(VertexAttribute.Normal), - new VertexAttributeDescriptor(VertexAttribute.Color, dimension: 4), - new VertexAttributeDescriptor(VertexAttribute.TexCoord0, dimension: 2), - new VertexAttributeDescriptor(VertexAttribute.TexCoord1, dimension: 2), - new VertexAttributeDescriptor(VertexAttribute.BlendWeight, dimension: 4), - new VertexAttributeDescriptor(VertexAttribute.BlendIndices, VertexAttributeFormat.UInt16, 4), - }; + new VertexAttributeDescriptor(VertexAttribute.Normal), + new VertexAttributeDescriptor(VertexAttribute.Color, dimension: 4), + new VertexAttributeDescriptor(VertexAttribute.TexCoord0, dimension: 2), + new VertexAttributeDescriptor(VertexAttribute.TexCoord1, dimension: 2) + }; } } \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs.meta index 8190c9154..15c3bc058 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs.meta +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex.cs.meta @@ -1,3 +1,11 @@ -fileFormatVersion: 2 -guid: 0d540d8e32d54e7089a72156edb7ad80 -timeCreated: 1636526648 \ No newline at end of file +fileFormatVersion: 2 +guid: 3f4d5804612c4bddb05ece3a4b29bbdf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/SkinnedMeshVertex.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/SkinnedMeshVertex.cs new file mode 100644 index 000000000..5850aff65 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/SkinnedMeshVertex.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.InteropServices; +using UnityEngine.Rendering; + +namespace UniGLTF +{ + /// + /// インターリーブされたメッシュの頂点情報のうち、SkinnedMeshに関連した情報を表す構造体 + /// そのままGPUにアップロードされる + /// + [Serializable, StructLayout(LayoutKind.Sequential)] + internal readonly struct SkinnedMeshVertex + { + private readonly float _boneWeight0; + private readonly float _boneWeight1; + private readonly float _boneWeight2; + private readonly float _boneWeight3; + private readonly ushort _boneIndex0; + private readonly ushort _boneIndex1; + private readonly ushort _boneIndex2; + private readonly ushort _boneIndex3; + + public SkinnedMeshVertex( + ushort boneIndex0, + ushort boneIndex1, + ushort boneIndex2, + ushort boneIndex3, + float boneWeight0, + float boneWeight1, + float boneWeight2, + float boneWeight3) + { + _boneIndex0 = boneIndex0; + _boneIndex1 = boneIndex1; + _boneIndex2 = boneIndex2; + _boneIndex3 = boneIndex3; + _boneWeight0 = boneWeight0; + _boneWeight1 = boneWeight1; + _boneWeight2 = boneWeight2; + _boneWeight3 = boneWeight3; + } + + public static VertexAttributeDescriptor[] GetVertexAttributeDescriptor() => new[] { + new VertexAttributeDescriptor(VertexAttribute.BlendWeight, dimension: 4), + new VertexAttributeDescriptor(VertexAttribute.BlendIndices, VertexAttributeFormat.UInt16, 4), + }; + } +} \ No newline at end of file