From 94b0928d5acbcef78950a226077e07521495bd6e Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 7 Jun 2022 16:20:14 +0900 Subject: [PATCH] =?UTF-8?q?MeshImporter=20=E3=82=92=E6=95=B4=E7=90=86?= =?UTF-8?q?=E3=80=82=E6=A9=9F=E8=83=BD=E3=82=92=20ImporterContext=20?= =?UTF-8?q?=E3=81=A8=20MeshContext=20=E3=81=AB=E5=A7=94=E8=AD=B2=E3=81=97?= =?UTF-8?q?=E3=81=A6=E6=B6=88=E6=BB=85=E3=81=95=E3=81=9B=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runtime/UniGLTF/IO/ImporterContext.cs | 47 ++++- .../Runtime/UniGLTF/IO/MeshIO/MeshContext.cs | 114 ++++++++++++ .../Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs | 165 ------------------ .../UniGLTF/IO/MeshIO/MeshImporter.cs.meta | 11 -- 4 files changed, 158 insertions(+), 179 deletions(-) delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index cb281bf96..0efb50d7a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -163,6 +163,47 @@ namespace UniGLTF await awaitCaller.NextFrame(); } + private static bool HasSharedVertexBuffer(glTFMesh gltfMesh) + { + glTFAttributes lastAttributes = null; + var sharedAttributes = true; + foreach (var prim in gltfMesh.primitives) + { + if (lastAttributes != null && !prim.attributes.Equals(lastAttributes)) + { + sharedAttributes = false; + break; + } + + lastAttributes = prim.attributes; + } + + return sharedAttributes; + } + + private static MeshContext ReadMesh(GltfData data, int meshIndex, IAxisInverter inverter) + { + Profiler.BeginSample("ReadMesh"); + var gltfMesh = data.GLTF.meshes[meshIndex]; + + var meshContext = new MeshContext(gltfMesh.name, meshIndex); + if (HasSharedVertexBuffer(gltfMesh)) + { + meshContext.ImportMeshSharingVertexBuffer(data, gltfMesh, inverter); + } + else + { + meshContext.ImportMeshIndependentVertexBuffer(data, gltfMesh, inverter); + } + + meshContext.RenameBlendShape(gltfMesh); + + meshContext.DropUnusedVertices(); + + Profiler.EndSample(); + return meshContext; + } + protected virtual async Task LoadGeometryAsync(IAwaitCaller awaitCaller, Func MeasureTime) { var inverter = InvertAxis.Create(); @@ -174,7 +215,7 @@ namespace UniGLTF var index = i; using (MeasureTime("ReadMesh")) { - var meshContext = await awaitCaller.Run(() => MeshImporter.ReadMesh(Data, index, inverter)); + var meshContext = await awaitCaller.Run(() => ReadMesh(Data, index, inverter)); var meshWithMaterials = await BuildMeshAsync(awaitCaller, MeasureTime, meshContext, index); Meshes.Add(meshWithMaterials); } @@ -289,11 +330,11 @@ namespace UniGLTF return Task.FromResult(null); } - async Task BuildMeshAsync(IAwaitCaller awaitCaller, Func MeasureTime, MeshContext x, int i) + async Task BuildMeshAsync(IAwaitCaller awaitCaller, Func MeasureTime, MeshContext meshContext, int i) { using (MeasureTime("BuildMesh")) { - var meshWithMaterials = await MeshImporter.BuildMeshAsync(awaitCaller, MaterialFactory.GetMaterial, x); + var meshWithMaterials = await meshContext.BuildMeshAsync(awaitCaller, MaterialFactory.GetMaterial); var mesh = meshWithMaterials.Mesh; // mesh name diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs index 48e54d0a9..b4fb885e3 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshContext.cs @@ -1,14 +1,18 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using UnityEngine; using UnityEngine.Profiling; using UnityEngine.Rendering; +using VRMShaders; namespace UniGLTF { internal class MeshContext { + private const float FrameWeight = 100.0f; + private readonly List _vertices = new List(); private readonly List _skinnedMeshVertices = new List(); private readonly List _indices = new List(); @@ -537,5 +541,115 @@ namespace UniGLTF Profiler.EndSample(); } + + private (Mesh, bool) BuildMesh() + { + this.AddDefaultMaterial(); + + //Debug.Log(prims.ToJson()); + var mesh = new Mesh + { + name = this.Name + }; + + this.UploadMeshVertices(mesh); + this.UploadMeshIndices(mesh); + + // NOTE: mesh.vertices では自動的に行われていたが、SetVertexBuffer では行われないため、明示的に呼び出す. + mesh.RecalculateBounds(); + + if (!this.HasNormal) + { + mesh.RecalculateNormals(); + } + + return (mesh, true); + } + + private static async Task BuildBlendShapeAsync(IAwaitCaller awaitCaller, Mesh mesh, BlendShape blendShape, + Vector3[] emptyVertices) + { + Vector3[] positions = null; + Vector3[] normals = null; + await awaitCaller.Run(() => + { + positions = blendShape.Positions.ToArray(); + if (blendShape.Normals != null) + { + normals = blendShape.Normals.ToArray(); + } + }); + + Profiler.BeginSample("MeshImporter.BuildBlendShapeAsync"); + if (blendShape.Positions.Count > 0) + { + if (blendShape.Positions.Count == mesh.vertexCount) + { + mesh.AddBlendShapeFrame(blendShape.Name, FrameWeight, + blendShape.Positions.ToArray(), + normals.Length == mesh.vertexCount && normals.Length == positions.Length ? normals : null, + null + ); + } + else + { + Debug.LogWarningFormat( + "May be partial primitive has blendShape. Require separate mesh or extend blend shape, but not implemented: {0}", + blendShape.Name); + } + } + else + { + // Debug.LogFormat("empty blendshape: {0}.{1}", mesh.name, blendShape.Name); + // add empty blend shape for keep blend shape index + mesh.AddBlendShapeFrame(blendShape.Name, FrameWeight, + emptyVertices, + null, + null + ); + } + + Profiler.EndSample(); + } + + public async Task BuildMeshAsync( + IAwaitCaller awaitCaller, + Func ctx) + { + Profiler.BeginSample("MeshImporter.BuildMesh"); + var (mesh, recalculateTangents) = this.BuildMesh(); + Profiler.EndSample(); + + if (recalculateTangents) + { + await awaitCaller.NextFrame(); + mesh.RecalculateTangents(); + await awaitCaller.NextFrame(); + } + + // 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい + var result = new MeshWithMaterials + { + Mesh = mesh, + Materials = this.MaterialIndices.Select(ctx).ToArray() + }; + + await awaitCaller.NextFrame(); + if (this.BlendShapes.Count > 0) + { + var emptyVertices = new Vector3[mesh.vertexCount]; + foreach (var blendShape in this.BlendShapes) + { + await BuildBlendShapeAsync(awaitCaller, mesh, blendShape, emptyVertices); + } + } + + Profiler.BeginSample("Mesh.UploadMeshData"); + mesh.UploadMeshData(false); + Profiler.EndSample(); + + return result; + } + } } \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs deleted file mode 100644 index aa726b807..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using UnityEngine; -using UnityEngine.Profiling; -using VRMShaders; - -namespace UniGLTF -{ - public static class MeshImporter - { - private const float FrameWeight = 100.0f; - - private static bool HasSharedVertexBuffer(glTFMesh gltfMesh) - { - glTFAttributes lastAttributes = null; - var sharedAttributes = true; - foreach (var prim in gltfMesh.primitives) - { - if (lastAttributes != null && !prim.attributes.Equals(lastAttributes)) - { - sharedAttributes = false; - break; - } - - lastAttributes = prim.attributes; - } - - return sharedAttributes; - } - - internal static MeshContext ReadMesh(GltfData data, int meshIndex, IAxisInverter inverter) - { - Profiler.BeginSample("ReadMesh"); - var gltfMesh = data.GLTF.meshes[meshIndex]; - - var meshContext = new MeshContext(gltfMesh.name, meshIndex); - if (HasSharedVertexBuffer(gltfMesh)) - { - meshContext.ImportMeshSharingVertexBuffer(data, gltfMesh, inverter); - } - else - { - meshContext.ImportMeshIndependentVertexBuffer(data, gltfMesh, inverter); - } - - meshContext.RenameBlendShape(gltfMesh); - - meshContext.DropUnusedVertices(); - - Profiler.EndSample(); - return meshContext; - } - - private static (Mesh, bool) BuildMesh(MeshContext meshContext) - { - meshContext.AddDefaultMaterial(); - - //Debug.Log(prims.ToJson()); - var mesh = new Mesh - { - name = meshContext.Name - }; - - meshContext.UploadMeshVertices(mesh); - meshContext.UploadMeshIndices(mesh); - - // NOTE: mesh.vertices では自動的に行われていたが、SetVertexBuffer では行われないため、明示的に呼び出す. - mesh.RecalculateBounds(); - - if (!meshContext.HasNormal) - { - mesh.RecalculateNormals(); - } - - return (mesh, true); - } - - private static async Task BuildBlendShapeAsync(IAwaitCaller awaitCaller, Mesh mesh, BlendShape blendShape, - Vector3[] emptyVertices) - { - Vector3[] positions = null; - Vector3[] normals = null; - await awaitCaller.Run(() => - { - positions = blendShape.Positions.ToArray(); - if (blendShape.Normals != null) - { - normals = blendShape.Normals.ToArray(); - } - }); - - Profiler.BeginSample("MeshImporter.BuildBlendShapeAsync"); - if (blendShape.Positions.Count > 0) - { - if (blendShape.Positions.Count == mesh.vertexCount) - { - mesh.AddBlendShapeFrame(blendShape.Name, FrameWeight, - blendShape.Positions.ToArray(), - normals.Length == mesh.vertexCount && normals.Length == positions.Length ? normals : null, - null - ); - } - else - { - Debug.LogWarningFormat( - "May be partial primitive has blendShape. Require separate mesh or extend blend shape, but not implemented: {0}", - blendShape.Name); - } - } - else - { - // Debug.LogFormat("empty blendshape: {0}.{1}", mesh.name, blendShape.Name); - // add empty blend shape for keep blend shape index - mesh.AddBlendShapeFrame(blendShape.Name, FrameWeight, - emptyVertices, - null, - null - ); - } - - Profiler.EndSample(); - } - - internal static async Task BuildMeshAsync( - IAwaitCaller awaitCaller, - Func ctx, - MeshContext meshContext) - { - Profiler.BeginSample("MeshImporter.BuildMesh"); - var (mesh, recalculateTangents) = BuildMesh(meshContext); - Profiler.EndSample(); - - if (recalculateTangents) - { - await awaitCaller.NextFrame(); - mesh.RecalculateTangents(); - await awaitCaller.NextFrame(); - } - - // 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい - var result = new MeshWithMaterials - { - Mesh = mesh, - Materials = meshContext.MaterialIndices.Select(ctx).ToArray() - }; - - await awaitCaller.NextFrame(); - if (meshContext.BlendShapes.Count > 0) - { - var emptyVertices = new Vector3[mesh.vertexCount]; - foreach (var blendShape in meshContext.BlendShapes) - { - await BuildBlendShapeAsync(awaitCaller, mesh, blendShape, emptyVertices); - } - } - - Profiler.BeginSample("Mesh.UploadMeshData"); - mesh.UploadMeshData(false); - Profiler.EndSample(); - - return result; - } - } -} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs.meta deleted file mode 100644 index 89f3ce9b8..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshImporter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d9658f6e46942b146ad7e752c6592401 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: