From 60e3d7a5d514a49aed31dc218976fad213aa76b4 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 8 Apr 2021 20:07:16 +0900 Subject: [PATCH 01/11] add UseSharingVertexBuffer option. remove unused code. --- .../Runtime/UniGLTF/IO/MeshExporter.cs | 70 +++---------------- 1 file changed, 10 insertions(+), 60 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs index 314f2a8a6..9070440f5 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs @@ -3,11 +3,20 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; + namespace UniGLTF { [Serializable] public struct MeshExportSettings { + // + // https://github.com/vrm-c/UniVRM/issues/800 + // + // VertexBuffer を共有バッファ方式にする + // UniVRM-0.71.0 までの挙動 + // + public bool UseSharingVertexBuffer; + // MorphTarget に Sparse Accessor を使う public bool UseSparseAccessorForMorphTarget; @@ -144,7 +153,7 @@ namespace UniGLTF } gltfMesh.primitives.Add(primitives); - + } return gltfMesh; } @@ -454,64 +463,5 @@ namespace UniGLTF yield return (unityMesh.Mesh, gltfMesh, blendShapeIndexMap); } } - - public static (glTFMesh gltfMesh, Dictionary blendShapeIndexMap) ExportMesh(glTF gltf, int bufferIndex, Mesh mesh, Renderer renderer, List exportedMaterials, MeshExportSettings meshExportSettings, IAxisInverter axisInverter) - { - var meshMaterials = default(Material[]); - if (renderer != null) - { - meshMaterials = renderer.sharedMaterials; - } - - var boneWeights = default(BoneWeight[]); - var jointIndexMap = default(int[]); - if (renderer is SkinnedMeshRenderer skin) - { - var bones = skin.bones; - var uniqueBones = bones.Distinct().ToArray(); - jointIndexMap = new int[bones.Length]; - for (var i = 0; i < bones.Length; i++) - { - jointIndexMap[i] = Array.IndexOf(uniqueBones, bones[i]); - } - - boneWeights = mesh.boneWeights; - } - - var gltfMesh = ExportPrimitives(gltf, bufferIndex, mesh, meshMaterials, boneWeights, jointIndexMap, exportedMaterials); - - var targetNames = new List(); - - var blendShapeIndexMap = new Dictionary(); - int exportBlendShapes = 0; - for (int j = 0; j < mesh.blendShapeCount; ++j) - { - var morphTarget = ExportMorphTarget(gltf, bufferIndex, - mesh, j, - meshExportSettings.UseSparseAccessorForMorphTarget, - meshExportSettings.ExportOnlyBlendShapePosition, axisInverter); - if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0) - { - continue; - } - - // maybe skip - var blendShapeName = mesh.GetBlendShapeName(j); - blendShapeIndexMap.Add(j, exportBlendShapes++); - targetNames.Add(blendShapeName); - - // - // all primitive has same blendShape - // - for (int k = 0; k < gltfMesh.primitives.Count; ++k) - { - gltfMesh.primitives[k].targets.Add(morphTarget); - } - } - - gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames); - - return (gltfMesh, blendShapeIndexMap); - } } } From 6aa145562322520abf19790a0180ad7dc8a8c0c5 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 9 Apr 2021 18:02:19 +0900 Subject: [PATCH 02/11] ExportMesh --- .../Runtime/UniGLTF/IO/MeshExporter.cs | 76 ++++++++++--------- .../Runtime/UniGLTF/IO/gltfExporter.cs | 17 ++--- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs index 9070440f5..53a8a6131 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs @@ -420,48 +420,56 @@ namespace UniGLTF }; } - public static IEnumerable<(Mesh, glTFMesh, Dictionary)> ExportMeshes(glTF gltf, int bufferIndex, - List unityMeshes, List unityMaterials, + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static (glTFMesh mesh, Dictionary blendShapeIndexMap) ExportMesh(glTF gltf, int bufferIndex, + MeshWithRenderer unityMesh, List unityMaterials, MeshExportSettings settings, IAxisInverter axisInverter) { - foreach (var unityMesh in unityMeshes) + var gltfMesh = ExportPrimitives(gltf, bufferIndex, + unityMesh, unityMaterials, axisInverter); + + var targetNames = new List(); + + var blendShapeIndexMap = new Dictionary(); + int exportBlendShapes = 0; + for (int j = 0; j < unityMesh.Mesh.blendShapeCount; ++j) { - var gltfMesh = ExportPrimitives(gltf, bufferIndex, - unityMesh, unityMaterials, axisInverter); - - var targetNames = new List(); - - var blendShapeIndexMap = new Dictionary(); - int exportBlendShapes = 0; - for (int j = 0; j < unityMesh.Mesh.blendShapeCount; ++j) + var morphTarget = ExportMorphTarget(gltf, bufferIndex, + unityMesh.Mesh, j, + settings.UseSparseAccessorForMorphTarget, + settings.ExportOnlyBlendShapePosition, axisInverter); + if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0) { - var morphTarget = ExportMorphTarget(gltf, bufferIndex, - unityMesh.Mesh, j, - settings.UseSparseAccessorForMorphTarget, - settings.ExportOnlyBlendShapePosition, axisInverter); - if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0) - { - continue; - } - - // maybe skip - var blendShapeName = unityMesh.Mesh.GetBlendShapeName(j); - blendShapeIndexMap.Add(j, exportBlendShapes++); - targetNames.Add(blendShapeName); - - // - // all primitive has same blendShape - // - for (int k = 0; k < gltfMesh.primitives.Count; ++k) - { - gltfMesh.primitives[k].targets.Add(morphTarget); - } + continue; } - gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames); + // maybe skip + var blendShapeName = unityMesh.Mesh.GetBlendShapeName(j); + blendShapeIndexMap.Add(j, exportBlendShapes++); + targetNames.Add(blendShapeName); - yield return (unityMesh.Mesh, gltfMesh, blendShapeIndexMap); + // + // all primitive has same blendShape + // + for (int k = 0; k < gltfMesh.primitives.Count; ++k) + { + gltfMesh.primitives[k].targets.Add(morphTarget); + } } + + gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames); + + return (gltfMesh, blendShapeIndexMap); } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index 3f54a66c5..8408dd028 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -17,11 +17,8 @@ namespace UniGLTF protected set; } - public List Meshes - { - get; - private set; - } + readonly List m_meshes = new List(); + public List Meshes => m_meshes; /// /// Mesh毎に、元のBlendShapeIndex => ExportされたBlendShapeIndex の対応を記録する @@ -195,17 +192,17 @@ namespace UniGLTF var unityMeshes = MeshWithRenderer.FromNodes(Nodes).Where(x => x.Mesh.vertices.Any()).ToList(); MeshBlendShapeIndexMap = new Dictionary>(); - foreach (var (mesh, gltfMesh, blendShapeIndexMap) in MeshExporter.ExportMeshes( - glTF, bufferIndex, unityMeshes, Materials, meshExportSettings, m_axisInverter)) + foreach (var unityMesh in unityMeshes) { + var (gltfMesh, blendShapeIndexMap) = MeshExporter.ExportMesh(glTF, bufferIndex, unityMesh, Materials, meshExportSettings, m_axisInverter); glTF.meshes.Add(gltfMesh); - if (!MeshBlendShapeIndexMap.ContainsKey(mesh)) + Meshes.Add(unityMesh.Mesh); + if (!MeshBlendShapeIndexMap.ContainsKey(unityMesh.Mesh)) { // 同じmeshが複数回現れた - MeshBlendShapeIndexMap.Add(mesh, blendShapeIndexMap); + MeshBlendShapeIndexMap.Add(unityMesh.Mesh, blendShapeIndexMap); } } - Meshes = unityMeshes.Select(x => x.Mesh).ToList(); #endregion #region Nodes and Skins From 42837bfff67510d3b9a8d0c0fe80a73be4dfb92c Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 9 Apr 2021 19:00:14 +0900 Subject: [PATCH 03/11] MeshExportSettings.ExportTangents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #if を削減 --- .../Runtime/UniGLTF/IO/MeshExporter.cs | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs index 53a8a6131..94f967231 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs @@ -23,17 +23,24 @@ namespace UniGLTF // MorphTarget を Position だけにする(normal とか捨てる) public bool ExportOnlyBlendShapePosition; + // tangent を出力する + public bool ExportTangents; + public static MeshExportSettings Default => new MeshExportSettings { UseSparseAccessorForMorphTarget = false, ExportOnlyBlendShapePosition = false, + UseSharingVertexBuffer = true, +#if GLTF_EXPORT_TANGENTS + ExportTangents = true, +#endif }; } public static class MeshExporter { static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex, Mesh mesh, Material[] meshMaterials, BoneWeight[] boneWeights, int[] jointIndexMap, - List exportedMaterials) + List exportedMaterials, MeshExportSettings settings) { var positions = mesh.vertices.Select(y => y.ReverseZ()).ToArray(); var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER); @@ -41,9 +48,13 @@ namespace UniGLTF gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.normalized.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); -#if GLTF_EXPORT_TANGENTS - var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); -#endif + + int? tangentAccessorIndex = default; + if (settings.ExportTangents) + { + tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); + } + var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); var uvAccessorIndex1 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv2.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); @@ -81,12 +92,12 @@ namespace UniGLTF { attributes.NORMAL = normalAccessorIndex; } -#if GLTF_EXPORT_TANGENTS - if (tangentAccessorIndex != -1) + + if (tangentAccessorIndex.HasValue) { - attributes.TANGENT = tangentAccessorIndex; + attributes.TANGENT = tangentAccessorIndex.Value; } -#endif + if (uvAccessorIndex0 != -1) { attributes.TEXCOORD_0 = uvAccessorIndex0; @@ -160,7 +171,7 @@ namespace UniGLTF static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex, MeshWithRenderer unityMesh, List unityMaterials, - IAxisInverter axisInverter) + IAxisInverter axisInverter, MeshExportSettings settings) { var mesh = unityMesh.Mesh; var materials = unityMesh.Renderer.sharedMaterials; @@ -170,9 +181,13 @@ namespace UniGLTF gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => axisInverter.InvertVector3(y.normalized)).ToArray(), glBufferTarget.ARRAY_BUFFER); -#if GLTF_EXPORT_TANGENTS - var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(axisInverter.InvertVector4()).ToArray(), glBufferTarget.ARRAY_BUFFER); -#endif + + int? tangentAccessorIndex = default; + if (settings.ExportTangents) + { + tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(axisInverter.InvertVector4).ToArray(), glBufferTarget.ARRAY_BUFFER); + } + var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); var uvAccessorIndex1 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv2.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); @@ -205,12 +220,12 @@ namespace UniGLTF { attributes.NORMAL = normalAccessorIndex; } -#if GLTF_EXPORT_TANGENTS - if (tangentAccessorIndex != -1) + + if (tangentAccessorIndex.HasValue) { - attributes.TANGENT = tangentAccessorIndex; + attributes.TANGENT = tangentAccessorIndex.Value; } -#endif + if (uvAccessorIndex0 != -1) { attributes.TEXCOORD_0 = uvAccessorIndex0; @@ -435,8 +450,15 @@ namespace UniGLTF MeshWithRenderer unityMesh, List unityMaterials, MeshExportSettings settings, IAxisInverter axisInverter) { - var gltfMesh = ExportPrimitives(gltf, bufferIndex, - unityMesh, unityMaterials, axisInverter); + glTFMesh gltfMesh = default; + if (settings.UseSharingVertexBuffer) + { + gltfMesh = ExportPrimitives(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); + } + else + { + throw new NotImplementedException(); + } var targetNames = new List(); From 2bd547627c1f41ef2b714e4fb09e9225dec1d5fb Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 9 Apr 2021 19:05:24 +0900 Subject: [PATCH 04/11] rename ExportSharedVertexBuffer. remove unused function --- .../Runtime/UniGLTF/IO/MeshExporter.cs | 147 ++---------------- 1 file changed, 15 insertions(+), 132 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs index 94f967231..e216e3112 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs @@ -39,137 +39,20 @@ namespace UniGLTF public static class MeshExporter { - static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex, Mesh mesh, Material[] meshMaterials, BoneWeight[] boneWeights, int[] jointIndexMap, - List exportedMaterials, MeshExportSettings settings) - { - var positions = mesh.vertices.Select(y => y.ReverseZ()).ToArray(); - var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER); - gltf.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray(); - gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); - - var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.normalized.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); - - int? tangentAccessorIndex = default; - if (settings.ExportTangents) - { - tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); - } - - var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); - var uvAccessorIndex1 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv2.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER); - - var colorAccessorIndex = -1; - - var vColorState = MeshExportInfo.DetectVertexColor(mesh, meshMaterials); - if (vColorState == MeshExportInfo.VertexColorState.ExistsAndIsUsed // VColor使っている - || vColorState == MeshExportInfo.VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする) - ) - { - // UniUnlit で Multiply 設定になっている - colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.ARRAY_BUFFER); - } - - var weightAccessorIndex = -1; - var jointsAccessorIndex = -1; - - if (boneWeights != null && jointIndexMap != null) - { - weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneWeights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), glBufferTarget.ARRAY_BUFFER); - jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneWeights.Select(y => - new UShort4( - (ushort)jointIndexMap[y.boneIndex0], - (ushort)jointIndexMap[y.boneIndex1], - (ushort)jointIndexMap[y.boneIndex2], - (ushort)jointIndexMap[y.boneIndex3]) - ).ToArray(), glBufferTarget.ARRAY_BUFFER); - } - - var attributes = new glTFAttributes - { - POSITION = positionAccessorIndex, - }; - if (normalAccessorIndex != -1) - { - attributes.NORMAL = normalAccessorIndex; - } - - if (tangentAccessorIndex.HasValue) - { - attributes.TANGENT = tangentAccessorIndex.Value; - } - - if (uvAccessorIndex0 != -1) - { - attributes.TEXCOORD_0 = uvAccessorIndex0; - } - if (uvAccessorIndex1 != -1) - { - attributes.TEXCOORD_1 = uvAccessorIndex1; - } - if (colorAccessorIndex != -1) - { - attributes.COLOR_0 = colorAccessorIndex; - } - if (weightAccessorIndex != -1) - { - attributes.WEIGHTS_0 = weightAccessorIndex; - } - if (jointsAccessorIndex != -1) - { - attributes.JOINTS_0 = jointsAccessorIndex; - } - - var gltfMesh = new glTFMesh(mesh.name); - var indices = new List(); - for (var j = 0; j < mesh.subMeshCount; ++j) - { - indices.Clear(); - - var triangles = mesh.GetIndices(j); - if (triangles.Length == 0) - { - // https://github.com/vrm-c/UniVRM/issues/664 - continue; - } - - for (var i = 0; i < triangles.Length; i += 3) - { - var i0 = triangles[i]; - var i1 = triangles[i + 1]; - var i2 = triangles[i + 2]; - - // flip triangle - indices.Add((uint)i2); - indices.Add((uint)i1); - indices.Add((uint)i0); - } - - var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER); - if (indicesAccessorIndex < 0) - { - // https://github.com/vrm-c/UniVRM/issues/664 - throw new Exception(); - } - - var primitives = new glTFPrimitives - { - attributes = attributes, - indices = indicesAccessorIndex, - mode = 4, // triangles ? - }; - - if (meshMaterials != null) - { - primitives.material = exportedMaterials.IndexOf(meshMaterials[j]); - } - - gltfMesh.primitives.Add(primitives); - - } - return gltfMesh; - } - - static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex, + /// + /// primitive 間で vertex を共有する形で Export する。 + /// + /// UniVRM-0.71.0 までの挙動 + /// + /// /// + /// + /// + /// + /// + /// + /// + /// + static glTFMesh ExportSharedVertexBuffer(glTF gltf, int bufferIndex, MeshWithRenderer unityMesh, List unityMaterials, IAxisInverter axisInverter, MeshExportSettings settings) { @@ -453,7 +336,7 @@ namespace UniGLTF glTFMesh gltfMesh = default; if (settings.UseSharingVertexBuffer) { - gltfMesh = ExportPrimitives(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); + gltfMesh = ExportSharedVertexBuffer(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); } else { From 74bbf88d532278d65c6a3599215bc5e92059a5b1 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 9 Apr 2021 20:03:04 +0900 Subject: [PATCH 05/11] ExportDividedVertexBuffer --- .../Runtime/UniGLTF/IO/MeshExporter.cs | 215 +++++++++++++++--- .../Runtime/UniGLTF/IO/MeshWithRenderer.cs | 6 + 2 files changed, 188 insertions(+), 33 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs index e216e3112..433225582 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs @@ -30,15 +30,164 @@ namespace UniGLTF { UseSparseAccessorForMorphTarget = false, ExportOnlyBlendShapePosition = false, - UseSharingVertexBuffer = true, #if GLTF_EXPORT_TANGENTS ExportTangents = true, #endif }; } + class MorphTarget + { + readonly string m_name; + readonly List m_positions; + readonly List m_normals; + + public MorphTarget(string name, int reserve) + { + m_name = name; + m_positions = new List(reserve); + m_normals = new List(reserve); + } + } + + + class VertexBuffer + { + readonly IAxisInverter m_inverter; + readonly int m_indexCount; + readonly List m_positions; + readonly List m_normals; + readonly List m_uv; + + readonly Func m_getJointIndex; + readonly List m_joints; + readonly List m_weights; + + readonly List m_morphs = new List(); + + + public VertexBuffer(IAxisInverter inverter, int reserve, Func getJointIndex) + { + m_inverter = inverter; + m_indexCount = reserve; + m_positions = new List(reserve); + m_normals = new List(reserve); + m_uv = new List(); + + m_getJointIndex = getJointIndex; + if (m_getJointIndex != null) + { + m_joints = new List(reserve); + m_weights = new List(reserve); + } + } + + public void Push(Vector3 position, Vector3 normal, Vector2 uv) + { + m_positions.Add(m_inverter.InvertVector3(position)); + m_normals.Add(m_inverter.InvertVector3(normal)); + m_uv.Add(uv.ReverseUV()); + } + + public void Push(BoneWeight boneWeight) + { + m_joints.Add(new UShort4((ushort)boneWeight.boneIndex0, (ushort)boneWeight.boneIndex1, (ushort)boneWeight.boneIndex2, (ushort)boneWeight.boneIndex3)); + m_weights.Add(new Vector4(boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3)); + } + + public glTFPrimitives ToGltf(glTF gltf, int bufferIndex, int materialIndex) + { + var indices = new List(m_indexCount); + // flip triangles + for (int i = 0; i < m_indexCount; i += 3) + { + // 2, 1, 0, 5, 4, 3, ... + indices.Add((uint)(i + 2)); + indices.Add((uint)(i + 1)); + indices.Add((uint)(i + 0)); + } + + var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER); + var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_positions.ToArray(), glBufferTarget.ARRAY_BUFFER); + var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_normals.ToArray(), glBufferTarget.ARRAY_BUFFER); + var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_uv.ToArray(), glBufferTarget.ARRAY_BUFFER); + var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_joints.ToArray(), glBufferTarget.ARRAY_BUFFER); + var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER); + + var primitive = new glTFPrimitives + { + indices = indicesAccessorIndex, + attributes = new glTFAttributes + { + POSITION = positionAccessorIndex, + NORMAL = normalAccessorIndex, + TEXCOORD_0 = uvAccessorIndex0, + JOINTS_0 = jointsAccessorIndex, + WEIGHTS_0 = weightAccessorIndex, + }, + material = materialIndex, + mode = 4, + targets = null, + }; + return primitive; + } + } + public static class MeshExporter { + static glTFMesh ExportDividedVertexBuffer(glTF gltf, int bufferIndex, + MeshWithRenderer unityMesh, List unityMaterials, + IAxisInverter axisInverter, MeshExportSettings settings) + { + var mesh = unityMesh.Mesh; + var gltfMesh = new glTFMesh(mesh.name); + + if (settings.ExportTangents) + { + // support しない + throw new NotImplementedException(); + } + + var positions = mesh.vertices; + var normals = mesh.normals; + var uv = mesh.uv; + var boneWeights = mesh.boneWeights; + + Func getJointIndex = null; + if (boneWeights != null && boneWeights.Length == positions.Length) + { + getJointIndex = unityMesh.GetJointIndex; + } + + for (int i = 0; i < mesh.subMeshCount; ++i) + { + var indices = mesh.GetIndices(i); + + // index の順に attributes を蓄える + var buffer = new VertexBuffer(axisInverter, indices.Length, getJointIndex); + foreach (var j in indices) + { + buffer.Push(positions[j], normals[j], uv[j]); + if (getJointIndex != null) + { + buffer.Push(boneWeights[j]); + } + } + + var material = unityMesh.Renderer.sharedMaterials[i]; + var materialIndex = -1; + if (material != null) + { + materialIndex = unityMaterials.IndexOf(material); + } + gltfMesh.primitives.Add(buffer.ToGltf(gltf, bufferIndex, materialIndex)); + } + + // morphTarget + + return gltfMesh; + } + /// /// primitive 間で vertex を共有する形で Export する。 /// @@ -334,46 +483,46 @@ namespace UniGLTF MeshExportSettings settings, IAxisInverter axisInverter) { glTFMesh gltfMesh = default; + var blendShapeIndexMap = new Dictionary(); if (settings.UseSharingVertexBuffer) { gltfMesh = ExportSharedVertexBuffer(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); + + var targetNames = new List(); + + int exportBlendShapes = 0; + for (int j = 0; j < unityMesh.Mesh.blendShapeCount; ++j) + { + var morphTarget = ExportMorphTarget(gltf, bufferIndex, + unityMesh.Mesh, j, + settings.UseSparseAccessorForMorphTarget, + settings.ExportOnlyBlendShapePosition, axisInverter); + if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0) + { + continue; + } + + // maybe skip + var blendShapeName = unityMesh.Mesh.GetBlendShapeName(j); + blendShapeIndexMap.Add(j, exportBlendShapes++); + targetNames.Add(blendShapeName); + + // + // all primitive has same blendShape + // + for (int k = 0; k < gltfMesh.primitives.Count; ++k) + { + gltfMesh.primitives[k].targets.Add(morphTarget); + } + } + + gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames); } else { - throw new NotImplementedException(); + gltfMesh = ExportDividedVertexBuffer(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); } - var targetNames = new List(); - - var blendShapeIndexMap = new Dictionary(); - int exportBlendShapes = 0; - for (int j = 0; j < unityMesh.Mesh.blendShapeCount; ++j) - { - var morphTarget = ExportMorphTarget(gltf, bufferIndex, - unityMesh.Mesh, j, - settings.UseSparseAccessorForMorphTarget, - settings.ExportOnlyBlendShapePosition, axisInverter); - if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0) - { - continue; - } - - // maybe skip - var blendShapeName = unityMesh.Mesh.GetBlendShapeName(j); - blendShapeIndexMap.Add(j, exportBlendShapes++); - targetNames.Add(blendShapeName); - - // - // all primitive has same blendShape - // - for (int k = 0; k < gltfMesh.primitives.Count; ++k) - { - gltfMesh.primitives[k].targets.Add(morphTarget); - } - } - - gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames); - return (gltfMesh, blendShapeIndexMap); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs index 9c67c42cb..1ee16c1e8 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshWithRenderer.cs @@ -37,6 +37,12 @@ namespace UniGLTF } } + /// + /// glTF は skinning の boneList の重複を許可しない + /// (unity は ok) + /// + /// + /// public int GetJointIndex(int index) { if (index < 0) From 9a479b2337f38b7cd015a53bdaef6dc889dc53e0 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 9 Apr 2021 20:52:44 +0900 Subject: [PATCH 06/11] MeshExporterDivided --- .../Runtime/UniGLTF/IO/MeshExportSettings.cs | 36 ++++ .../UniGLTF/IO/MeshExportSettings.cs.meta | 11 + .../Runtime/UniGLTF/IO/MeshExporter.cs | 181 +--------------- .../Runtime/UniGLTF/IO/MeshExporterDivided.cs | 196 ++++++++++++++++++ .../UniGLTF/IO/MeshExporterDivided.cs.meta | 11 + 5 files changed, 255 insertions(+), 180 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs.meta create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs new file mode 100644 index 000000000..155ee72ef --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs @@ -0,0 +1,36 @@ +using System; + +namespace UniGLTF +{ + [Serializable] + public struct MeshExportSettings + { + // + // https://github.com/vrm-c/UniVRM/issues/800 + // + // VertexBuffer を共有バッファ方式にする + // UniVRM-0.71.0 までの挙動 + // + public bool UseSharingVertexBuffer; + + // MorphTarget に Sparse Accessor を使う + public bool UseSparseAccessorForMorphTarget; + + // MorphTarget を Position だけにする(normal とか捨てる) + public bool ExportOnlyBlendShapePosition; + + // tangent を出力する + public bool ExportTangents; + + public static MeshExportSettings Default => new MeshExportSettings + { + UseSparseAccessorForMorphTarget = false, + ExportOnlyBlendShapePosition = false, + // WIP + UseSharingVertexBuffer = true, +#if GLTF_EXPORT_TANGENTS + ExportTangents = true, +#endif + }; + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs.meta new file mode 100644 index 000000000..78ce31750 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26b97430e1698e94e9a27ab322f3eee5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs index 433225582..9b0a72c03 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs @@ -6,187 +6,8 @@ using UnityEngine; namespace UniGLTF { - [Serializable] - public struct MeshExportSettings - { - // - // https://github.com/vrm-c/UniVRM/issues/800 - // - // VertexBuffer を共有バッファ方式にする - // UniVRM-0.71.0 までの挙動 - // - public bool UseSharingVertexBuffer; - - // MorphTarget に Sparse Accessor を使う - public bool UseSparseAccessorForMorphTarget; - - // MorphTarget を Position だけにする(normal とか捨てる) - public bool ExportOnlyBlendShapePosition; - - // tangent を出力する - public bool ExportTangents; - - public static MeshExportSettings Default => new MeshExportSettings - { - UseSparseAccessorForMorphTarget = false, - ExportOnlyBlendShapePosition = false, -#if GLTF_EXPORT_TANGENTS - ExportTangents = true, -#endif - }; - } - - class MorphTarget - { - readonly string m_name; - readonly List m_positions; - readonly List m_normals; - - public MorphTarget(string name, int reserve) - { - m_name = name; - m_positions = new List(reserve); - m_normals = new List(reserve); - } - } - - - class VertexBuffer - { - readonly IAxisInverter m_inverter; - readonly int m_indexCount; - readonly List m_positions; - readonly List m_normals; - readonly List m_uv; - - readonly Func m_getJointIndex; - readonly List m_joints; - readonly List m_weights; - - readonly List m_morphs = new List(); - - - public VertexBuffer(IAxisInverter inverter, int reserve, Func getJointIndex) - { - m_inverter = inverter; - m_indexCount = reserve; - m_positions = new List(reserve); - m_normals = new List(reserve); - m_uv = new List(); - - m_getJointIndex = getJointIndex; - if (m_getJointIndex != null) - { - m_joints = new List(reserve); - m_weights = new List(reserve); - } - } - - public void Push(Vector3 position, Vector3 normal, Vector2 uv) - { - m_positions.Add(m_inverter.InvertVector3(position)); - m_normals.Add(m_inverter.InvertVector3(normal)); - m_uv.Add(uv.ReverseUV()); - } - - public void Push(BoneWeight boneWeight) - { - m_joints.Add(new UShort4((ushort)boneWeight.boneIndex0, (ushort)boneWeight.boneIndex1, (ushort)boneWeight.boneIndex2, (ushort)boneWeight.boneIndex3)); - m_weights.Add(new Vector4(boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3)); - } - - public glTFPrimitives ToGltf(glTF gltf, int bufferIndex, int materialIndex) - { - var indices = new List(m_indexCount); - // flip triangles - for (int i = 0; i < m_indexCount; i += 3) - { - // 2, 1, 0, 5, 4, 3, ... - indices.Add((uint)(i + 2)); - indices.Add((uint)(i + 1)); - indices.Add((uint)(i + 0)); - } - - var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER); - var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_positions.ToArray(), glBufferTarget.ARRAY_BUFFER); - var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_normals.ToArray(), glBufferTarget.ARRAY_BUFFER); - var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_uv.ToArray(), glBufferTarget.ARRAY_BUFFER); - var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_joints.ToArray(), glBufferTarget.ARRAY_BUFFER); - var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER); - - var primitive = new glTFPrimitives - { - indices = indicesAccessorIndex, - attributes = new glTFAttributes - { - POSITION = positionAccessorIndex, - NORMAL = normalAccessorIndex, - TEXCOORD_0 = uvAccessorIndex0, - JOINTS_0 = jointsAccessorIndex, - WEIGHTS_0 = weightAccessorIndex, - }, - material = materialIndex, - mode = 4, - targets = null, - }; - return primitive; - } - } - public static class MeshExporter { - static glTFMesh ExportDividedVertexBuffer(glTF gltf, int bufferIndex, - MeshWithRenderer unityMesh, List unityMaterials, - IAxisInverter axisInverter, MeshExportSettings settings) - { - var mesh = unityMesh.Mesh; - var gltfMesh = new glTFMesh(mesh.name); - - if (settings.ExportTangents) - { - // support しない - throw new NotImplementedException(); - } - - var positions = mesh.vertices; - var normals = mesh.normals; - var uv = mesh.uv; - var boneWeights = mesh.boneWeights; - - Func getJointIndex = null; - if (boneWeights != null && boneWeights.Length == positions.Length) - { - getJointIndex = unityMesh.GetJointIndex; - } - - for (int i = 0; i < mesh.subMeshCount; ++i) - { - var indices = mesh.GetIndices(i); - - // index の順に attributes を蓄える - var buffer = new VertexBuffer(axisInverter, indices.Length, getJointIndex); - foreach (var j in indices) - { - buffer.Push(positions[j], normals[j], uv[j]); - if (getJointIndex != null) - { - buffer.Push(boneWeights[j]); - } - } - - var material = unityMesh.Renderer.sharedMaterials[i]; - var materialIndex = -1; - if (material != null) - { - materialIndex = unityMaterials.IndexOf(material); - } - gltfMesh.primitives.Add(buffer.ToGltf(gltf, bufferIndex, materialIndex)); - } - - // morphTarget - - return gltfMesh; - } /// /// primitive 間で vertex を共有する形で Export する。 @@ -520,7 +341,7 @@ namespace UniGLTF } else { - gltfMesh = ExportDividedVertexBuffer(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); + gltfMesh = MeshExporterDivided.Export(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); } return (gltfMesh, blendShapeIndexMap); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs new file mode 100644 index 000000000..34366ae88 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace UniGLTF +{ + public static class MeshExporterDivided + { + class BlendShapeBuffer + { + readonly List m_positions; + readonly List m_normals; + + public BlendShapeBuffer(int reserve) + { + m_positions = new List(reserve); + m_normals = new List(reserve); + } + + public void Push(Vector3 position, Vector3 normal) + { + m_positions.Add(position); + m_normals.Add(normal); + } + + public gltfMorphTarget ToGltf(glTF gltf, int bufferIndex, bool useNormal) + { + var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_positions.ToArray(), glBufferTarget.ARRAY_BUFFER); + var normalAccessorIndex = -1; + if (useNormal) + { + normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_normals.ToArray(), glBufferTarget.ARRAY_BUFFER); + } + return new gltfMorphTarget + { + POSITION = positionAccessorIndex, + NORMAL = normalAccessorIndex, + }; + } + } + + class VertexBuffer + { + readonly int m_indexCount; + readonly List m_positions; + readonly List m_normals; + readonly List m_uv; + + readonly Func m_getJointIndex; + readonly List m_joints; + readonly List m_weights; + + public VertexBuffer(int reserve, Func getJointIndex) + { + m_indexCount = reserve; + m_positions = new List(reserve); + m_normals = new List(reserve); + m_uv = new List(); + + m_getJointIndex = getJointIndex; + if (m_getJointIndex != null) + { + m_joints = new List(reserve); + m_weights = new List(reserve); + } + } + + public void Push(Vector3 position, Vector3 normal, Vector2 uv) + { + m_positions.Add(position); + m_normals.Add(normal); + m_uv.Add(uv); + } + + public void Push(BoneWeight boneWeight) + { + m_joints.Add(new UShort4((ushort)boneWeight.boneIndex0, (ushort)boneWeight.boneIndex1, (ushort)boneWeight.boneIndex2, (ushort)boneWeight.boneIndex3)); + m_weights.Add(new Vector4(boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3)); + } + + public glTFPrimitives ToGltf(glTF gltf, int bufferIndex, int materialIndex) + { + var indices = new List(m_indexCount); + // flip triangles + for (int i = 0; i < m_indexCount; i += 3) + { + // 2, 1, 0, 5, 4, 3, ... + indices.Add((uint)(i + 2)); + indices.Add((uint)(i + 1)); + indices.Add((uint)(i + 0)); + } + + var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER); + var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_positions.ToArray(), glBufferTarget.ARRAY_BUFFER); + var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_normals.ToArray(), glBufferTarget.ARRAY_BUFFER); + var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_uv.ToArray(), glBufferTarget.ARRAY_BUFFER); + var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_joints.ToArray(), glBufferTarget.ARRAY_BUFFER); + var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER); + + var primitive = new glTFPrimitives + { + indices = indicesAccessorIndex, + attributes = new glTFAttributes + { + POSITION = positionAccessorIndex, + NORMAL = normalAccessorIndex, + TEXCOORD_0 = uvAccessorIndex0, + JOINTS_0 = jointsAccessorIndex, + WEIGHTS_0 = weightAccessorIndex, + }, + material = materialIndex, + mode = 4, + }; + return primitive; + } + } + + public static glTFMesh Export(glTF gltf, int bufferIndex, + MeshWithRenderer unityMesh, List unityMaterials, + IAxisInverter axisInverter, MeshExportSettings settings) + { + var mesh = unityMesh.Mesh; + var gltfMesh = new glTFMesh(mesh.name); + + if (settings.ExportTangents) + { + // support しない + throw new NotImplementedException(); + } + + var positions = mesh.vertices; + var normals = mesh.normals; + var uv = mesh.uv; + var boneWeights = mesh.boneWeights; + + Func getJointIndex = null; + if (boneWeights != null && boneWeights.Length == positions.Length) + { + getJointIndex = unityMesh.GetJointIndex; + } + + Vector3[] blendShapePositions = new Vector3[mesh.vertexCount]; + Vector3[] blendShapeNormals = new Vector3[mesh.vertexCount]; + + for (int i = 0; i < mesh.subMeshCount; ++i) + { + var indices = mesh.GetIndices(i); + + // mesh + // index の順に attributes を蓄える + var buffer = new VertexBuffer(indices.Length, getJointIndex); + foreach (var k in indices) + { + buffer.Push(axisInverter.InvertVector3(positions[k]), axisInverter.InvertVector3(normals[k]), uv[k].ReverseUV()); + if (getJointIndex != null) + { + buffer.Push(boneWeights[k]); + } + } + + var material = unityMesh.Renderer.sharedMaterials[i]; + var materialIndex = -1; + if (material != null) + { + materialIndex = unityMaterials.IndexOf(material); + } + var gltfPrimitive = buffer.ToGltf(gltf, bufferIndex, materialIndex); + + // blendShape + for (int j = 0; j < mesh.blendShapeCount; ++j) + { + var blendShape = new BlendShapeBuffer(indices.Length); + + // index の順に attributes を蓄える + mesh.GetBlendShapeFrameVertices(j, 0, blendShapePositions, blendShapeNormals, null); + foreach (var k in indices) + { + blendShape.Push( + axisInverter.InvertVector3(blendShapePositions[k]), + axisInverter.InvertVector3(blendShapeNormals[k])); + } + + gltfPrimitive.targets.Add(blendShape.ToGltf(gltf, bufferIndex, !settings.ExportOnlyBlendShapePosition)); + } + + gltfMesh.primitives.Add(gltfPrimitive); + } + + var targetNames = Enumerable.Range(0, mesh.blendShapeCount).Select(x => mesh.GetBlendShapeName(x)).ToArray(); + gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames); + + return gltfMesh; + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs.meta new file mode 100644 index 000000000..6a31e5d50 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92bc82be5ead84a429346379590f6d7d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From ceb884d82ca14343fe8f885c115d1abe0b4f3a29 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 12 Apr 2021 13:59:29 +0900 Subject: [PATCH 07/11] SharedVertexBufferTest, DividedVertexBufferTest --- Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs | 157 +++++++++++++++++++++- 1 file changed, 153 insertions(+), 4 deletions(-) diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs index 840fd67f7..8742a1f29 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using NUnit.Framework; +using UnityEngine; namespace UniGLTF { @@ -11,8 +12,8 @@ namespace UniGLTF public void AccessorTest() { byte[] bytes = default; - using(var ms = new MemoryStream()) - using(var w = new BinaryWriter(ms)) + using (var ms = new MemoryStream()) + using (var w = new BinaryWriter(ms)) { w.Write(1.0f); w.Write(2.0f); @@ -28,7 +29,7 @@ namespace UniGLTF var gltf = new glTF { - buffers=new List + buffers = new List { new glTFBuffer { @@ -39,7 +40,7 @@ namespace UniGLTF new glTFBufferView{ buffer=0, byteLength=32, - byteOffset=0, + byteOffset=0, } }, accessors = new List @@ -59,5 +60,153 @@ namespace UniGLTF Assert.AreEqual((1.0f, 2.0f, 3.0f, 4.0f), getter(0)); Assert.AreEqual((5.0f, 6.0f, 7.0f, 8.0f), getter(1)); } + + /// + /// 0 1 2 + /// +-+-+ + /// |A|B| + /// +-+-+ + /// 5 4 3 + /// + /// 6 vertices + /// 4 triangles + /// 2 materials + /// + /// + static (GameObject, Mesh) CreateMesh(Material[] materials) + { + var unityMesh = new Mesh(); + unityMesh.vertices = new Vector3[] + { + new Vector3(0, 1, 0), + new Vector3(1, 1, 0), + new Vector3(2, 1, 0), + new Vector3(2, 0, 0), + new Vector3(1, 0, 0), + new Vector3(0, 0, 0), + }; + unityMesh.uv = new Vector2[] + { + new Vector2(0, 0), + new Vector2(1, 0), + new Vector2(2, 0), + new Vector2(2, 1), + new Vector2(1, 1), + new Vector2(0, 1), + }; + + unityMesh.subMeshCount = 2; + unityMesh.SetTriangles(new int[]{ + 0, 1, 5, + 5, 1, 4, + }, 0); + unityMesh.SetTriangles(new int[]{ + 1, 2, 4, + 4, 2, 3, + }, 1); + + unityMesh.RecalculateNormals(); + unityMesh.RecalculateTangents(); + + var go = new GameObject(); + go.AddComponent().sharedMaterials = materials; + go.AddComponent().sharedMesh = unityMesh; + + return (go, unityMesh); + } + + [Test] + public void SharedVertexBufferTest() + { + var glTF = new glTF(); + var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); + var bufferIndex = glTF.AddBuffer(bytesBuffer); + + var Materials = new List{ + new Material(Shader.Find("Standard")), // A + new Material(Shader.Find("Standard")), // B + }; + + var (go, unityMesh) = CreateMesh(Materials.ToArray()); + var meshExportSettings = new MeshExportSettings + { + UseSharingVertexBuffer = true + }; + var axisInverter = Axises.X.Create(); + + var (gltfMesh, blendShapeIndexMap) = MeshExporter.ExportMesh(glTF, bufferIndex, new MeshWithRenderer(go.transform), Materials, meshExportSettings, axisInverter); + + { + var indices = glTF.GetIndices(gltfMesh.primitives[0].indices); + Assert.AreEqual(0, indices[0]); + Assert.AreEqual(1, indices[1]); + Assert.AreEqual(5, indices[2]); + Assert.AreEqual(5, indices[3]); + Assert.AreEqual(1, indices[4]); + Assert.AreEqual(4, indices[5]); + } + { + var indices = glTF.GetIndices(gltfMesh.primitives[1].indices); + Assert.AreEqual(1, indices[0]); + Assert.AreEqual(2, indices[1]); + Assert.AreEqual(4, indices[2]); + Assert.AreEqual(4, indices[3]); + Assert.AreEqual(2, indices[4]); + Assert.AreEqual(3, indices[5]); + } + + var positions = glTF.GetArrayFromAccessor(gltfMesh.primitives[0].attributes.POSITION); + Assert.AreEqual(6, positions.Length); + } + + [Test] + public void DividedVertexBufferTest() + { + var glTF = new glTF(); + var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); + var bufferIndex = glTF.AddBuffer(bytesBuffer); + + var Materials = new List{ + new Material(Shader.Find("Standard")), // A + new Material(Shader.Find("Standard")), // B + }; + + var (go, unityMesh) = CreateMesh(Materials.ToArray()); + var meshExportSettings = new MeshExportSettings + { + UseSharingVertexBuffer = false + }; + var axisInverter = Axises.X.Create(); + + var (gltfMesh, blendShapeIndexMap) = MeshExporter.ExportMesh(glTF, bufferIndex, new MeshWithRenderer(go.transform), Materials, meshExportSettings, axisInverter); + + { + var indices = glTF.GetIndices(gltfMesh.primitives[0].indices); + Assert.AreEqual(0, indices[0]); + Assert.AreEqual(1, indices[1]); + Assert.AreEqual(3, indices[2]); + Assert.AreEqual(3, indices[3]); + Assert.AreEqual(1, indices[4]); + Assert.AreEqual(2, indices[5]); + } + { + var positions = glTF.GetArrayFromAccessor(gltfMesh.primitives[0].attributes.POSITION); + Assert.AreEqual(4, positions.Length); + } + + { + var indices = glTF.GetIndices(gltfMesh.primitives[1].indices); + Assert.AreEqual(1, indices[0]); + Assert.AreEqual(2, indices[1]); + Assert.AreEqual(4, indices[2]); + Assert.AreEqual(4, indices[3]); + Assert.AreEqual(2, indices[4]); + Assert.AreEqual(3, indices[5]); + } + { + var positions = glTF.GetArrayFromAccessor(gltfMesh.primitives[1].attributes.POSITION); + Assert.AreEqual(4, positions.Length); + } + } } } From ea6ddd75809d64bf347a836f69bad6747d2015da Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 12 Apr 2021 13:59:45 +0900 Subject: [PATCH 08/11] null check --- .../Runtime/UniGLTF/IO/MeshExporterDivided.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs index 34366ae88..d54f9186e 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs @@ -95,8 +95,17 @@ namespace UniGLTF var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_positions.ToArray(), glBufferTarget.ARRAY_BUFFER); var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_normals.ToArray(), glBufferTarget.ARRAY_BUFFER); var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_uv.ToArray(), glBufferTarget.ARRAY_BUFFER); - var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_joints.ToArray(), glBufferTarget.ARRAY_BUFFER); - var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER); + + int? jointsAccessorIndex = default; + if (m_joints != null) + { + jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_joints.ToArray(), glBufferTarget.ARRAY_BUFFER); + } + int? weightAccessorIndex = default; + if (m_weights != null) + { + weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER); + } var primitive = new glTFPrimitives { @@ -106,8 +115,8 @@ namespace UniGLTF POSITION = positionAccessorIndex, NORMAL = normalAccessorIndex, TEXCOORD_0 = uvAccessorIndex0, - JOINTS_0 = jointsAccessorIndex, - WEIGHTS_0 = weightAccessorIndex, + JOINTS_0 = jointsAccessorIndex.GetValueOrDefault(-1), + WEIGHTS_0 = weightAccessorIndex.GetValueOrDefault(-1), }, material = materialIndex, mode = 4, From 6b9ab0db3795d2c03b7bbadb0f9b13769ba52eed Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 12 Apr 2021 14:45:17 +0900 Subject: [PATCH 09/11] =?UTF-8?q?=E9=87=8D=E8=A4=87=E9=A0=82=E7=82=B9?= =?UTF-8?q?=E3=81=8C=E5=A2=97=E3=81=88=E3=81=AA=E3=81=84=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/UniGLTF/IO/MeshExporterDivided.cs | 50 ++++++++++++------- Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs | 12 ++--- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs index d54f9186e..3b876f87a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporterDivided.cs @@ -42,7 +42,6 @@ namespace UniGLTF class VertexBuffer { - readonly int m_indexCount; readonly List m_positions; readonly List m_normals; readonly List m_uv; @@ -53,7 +52,6 @@ namespace UniGLTF public VertexBuffer(int reserve, Func getJointIndex) { - m_indexCount = reserve; m_positions = new List(reserve); m_normals = new List(reserve); m_uv = new List(); @@ -79,18 +77,8 @@ namespace UniGLTF m_weights.Add(new Vector4(boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3)); } - public glTFPrimitives ToGltf(glTF gltf, int bufferIndex, int materialIndex) + public glTFPrimitives ToGltf(glTF gltf, int bufferIndex, int materialIndex, IReadOnlyList indices) { - var indices = new List(m_indexCount); - // flip triangles - for (int i = 0; i < m_indexCount; i += 3) - { - // 2, 1, 0, 5, 4, 3, ... - indices.Add((uint)(i + 2)); - indices.Add((uint)(i + 1)); - indices.Add((uint)(i + 0)); - } - var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER); var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_positions.ToArray(), glBufferTarget.ARRAY_BUFFER); var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_normals.ToArray(), glBufferTarget.ARRAY_BUFFER); @@ -152,6 +140,7 @@ namespace UniGLTF Vector3[] blendShapePositions = new Vector3[mesh.vertexCount]; Vector3[] blendShapeNormals = new Vector3[mesh.vertexCount]; + var usedIndices = new List(); for (int i = 0; i < mesh.subMeshCount; ++i) { var indices = mesh.GetIndices(i); @@ -159,12 +148,26 @@ namespace UniGLTF // mesh // index の順に attributes を蓄える var buffer = new VertexBuffer(indices.Length, getJointIndex); - foreach (var k in indices) + // foreach (var k in indices) + // { + // buffer.Push(axisInverter.InvertVector3(positions[k]), axisInverter.InvertVector3(normals[k]), uv[k].ReverseUV()); + // if (getJointIndex != null) + // { + // buffer.Push(boneWeights[k]); + // } + // } + // indices から参照される頂点だけを蓄える + usedIndices.Clear(); + for (int k = 0; k < positions.Length; ++k) { - buffer.Push(axisInverter.InvertVector3(positions[k]), axisInverter.InvertVector3(normals[k]), uv[k].ReverseUV()); - if (getJointIndex != null) + if (indices.Contains(k)) { - buffer.Push(boneWeights[k]); + usedIndices.Add(k); + buffer.Push(axisInverter.InvertVector3(positions[k]), axisInverter.InvertVector3(normals[k]), uv[k].ReverseUV()); + if (getJointIndex != null) + { + buffer.Push(boneWeights[k]); + } } } @@ -174,7 +177,16 @@ namespace UniGLTF { materialIndex = unityMaterials.IndexOf(material); } - var gltfPrimitive = buffer.ToGltf(gltf, bufferIndex, materialIndex); + var indexMap = usedIndices.Select((used, index) => (used, index)).ToDictionary(x => x.used, x => (uint)x.index); + + var flipped = new List(); + for (int j = 0; j < indices.Length; j += 3) + { + flipped.Add((uint)indexMap[indices[j + 2]]); + flipped.Add((uint)indexMap[indices[j + 1]]); + flipped.Add((uint)indexMap[indices[j]]); + } + var gltfPrimitive = buffer.ToGltf(gltf, bufferIndex, materialIndex, flipped); // blendShape for (int j = 0; j < mesh.blendShapeCount; ++j) @@ -183,7 +195,7 @@ namespace UniGLTF // index の順に attributes を蓄える mesh.GetBlendShapeFrameVertices(j, 0, blendShapePositions, blendShapeNormals, null); - foreach (var k in indices) + foreach (var k in usedIndices) { blendShape.Push( axisInverter.InvertVector3(blendShapePositions[k]), diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs index 8742a1f29..f8e30b21e 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs @@ -196,12 +196,12 @@ namespace UniGLTF { var indices = glTF.GetIndices(gltfMesh.primitives[1].indices); - Assert.AreEqual(1, indices[0]); - Assert.AreEqual(2, indices[1]); - Assert.AreEqual(4, indices[2]); - Assert.AreEqual(4, indices[3]); - Assert.AreEqual(2, indices[4]); - Assert.AreEqual(3, indices[5]); + Assert.AreEqual(0, indices[0]); + Assert.AreEqual(1, indices[1]); + Assert.AreEqual(3, indices[2]); + Assert.AreEqual(3, indices[3]); + Assert.AreEqual(1, indices[4]); + Assert.AreEqual(2, indices[5]); } { var positions = glTF.GetArrayFromAccessor(gltfMesh.primitives[1].attributes.POSITION); From 608caf1e7410c6f4a283c21a52de631ef3e1ef27 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 12 Apr 2021 15:13:07 +0900 Subject: [PATCH 10/11] DivideVertexBuffer option --- .../Editor/UniGLTF/GltfExportSettings.cs | 2 + .../Editor/UniGLTF/GltfExportWindow.cs | 3 +- .../Runtime/UniGLTF/IO/MeshExportSettings.cs | 5 +- .../Runtime/UniGLTF/IO/MeshExporter.cs | 10 ++-- Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs | 4 +- Assets/VRM/Editor/Format/VRMExportSettings.cs | 12 ++++- .../Editor/Format/VRMExportSettingsEditor.cs | 54 +++++-------------- 7 files changed, 36 insertions(+), 54 deletions(-) diff --git a/Assets/UniGLTF/Editor/UniGLTF/GltfExportSettings.cs b/Assets/UniGLTF/Editor/UniGLTF/GltfExportSettings.cs index 843e47a5e..54101e083 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/GltfExportSettings.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/GltfExportSettings.cs @@ -14,5 +14,7 @@ namespace UniGLTF public bool Sparse; public bool DropNormal; + + public bool DivideVertexBuffer; } } diff --git a/Assets/UniGLTF/Editor/UniGLTF/GltfExportWindow.cs b/Assets/UniGLTF/Editor/UniGLTF/GltfExportWindow.cs index 4842878dc..d8e22e5c4 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/GltfExportWindow.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/GltfExportWindow.cs @@ -36,7 +36,7 @@ namespace UniGLTF using (var exporter = new gltfExporter(gltf, inverseAxis)) { exporter.Prepare(go); - exporter.Export(settings, AssetTextureUtil.IsTextureEditorAsset ); + exporter.Export(settings, AssetTextureUtil.IsTextureEditorAsset); } @@ -244,6 +244,7 @@ namespace UniGLTF { ExportOnlyBlendShapePosition = settings.DropNormal, UseSparseAccessorForMorphTarget = settings.Sparse, + DivideVertexBuffer = settings.DivideVertexBuffer, }, settings.InverseAxis); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs index 155ee72ef..4af2f6290 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExportSettings.cs @@ -11,7 +11,7 @@ namespace UniGLTF // VertexBuffer を共有バッファ方式にする // UniVRM-0.71.0 までの挙動 // - public bool UseSharingVertexBuffer; + public bool DivideVertexBuffer; // MorphTarget に Sparse Accessor を使う public bool UseSparseAccessorForMorphTarget; @@ -26,8 +26,7 @@ namespace UniGLTF { UseSparseAccessorForMorphTarget = false, ExportOnlyBlendShapePosition = false, - // WIP - UseSharingVertexBuffer = true, + DivideVertexBuffer = false, #if GLTF_EXPORT_TANGENTS ExportTangents = true, #endif diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs index 9b0a72c03..7b0cd7cfb 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshExporter.cs @@ -305,7 +305,11 @@ namespace UniGLTF { glTFMesh gltfMesh = default; var blendShapeIndexMap = new Dictionary(); - if (settings.UseSharingVertexBuffer) + if (settings.DivideVertexBuffer) + { + gltfMesh = MeshExporterDivided.Export(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); + } + else { gltfMesh = ExportSharedVertexBuffer(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); @@ -339,10 +343,6 @@ namespace UniGLTF gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames); } - else - { - gltfMesh = MeshExporterDivided.Export(gltf, bufferIndex, unityMesh, unityMaterials, axisInverter, settings); - } return (gltfMesh, blendShapeIndexMap); } diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs index f8e30b21e..9f4e6a112 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs @@ -130,7 +130,7 @@ namespace UniGLTF var (go, unityMesh) = CreateMesh(Materials.ToArray()); var meshExportSettings = new MeshExportSettings { - UseSharingVertexBuffer = true + DivideVertexBuffer = false }; var axisInverter = Axises.X.Create(); @@ -174,7 +174,7 @@ namespace UniGLTF var (go, unityMesh) = CreateMesh(Materials.ToArray()); var meshExportSettings = new MeshExportSettings { - UseSharingVertexBuffer = false + DivideVertexBuffer = true }; var axisInverter = Axises.X.Create(); diff --git a/Assets/VRM/Editor/Format/VRMExportSettings.cs b/Assets/VRM/Editor/Format/VRMExportSettings.cs index 2e0f2e89e..66cba297d 100644 --- a/Assets/VRM/Editor/Format/VRMExportSettings.cs +++ b/Assets/VRM/Editor/Format/VRMExportSettings.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using UniGLTF; using UnityEngine; namespace VRM @@ -7,6 +7,7 @@ namespace VRM [Serializable] public class VRMExportSettings : ScriptableObject { + /// /// エクスポート時に強制的にT-Pose化する /// @@ -43,10 +44,17 @@ namespace VRM [Tooltip("Remove blendShapeClip that preset is Unknown")] public bool ReduceBlendshapeClip = false; - public UniGLTF.MeshExportSettings MeshExportSettings => new UniGLTF.MeshExportSettings + /// + /// Export時に頂点バッファをsubmeshで分割する。GLTF互換性 + /// + [Tooltip("Divide vertex buffer. For more gltf compatibility")] + public bool DivideVertexBuffer = false; + + public MeshExportSettings MeshExportSettings => new MeshExportSettings { UseSparseAccessorForMorphTarget = UseSparseAccessor, ExportOnlyBlendShapePosition = OnlyBlendshapePosition, + DivideVertexBuffer = DivideVertexBuffer, }; public GameObject Root { get; set; } diff --git a/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs b/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs index 6600a4a4b..3e883b92a 100644 --- a/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs +++ b/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs @@ -36,47 +36,12 @@ namespace VRM } } - /// - /// エクスポート時にヒエラルキーの正規化を実施する - /// - [Tooltip("Require only first time")] - public bool PoseFreeze = true; - - /// - /// エクスポート時に新しいJsonSerializerを使う - /// - [Tooltip("Use new JSON serializer")] - public bool UseExperimentalExporter = false; - - /// - /// BlendShapeのシリアライズにSparseAccessorを使う - /// - [Tooltip("Use sparse accessor for blendshape. This may reduce vrm size")] - public bool UseSparseAccessor = false; - - /// - /// BlendShapeのPositionのみをエクスポートする - /// - [Tooltip("UniVRM-0.54 or later can load it. Otherwise fail to load")] - public bool OnlyBlendshapePosition = false; - - /// - /// エクスポート時にBlendShapeClipから参照されないBlendShapeを削除する - /// - [Tooltip("Remove blendshape that is not used from BlendShapeClip")] - public bool ReduceBlendshape = false; - - /// - /// skip if BlendShapeClip.Preset == Unknown - /// - [Tooltip("Remove blendShapeClip that preset is Unknown")] - public bool ReduceBlendshapeClip = false; - CheckBoxProp m_poseFreeze; CheckBoxProp m_useSparseAccessor; CheckBoxProp m_onlyBlendShapePosition; CheckBoxProp m_reduceBlendShape; CheckBoxProp m_reduceBlendShapeClip; + CheckBoxProp m_divideVertexBuffer; static string Msg(Options key) { @@ -128,15 +93,20 @@ namespace VRM [LangMsg(Languages.ja, "T-Pose にする")] [LangMsg(Languages.en, "Make T-Pose")] DO_TPOSE, + + [LangMsg(Languages.ja, "頂点バッファをsubmeshで分割する。GLTF互換性のため。UniVRM-0.72 からロードできる。")] + [LangMsg(Languages.en, "Divide vertex buffer by submesh。For more gltf compatibility。UniVRM-0.72 or later can load.")] + DIVIDE_VERTEX_BUFFER, } private void OnEnable() { - m_poseFreeze = new CheckBoxProp(serializedObject.FindProperty(nameof(PoseFreeze)), Options.NORMALIZE); - m_useSparseAccessor = new CheckBoxProp(serializedObject.FindProperty(nameof(UseSparseAccessor)), Options.BLENDSHAPE_USE_SPARSE); - m_onlyBlendShapePosition = new CheckBoxProp(serializedObject.FindProperty(nameof(OnlyBlendshapePosition)), Options.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT); - m_reduceBlendShape = new CheckBoxProp(serializedObject.FindProperty(nameof(ReduceBlendshape)), Options.BLENDSHAPE_ONLY_CLIP_USE); - m_reduceBlendShapeClip = new CheckBoxProp(serializedObject.FindProperty(nameof(ReduceBlendshapeClip)), Options.BLENDSHAPE_EXCLUDE_UNKNOWN); + m_poseFreeze = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.PoseFreeze)), Options.NORMALIZE); + m_useSparseAccessor = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.UseSparseAccessor)), Options.BLENDSHAPE_USE_SPARSE); + m_onlyBlendShapePosition = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.OnlyBlendshapePosition)), Options.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT); + m_reduceBlendShape = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshape)), Options.BLENDSHAPE_ONLY_CLIP_USE); + m_reduceBlendShapeClip = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshapeClip)), Options.BLENDSHAPE_EXCLUDE_UNKNOWN); + m_divideVertexBuffer = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.DivideVertexBuffer)), Options.DIVIDE_VERTEX_BUFFER); } public override void OnInspectorGUI() @@ -173,6 +143,8 @@ namespace VRM m_onlyBlendShapePosition.Draw(); m_reduceBlendShape.Draw(); m_reduceBlendShapeClip.Draw(); + m_divideVertexBuffer.Draw(); + serializedObject.ApplyModifiedProperties(); } } From bdd962225f92f790da3dfce5aff8140985cb0939 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Mon, 12 Apr 2021 18:14:09 +0900 Subject: [PATCH 11/11] =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index 8408dd028..0fa288dc3 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -17,8 +17,7 @@ namespace UniGLTF protected set; } - readonly List m_meshes = new List(); - public List Meshes => m_meshes; + public List Meshes { get; private set; } = new List(); /// /// Mesh毎に、元のBlendShapeIndex => ExportされたBlendShapeIndex の対応を記録する