From 67e58a8cde553cea2664a25054eed0dce5d316ab Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 3 Jun 2021 17:10:08 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E6=95=B4?= =?UTF-8?q?=E7=90=86=E3=80=82static?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UniGLTF/ExportDialog/MeshExportValidator.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs index a22dcca35..918eee3c0 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs @@ -35,8 +35,11 @@ namespace UniGLTF public virtual bool UseBlendShape(int index, string relativePath) => true; - public virtual void CalcMeshSize(ref MeshExportInfo info, - string relativePath) + static void CalcMeshSize(ref MeshExportInfo info, + string relativePath, + MeshExportSettings settings, + Func useBlendShape + ) { var sb = new StringBuilder(); if (!info.IsRendererActive) @@ -78,10 +81,10 @@ namespace UniGLTF // postion + normal ?. always tangent is ignored info.TotalBlendShapeCount = info.Mesh.blendShapeCount; - info.ExportBlendShapeVertexSize = Settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); + info.ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); for (var i = 0; i < info.Mesh.blendShapeCount; ++i) { - if (!UseBlendShape(i, relativePath)) + if (!useBlendShape(i, relativePath)) { continue; } @@ -114,7 +117,7 @@ namespace UniGLTF info.Summary = sb.ToString(); } - bool TryGetMeshInfo(GameObject root, Renderer renderer, out MeshExportInfo info) + static bool TryGetMeshInfo(GameObject root, Renderer renderer, MeshExportSettings settings, Func useBlendShape, out MeshExportInfo info) { info = default; if (root == null) @@ -153,7 +156,7 @@ namespace UniGLTF info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Renderer.sharedMaterials); var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); - CalcMeshSize(ref info, relativePath); + CalcMeshSize(ref info, relativePath, settings, useBlendShape); return true; } @@ -169,7 +172,7 @@ namespace UniGLTF foreach (var renderer in ExportRoot.GetComponentsInChildren(true)) { - if (TryGetMeshInfo(ExportRoot, renderer, out MeshExportInfo info)) + if (TryGetMeshInfo(ExportRoot, renderer, settings, UseBlendShape, out MeshExportInfo info)) { Meshes.Add(info); } From f02d2d2ee0baf50f0e8e274e768205dacd19783e Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 3 Jun 2021 17:23:04 +0900 Subject: [PATCH 2/7] MeshExportInfo.GetInfo --- .../ExportDialog/ExporterExtensions.cs | 18 -- .../ExportDialog/ExporterExtensions.cs.meta | 11 -- .../ExportDialog/MeshExportValidator.cs | 139 +--------------- .../Runtime/Extensions/UnityExtensions.cs | 12 +- .../UniGLTF/IO/MeshIO/MeshExportInfo.cs | 155 ++++++++++++++++++ 5 files changed, 167 insertions(+), 168 deletions(-) delete mode 100644 Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs delete mode 100644 Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs.meta diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs deleted file mode 100644 index c10c09b87..000000000 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Linq; -using UnityEngine; - -namespace UniGLTF -{ - public static class ExporterExtensions - { - public static bool EnableForExport(this Component mono) - { - if (mono.transform.Ancestors().Any(x => !x.gameObject.activeSelf)) - { - // 自分か祖先に !activeSelf がいる - return false; - } - return true; - } - } -} diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs.meta b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs.meta deleted file mode 100644 index 821ce7fec..000000000 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/ExporterExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f76ebfda1e249cb48890de41cc221889 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs index 918eee3c0..5adf5c53d 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs @@ -35,148 +35,11 @@ namespace UniGLTF public virtual bool UseBlendShape(int index, string relativePath) => true; - static void CalcMeshSize(ref MeshExportInfo info, - string relativePath, - MeshExportSettings settings, - Func useBlendShape - ) - { - var sb = new StringBuilder(); - if (!info.IsRendererActive) - { - sb.Append("[NotActive]"); - } - - info.VertexCount = info.Mesh.vertexCount; - info.ExportVertexSize = 0; - info.TotalBlendShapeCount = 0; - info.ExportBlendShapeCount = 0; - - // float4 x 3 - // vertices - sb.Append($"(Pos"); - if (info.HasNormal) - { - sb.Append("+Nom"); - info.ExportVertexSize += 4 * 3; - } - if (info.HasUV) - { - sb.Append("+UV"); - info.ExportVertexSize += 4 * 2; - } - if (info.HasVertexColor) - { - sb.Append("+Col"); - info.ExportVertexSize += 4 * 4; - } - if (info.HasSkinning) - { - // short, float x 4 weights - sb.Append("+Skin"); - info.ExportVertexSize += (2 + 4) * 4; - } - // indices - info.IndexCount = info.Mesh.triangles.Length; - - // postion + normal ?. always tangent is ignored - info.TotalBlendShapeCount = info.Mesh.blendShapeCount; - info.ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); - for (var i = 0; i < info.Mesh.blendShapeCount; ++i) - { - if (!useBlendShape(i, relativePath)) - { - continue; - } - - ++info.ExportBlendShapeCount; - } - - if (info.ExportBlendShapeCount > 0) - { - sb.Append($"+Morph x {info.ExportBlendShapeCount}"); - } - sb.Append($") x {info.Mesh.vertexCount}"); - switch (info.VertexColor) - { - case VertexColorState.ExistsAndIsUsed: - case VertexColorState.ExistsAndMixed: // エクスポートする - sb.Insert(0, "[use vcolor]"); - break; - case VertexColorState.ExistsButNotUsed: - sb.Insert(0, "[remove vcolor]"); - break; - } - if (info.ExportBlendShapeCount > 0 && !info.HasSkinning) - { - sb.Insert(0, "[morph without skin]"); - } - - // total bytes - sb.Insert(0, $"{info.ExportByteSize:#,0} Bytes = "); - info.Summary = sb.ToString(); - } - - static bool TryGetMeshInfo(GameObject root, Renderer renderer, MeshExportSettings settings, Func useBlendShape, out MeshExportInfo info) - { - info = default; - if (root == null) - { - info.Summary = ""; - return false; - } - if (renderer == null) - { - info.Summary = "no Renderer"; - return false; - } - info.Renderer = renderer; - - if (renderer is SkinnedMeshRenderer smr) - { - info.Skinned = true; - info.Mesh = smr.sharedMesh; - info.IsRendererActive = smr.EnableForExport(); - } - else if (renderer is MeshRenderer mr) - { - var filter = mr.GetComponent(); - if (filter != null) - { - info.Mesh = filter.sharedMesh; - } - info.IsRendererActive = mr.EnableForExport(); - } - else - { - info.Summary = "no Mesh"; - return false; - } - - info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Renderer.sharedMaterials); - - var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); - CalcMeshSize(ref info, relativePath, settings, useBlendShape); - - return true; - } - public void SetRoot(GameObject ExportRoot, MeshExportSettings settings) { Settings = settings; - Meshes.Clear(); - if (ExportRoot == null) - { - return; - } - foreach (var renderer in ExportRoot.GetComponentsInChildren(true)) - { - if (TryGetMeshInfo(ExportRoot, renderer, settings, UseBlendShape, out MeshExportInfo info)) - { - Meshes.Add(info); - } - } + MeshExportInfo.GetInfo(ExportRoot, Meshes, settings, UseBlendShape); } public Func GltfMaterialFromUnityShaderName = DefaultGltfMaterialType; diff --git a/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs b/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs index f51247633..698b6898f 100644 --- a/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs +++ b/Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs @@ -213,7 +213,7 @@ namespace UniGLTF { var current = self; - var split = path.Split(new [] {'/'}, StringSplitOptions.RemoveEmptyEntries); + var split = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); foreach (var childName in split) { @@ -334,5 +334,15 @@ namespace UniGLTF } return go.AddComponent(); } + + public static bool EnableForExport(this Component mono) + { + if (mono.transform.Ancestors().Any(x => !x.gameObject.activeSelf)) + { + // 自分か祖先に !activeSelf がいる + return false; + } + return true; + } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs index 768f27ce7..1e88899d6 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs @@ -1,8 +1,13 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using UnityEngine; namespace UniGLTF { + public delegate bool UseBlendShapeFunc(int blendShapeIndex, string relativePath); + [Serializable] public struct MeshExportInfo { @@ -46,5 +51,155 @@ namespace UniGLTF public int ExportByteSize => ExportVertexSize * VertexCount + IndicesSize + ExportBlendShapeCount * ExportBlendShapeVertexSize * VertexCount; public string Summary; + + /// + /// ヒエラルキーからエクスポートする Mesh の情報を収集する + /// + /// + /// + /// + /// blendShape の export を filtering する + public static void GetInfo(GameObject exportRoot, List list, MeshExportSettings settings, UseBlendShapeFunc useBlendShape) + { + list.Clear(); + if (exportRoot == null) + { + return; + } + + foreach (var renderer in exportRoot.GetComponentsInChildren(true)) + { + if (TryGetMeshInfo(exportRoot, renderer, settings, useBlendShape, out MeshExportInfo info)) + { + list.Add(info); + } + } + } + + static bool TryGetMeshInfo(GameObject root, Renderer renderer, MeshExportSettings settings, UseBlendShapeFunc useBlendShape, out MeshExportInfo info) + { + info = default; + if (root == null) + { + info.Summary = ""; + return false; + } + if (renderer == null) + { + info.Summary = "no Renderer"; + return false; + } + info.Renderer = renderer; + + if (renderer is SkinnedMeshRenderer smr) + { + info.Skinned = true; + info.Mesh = smr.sharedMesh; + info.IsRendererActive = smr.EnableForExport(); + } + else if (renderer is MeshRenderer mr) + { + var filter = mr.GetComponent(); + if (filter != null) + { + info.Mesh = filter.sharedMesh; + } + info.IsRendererActive = mr.EnableForExport(); + } + else + { + info.Summary = "no Mesh"; + return false; + } + + info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Renderer.sharedMaterials); + + var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); + CalcMeshSize(ref info, relativePath, settings, useBlendShape); + + return true; + } + + static void CalcMeshSize(ref MeshExportInfo info, + string relativePath, + MeshExportSettings settings, + UseBlendShapeFunc useBlendShape + ) + { + var sb = new StringBuilder(); + if (!info.IsRendererActive) + { + sb.Append("[NotActive]"); + } + + info.VertexCount = info.Mesh.vertexCount; + info.ExportVertexSize = 0; + info.TotalBlendShapeCount = 0; + info.ExportBlendShapeCount = 0; + + // float4 x 3 + // vertices + sb.Append($"(Pos"); + if (info.HasNormal) + { + sb.Append("+Nom"); + info.ExportVertexSize += 4 * 3; + } + if (info.HasUV) + { + sb.Append("+UV"); + info.ExportVertexSize += 4 * 2; + } + if (info.HasVertexColor) + { + sb.Append("+Col"); + info.ExportVertexSize += 4 * 4; + } + if (info.HasSkinning) + { + // short, float x 4 weights + sb.Append("+Skin"); + info.ExportVertexSize += (2 + 4) * 4; + } + // indices + info.IndexCount = info.Mesh.triangles.Length; + + // postion + normal ?. always tangent is ignored + info.TotalBlendShapeCount = info.Mesh.blendShapeCount; + info.ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); + for (var i = 0; i < info.Mesh.blendShapeCount; ++i) + { + if (!useBlendShape(i, relativePath)) + { + continue; + } + + ++info.ExportBlendShapeCount; + } + + if (info.ExportBlendShapeCount > 0) + { + sb.Append($"+Morph x {info.ExportBlendShapeCount}"); + } + sb.Append($") x {info.Mesh.vertexCount}"); + switch (info.VertexColor) + { + case VertexColorState.ExistsAndIsUsed: + case VertexColorState.ExistsAndMixed: // エクスポートする + sb.Insert(0, "[use vcolor]"); + break; + case VertexColorState.ExistsButNotUsed: + sb.Insert(0, "[remove vcolor]"); + break; + } + if (info.ExportBlendShapeCount > 0 && !info.HasSkinning) + { + sb.Insert(0, "[morph without skin]"); + } + + // total bytes + sb.Insert(0, $"{info.ExportByteSize:#,0} Bytes = "); + info.Summary = sb.ToString(); + } } } From ce98d54976871c7c965dbade389f8c50f9dca8ba Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 3 Jun 2021 18:14:38 +0900 Subject: [PATCH 3/7] IBlendShapeFilter --- .../UniGLTF/ExportDialog/GltfExportWindow.cs | 2 +- .../ExportDialog/MeshExportValidator.cs | 10 +--- .../UniGLTF/IO/MeshIO/BlendShapeFilter.cs | 18 +++++++ .../IO/MeshIO/BlendShapeFilter.cs.meta} | 2 +- .../UniGLTF/IO/MeshIO/MeshExportInfo.cs | 16 +++---- .../Tests/UniGLTF/MeshExportValidatorTests.cs | 10 ++-- ...idaotr.cs => VRMBlendShapeExportFilter.cs} | 47 ++++++++----------- ...meta => VRMBlendShapeExportFilter.cs.meta} | 2 +- Assets/VRM/Editor/Format/VRMExporterWizard.cs | 6 +-- .../Format/VRMMeshExportValidatorEditor.cs | 10 ---- Assets/VRM/Runtime/VRM.asmdef | 6 +-- Assets/VRM10/Editor/Vrm10ExportDialog.cs | 2 +- 12 files changed, 60 insertions(+), 71 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs rename Assets/{VRM/Editor/Format/VRMMeshExportValidaotr.cs.meta => UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs.meta} (83%) rename Assets/VRM/Editor/Format/{VRMMeshExportValidaotr.cs => VRMBlendShapeExportFilter.cs} (74%) rename Assets/VRM/Editor/Format/{VRMMeshExportValidatorEditor.cs.meta => VRMBlendShapeExportFilter.cs.meta} (83%) delete mode 100644 Assets/VRM/Editor/Format/VRMMeshExportValidatorEditor.cs diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs index 2ad68337a..6888cd5e3 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/GltfExportWindow.cs @@ -73,7 +73,7 @@ namespace UniGLTF protected override void OnLayout() { - m_meshes.SetRoot(State.ExportRoot, m_settings.MeshExportSettings); + m_meshes.SetRoot(State.ExportRoot, m_settings.MeshExportSettings, new DefualtBlendShapeExportFilter()); } protected override bool DoGUI(bool isValid) diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs index 5adf5c53d..6c61ffa57 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs @@ -31,15 +31,9 @@ namespace UniGLTF public int ExpectedExportByteSize => Meshes.Where(x => x.IsRendererActive).Sum(x => x.ExportByteSize); - public MeshExportSettings Settings; - - public virtual bool UseBlendShape(int index, string relativePath) => true; - - public void SetRoot(GameObject ExportRoot, MeshExportSettings settings) + public void SetRoot(GameObject ExportRoot, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) { - Settings = settings; - - MeshExportInfo.GetInfo(ExportRoot, Meshes, settings, UseBlendShape); + MeshExportInfo.GetInfo(ExportRoot, Meshes, settings, blendShapeFilter); } public Func GltfMaterialFromUnityShaderName = DefaultGltfMaterialType; diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs new file mode 100644 index 000000000..753e44a67 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs @@ -0,0 +1,18 @@ +namespace UniGLTF +{ + public interface IBlendShapeExportFilter + { + bool UseBlendShape(int blendShapeIndex, string relativePath); + } + + public class DefualtBlendShapeExportFilter : IBlendShapeExportFilter + { + /// + /// Export all blendshape + /// + /// + /// + /// + public bool UseBlendShape(int blendShapeIndex, string relativePath) => true; + } +} diff --git a/Assets/VRM/Editor/Format/VRMMeshExportValidaotr.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs.meta similarity index 83% rename from Assets/VRM/Editor/Format/VRMMeshExportValidaotr.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs.meta index 827e80db5..9a27d0dcc 100644 --- a/Assets/VRM/Editor/Format/VRMMeshExportValidaotr.cs.meta +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/BlendShapeFilter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 18a610aab46d5034cb787ab237e3dea2 +guid: d962c03c08e3d3a4eb5c52f5b4e0c93f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs index 1e88899d6..a069ae375 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs @@ -6,8 +6,6 @@ using UnityEngine; namespace UniGLTF { - public delegate bool UseBlendShapeFunc(int blendShapeIndex, string relativePath); - [Serializable] public struct MeshExportInfo { @@ -58,8 +56,8 @@ namespace UniGLTF /// /// /// - /// blendShape の export を filtering する - public static void GetInfo(GameObject exportRoot, List list, MeshExportSettings settings, UseBlendShapeFunc useBlendShape) + /// blendShape の export を filtering する + public static void GetInfo(GameObject exportRoot, List list, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) { list.Clear(); if (exportRoot == null) @@ -69,14 +67,14 @@ namespace UniGLTF foreach (var renderer in exportRoot.GetComponentsInChildren(true)) { - if (TryGetMeshInfo(exportRoot, renderer, settings, useBlendShape, out MeshExportInfo info)) + if (TryGetMeshInfo(exportRoot, renderer, settings, blendShapeFilter, out MeshExportInfo info)) { list.Add(info); } } } - static bool TryGetMeshInfo(GameObject root, Renderer renderer, MeshExportSettings settings, UseBlendShapeFunc useBlendShape, out MeshExportInfo info) + static bool TryGetMeshInfo(GameObject root, Renderer renderer, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter, out MeshExportInfo info) { info = default; if (root == null) @@ -115,7 +113,7 @@ namespace UniGLTF info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Renderer.sharedMaterials); var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); - CalcMeshSize(ref info, relativePath, settings, useBlendShape); + CalcMeshSize(ref info, relativePath, settings, blendShapeFilter); return true; } @@ -123,7 +121,7 @@ namespace UniGLTF static void CalcMeshSize(ref MeshExportInfo info, string relativePath, MeshExportSettings settings, - UseBlendShapeFunc useBlendShape + IBlendShapeExportFilter blendShapeFilter ) { var sb = new StringBuilder(); @@ -169,7 +167,7 @@ namespace UniGLTF info.ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); for (var i = 0; i < info.Mesh.blendShapeCount; ++i) { - if (!useBlendShape(i, relativePath)) + if (!blendShapeFilter.UseBlendShape(i, relativePath)) { continue; } diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshExportValidatorTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshExportValidatorTests.cs index 803437b4d..aedf44fc7 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshExportValidatorTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshExportValidatorTests.cs @@ -26,7 +26,7 @@ namespace UniGLTF try { - validator.SetRoot(root, MeshExportSettings.Default); + validator.SetRoot(root, MeshExportSettings.Default, new DefualtBlendShapeExportFilter()); var vs = validator.Validate(root); Assert.False(vs.All(x => x.CanExport)); } @@ -46,7 +46,7 @@ namespace UniGLTF try { - validator.SetRoot(root, MeshExportSettings.Default); + validator.SetRoot(root, MeshExportSettings.Default, new DefualtBlendShapeExportFilter()); var vs = validator.Validate(root); Assert.False(vs.All(x => x.CanExport)); } @@ -66,7 +66,7 @@ namespace UniGLTF try { - validator.SetRoot(root, MeshExportSettings.Default); + validator.SetRoot(root, MeshExportSettings.Default, new DefualtBlendShapeExportFilter()); var vs = validator.Validate(root); Assert.False(vs.All(x => x.CanExport)); } @@ -90,7 +90,7 @@ namespace UniGLTF // remove MeshFilter Component.DestroyImmediate(child.GetComponent()); - validator.SetRoot(root, MeshExportSettings.Default); + validator.SetRoot(root, MeshExportSettings.Default, new DefualtBlendShapeExportFilter()); var vs = validator.Validate(root); Assert.True(vs.All(x => x.CanExport)); } @@ -114,7 +114,7 @@ namespace UniGLTF // set null child.GetComponent().sharedMesh = null; - validator.SetRoot(root, MeshExportSettings.Default); + validator.SetRoot(root, MeshExportSettings.Default, new DefualtBlendShapeExportFilter()); var vs = validator.Validate(root); Assert.True(vs.All(x => x.CanExport)); } diff --git a/Assets/VRM/Editor/Format/VRMMeshExportValidaotr.cs b/Assets/VRM/Editor/Format/VRMBlendShapeExportFilter.cs similarity index 74% rename from Assets/VRM/Editor/Format/VRMMeshExportValidaotr.cs rename to Assets/VRM/Editor/Format/VRMBlendShapeExportFilter.cs index 9797057a9..d04f087f0 100644 --- a/Assets/VRM/Editor/Format/VRMMeshExportValidaotr.cs +++ b/Assets/VRM/Editor/Format/VRMBlendShapeExportFilter.cs @@ -5,14 +5,7 @@ using UnityEngine; namespace VRM { - /// - /// Export時にMeshを一覧する。 - /// - /// Mesh関連の Validation する。 - /// Meshのエクスポートサイズを試算する。 - /// - [Serializable] - public class VRMMeshExportValidator : MeshExportValidator + public class VRMBlendShapeExportFilter : IBlendShapeExportFilter { static bool ClipsContainsName(IReadOnlyList clips, bool onlyPreset, BlendShapeBinding binding) { @@ -40,7 +33,24 @@ namespace VRM public VRMExportSettings VRMExportSettings; public List Clips; - public override bool UseBlendShape(int index, string relativePath) + public VRMBlendShapeExportFilter(GameObject exportRoot, VRMExportSettings settings) + { + VRMExportSettings = settings; + Clips = new List(); + if (exportRoot != null) + { + var proxy = exportRoot.GetComponent(); + if (proxy != null) + { + if (proxy.BlendShapeAvatar != null) + { + Clips.AddRange(proxy.BlendShapeAvatar.Clips); + } + } + } + } + + public bool UseBlendShape(int index, string relativePath) { if (VRMExportSettings.ReduceBlendshape) { @@ -57,24 +67,5 @@ namespace VRM return true; } - - public void SetRoot(GameObject ExportRoot, VRMExportSettings settings) - { - VRMExportSettings = settings; - Clips = new List(); - if (ExportRoot != null) - { - var proxy = ExportRoot.GetComponent(); - if (proxy != null) - { - if (proxy.BlendShapeAvatar != null) - { - Clips.AddRange(proxy.BlendShapeAvatar.Clips); - } - } - } - - SetRoot(ExportRoot, settings.MeshExportSettings); - } } } diff --git a/Assets/VRM/Editor/Format/VRMMeshExportValidatorEditor.cs.meta b/Assets/VRM/Editor/Format/VRMBlendShapeExportFilter.cs.meta similarity index 83% rename from Assets/VRM/Editor/Format/VRMMeshExportValidatorEditor.cs.meta rename to Assets/VRM/Editor/Format/VRMBlendShapeExportFilter.cs.meta index 7fa901c84..a30a76ee8 100644 --- a/Assets/VRM/Editor/Format/VRMMeshExportValidatorEditor.cs.meta +++ b/Assets/VRM/Editor/Format/VRMBlendShapeExportFilter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e590565ae8d8e5f45956a20e207d3272 +guid: d634cf68918e2f947b7ea0288d52a720 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM/Editor/Format/VRMExporterWizard.cs b/Assets/VRM/Editor/Format/VRMExporterWizard.cs index 51cc1fd15..1c0f426fe 100644 --- a/Assets/VRM/Editor/Format/VRMExporterWizard.cs +++ b/Assets/VRM/Editor/Format/VRMExporterWizard.cs @@ -36,7 +36,7 @@ namespace VRM Editor m_settingsInspector; - VRMMeshExportValidator m_meshes; + MeshExportValidator m_meshes; Editor m_meshesInspector; @@ -69,7 +69,7 @@ namespace VRM m_settings = ScriptableObject.CreateInstance(); m_settingsInspector = Editor.CreateEditor(m_settings); - m_meshes = ScriptableObject.CreateInstance(); + m_meshes = ScriptableObject.CreateInstance(); m_meshesInspector = Editor.CreateEditor(m_meshes); State.ExportRootChanged += (root) => @@ -179,7 +179,7 @@ namespace VRM protected override void OnLayout() { - m_meshes.SetRoot(State.ExportRoot, m_settings); + m_meshes.SetRoot(State.ExportRoot, m_settings.MeshExportSettings, new VRMBlendShapeExportFilter(State.ExportRoot, m_settings)); } static bool s_foldT = true; diff --git a/Assets/VRM/Editor/Format/VRMMeshExportValidatorEditor.cs b/Assets/VRM/Editor/Format/VRMMeshExportValidatorEditor.cs deleted file mode 100644 index c96a9711a..000000000 --- a/Assets/VRM/Editor/Format/VRMMeshExportValidatorEditor.cs +++ /dev/null @@ -1,10 +0,0 @@ -using UniGLTF; -using UnityEditor; - -namespace VRM -{ - [CustomEditor(typeof(VRMMeshExportValidator))] - public class VRMExportMeshesEditor : MeshExportValidatorEditor - { - } -} diff --git a/Assets/VRM/Runtime/VRM.asmdef b/Assets/VRM/Runtime/VRM.asmdef index 828486611..d5bac528b 100644 --- a/Assets/VRM/Runtime/VRM.asmdef +++ b/Assets/VRM/Runtime/VRM.asmdef @@ -2,19 +2,17 @@ "name": "VRM", "references": [ "UniHumanoid", - "MeshUtility", "UniGLTF", "VRMShaders.GLTF.IO.Runtime", "VRMShaders.VRM.IO.Runtime", "MToon" ], + "optionalUnityReferences": [], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, "overrideReferences": false, "precompiledReferences": [], "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false + "defineConstraints": [] } \ No newline at end of file diff --git a/Assets/VRM10/Editor/Vrm10ExportDialog.cs b/Assets/VRM10/Editor/Vrm10ExportDialog.cs index 9818a4a86..37d18b337 100644 --- a/Assets/VRM10/Editor/Vrm10ExportDialog.cs +++ b/Assets/VRM10/Editor/Vrm10ExportDialog.cs @@ -168,7 +168,7 @@ namespace UniVRM10 protected override void OnLayout() { // m_settings, m_meshes.Meshes - m_meshes.SetRoot(State.ExportRoot, m_settings.MeshExportSettings); + m_meshes.SetRoot(State.ExportRoot, m_settings.MeshExportSettings, new DefualtBlendShapeExportFilter()); } protected override bool DoGUI(bool isValid) From 0706c869eec7c492f4e7118b499bbb0a2f65e6aa Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 3 Jun 2021 18:32:43 +0900 Subject: [PATCH 4/7] MeshExportInfo.Renderers --- .../ExportDialog/MeshExportValidator.cs | 10 +++--- .../ExportDialog/MeshExportValidatorEditor.cs | 15 ++++---- .../UniGLTF/IO/MeshIO/MeshExportInfo.cs | 36 ++++++++++++++----- Assets/VRM/Editor/Format/VRMExporterWizard.cs | 2 +- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs index 6c61ffa57..7137b8549 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs @@ -64,28 +64,28 @@ namespace UniGLTF foreach (var info in Meshes) { // invalid materials.len - if (info.Renderer.sharedMaterials.Length < info.Mesh.subMeshCount) + if (info.Materials.Length < info.Mesh.subMeshCount) { // submesh より material の方が少ない yield return Validation.Error(Messages.MATERIALS_LESS_THAN_SUBMESH_COUNT.Msg()); } else { - if (info.Renderer.sharedMaterials.Length > info.Mesh.subMeshCount) + if (info.Materials.Length > info.Mesh.subMeshCount) { // submesh より material の方が多い yield return Validation.Warning(Messages.MATERIALS_GREATER_THAN_SUBMESH_COUNT.Msg()); } - if (info.Renderer.sharedMaterials.Take(info.Mesh.subMeshCount).Any(x => x == null)) + if (info.Materials.Take(info.Mesh.subMeshCount).Any(x => x == null)) { // material に null が含まれる(unity で magenta になっているはず) - yield return Validation.Error($"{info.Renderer}: {Messages.MATERIALS_CONTAINS_NULL.Msg()}"); + yield return Validation.Error($"{info.Renderers}: {Messages.MATERIALS_CONTAINS_NULL.Msg()}"); } } } - foreach (var m in Meshes.SelectMany(x => x.Renderer.sharedMaterials).Distinct()) + foreach (var m in Meshes.SelectMany(x => x.Materials).Distinct()) { if (m == null) { diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs index 70edf409c..e69f21ba2 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs @@ -40,12 +40,15 @@ namespace UniGLTF var (left, right) = LeftRight(r.x, r.y, col0, r.width - col0, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(left, $"{i,3}"); - GUI.enabled = false; - EditorGUI.ObjectField(right, info.Renderer, info.Renderer.GetType(), true); - - right.y += EditorGUIUtility.singleLineHeight; - EditorGUI.ObjectField(right, info.Mesh, info.Renderer.GetType(), true); - GUI.enabled = true; + using (new EditorGUI.DisabledScope(false)) + { + foreach (var renderer in info.Renderers) + { + EditorGUI.ObjectField(right, renderer, info.Renderers.GetType(), true); + } + right.y += EditorGUIUtility.singleLineHeight; + EditorGUI.ObjectField(right, info.Mesh, info.Renderers.GetType(), true); + } right.y += EditorGUIUtility.singleLineHeight; EditorGUI.LabelField(right, info.Summary); diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs index a069ae375..785cb5b0a 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs @@ -7,10 +7,18 @@ using UnityEngine; namespace UniGLTF { [Serializable] - public struct MeshExportInfo + public class MeshExportInfo { - public Renderer Renderer; + #region この2つの組が gltf mesh の Unique なキーとなる public Mesh Mesh; + public Material[] Materials; + #endregion + + /// + /// ひとつの Mesh を複数の Renderer が共有することがありうる + /// + public List Renderers; + public bool IsRendererActive; public bool Skinned; @@ -50,6 +58,12 @@ namespace UniGLTF public string Summary; + MeshExportInfo(Renderer renderer) + { + Materials = renderer.sharedMaterials; + Renderers = new List { renderer }; + } + /// /// ヒエラルキーからエクスポートする Mesh の情報を収集する /// @@ -76,27 +90,27 @@ namespace UniGLTF static bool TryGetMeshInfo(GameObject root, Renderer renderer, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter, out MeshExportInfo info) { - info = default; if (root == null) { - info.Summary = ""; + info = default; return false; } if (renderer == null) { - info.Summary = "no Renderer"; + info = default; return false; } - info.Renderer = renderer; if (renderer is SkinnedMeshRenderer smr) { + info = new MeshExportInfo(renderer); info.Skinned = true; info.Mesh = smr.sharedMesh; info.IsRendererActive = smr.EnableForExport(); } else if (renderer is MeshRenderer mr) { + info = new MeshExportInfo(renderer); var filter = mr.GetComponent(); if (filter != null) { @@ -106,11 +120,15 @@ namespace UniGLTF } else { - info.Summary = "no Mesh"; - return false; + throw new NotImplementedException(); } - info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Renderer.sharedMaterials); + if (info.Mesh == null) + { + info.Summary = "no mesh"; + } + + info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Materials); var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); CalcMeshSize(ref info, relativePath, settings, blendShapeFilter); diff --git a/Assets/VRM/Editor/Format/VRMExporterWizard.cs b/Assets/VRM/Editor/Format/VRMExporterWizard.cs index 1c0f426fe..2861af0c6 100644 --- a/Assets/VRM/Editor/Format/VRMExporterWizard.cs +++ b/Assets/VRM/Editor/Format/VRMExporterWizard.cs @@ -259,7 +259,7 @@ namespace VRM switch (meshInfo.VertexColor) { case UniGLTF.VertexColorState.ExistsAndMixed: - Validation.Warning($"{meshInfo.Renderer}: Both vcolor.multiply and not multiply unlit materials exist").DrawGUI(); + Validation.Warning($"{meshInfo.Renderers}: Both vcolor.multiply and not multiply unlit materials exist").DrawGUI(); break; } } From 66f04112189641a6e79b0589fda031765693de0b Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 3 Jun 2021 19:42:30 +0900 Subject: [PATCH 5/7] integrate MeshWithRenderer to MeshExportInfo --- .../ExportDialog/MeshExportValidatorEditor.cs | 2 +- .../UniGLTF/IO/MeshIO/MeshExportInfo.cs | 333 ++++++++++++++---- .../MeshExporter_DividedVertexBuffer.cs | 4 +- .../MeshIO/MeshExporter_SharedVertexBuffer.cs | 6 +- .../UniGLTF/IO/MeshIO/MeshWithRenderer.cs | 112 ------ .../IO/MeshIO/MeshWithRenderer.cs.meta | 11 - .../Runtime/UniGLTF/IO/gltfExporter.cs | 86 +++-- Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs | 4 +- 8 files changed, 312 insertions(+), 246 deletions(-) delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs delete mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs.meta diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs index e69f21ba2..f5160f291 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidatorEditor.cs @@ -42,7 +42,7 @@ namespace UniGLTF using (new EditorGUI.DisabledScope(false)) { - foreach (var renderer in info.Renderers) + foreach (var (renderer, _) in info.Renderers) { EditorGUI.ObjectField(right, renderer, info.Renderers.GetType(), true); } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs index 785cb5b0a..25d15131b 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs @@ -12,16 +12,134 @@ namespace UniGLTF #region この2つの組が gltf mesh の Unique なキーとなる public Mesh Mesh; public Material[] Materials; + + public bool IsSameMeshAndMaterials(MeshExportInfo other) + { + return IsSameMeshAndMaterials(other.Mesh, other.Materials); + } + + public bool IsSameMeshAndMaterials(Mesh mesh, Material[] materials) + { + if (Mesh != mesh) return false; + if (Materials.Length != materials.Length) return false; + for (var i = 0; i < Materials.Length; i++) + { + if (Materials[i] != materials[i]) return false; + } + return true; + } + + public bool IsSameMeshAndMaterials(Renderer r) + { + if (r is SkinnedMeshRenderer smr) + { + return IsSameMeshAndMaterials(smr.sharedMesh, smr.sharedMaterials); + } + else if (r is MeshRenderer mr) + { + var filter = r.GetComponent(); + if (filter == null) + { + return false; + } + return IsSameMeshAndMaterials(filter.sharedMesh, mr.sharedMaterials); + } + else + { + throw new NotImplementedException(); + } + } + + public static bool TryGetSameMeshIndex(List meshWithRenderers, Mesh mesh, Material[] materials, out int meshIndex) + { + for (var i = 0; i < meshWithRenderers.Count; i++) + { + if (meshWithRenderers[i].IsSameMeshAndMaterials(mesh, materials)) + { + meshIndex = i; + return true; + } + } + + meshIndex = -1; + return false; + } + + public bool CanExport + { + get + { + if (Mesh == null) + { + return false; + } + if (Mesh.vertexCount == 0) + { + return false; + } + if (Materials == null) + { + return false; + } + if (Materials.Length == 0) + { + return false; + } + return true; + } + } #endregion /// /// ひとつの Mesh を複数の Renderer が共有することがありうる /// - public List Renderers; + List<(Renderer, Transform[] UniqueBones)> _renderers; + public IReadOnlyList<(Renderer, Transform[] UniqueBones)> Renderers => _renderers; - public bool IsRendererActive; + public bool IsRendererActive => Renderers.Any(x => x.Item1.EnableForExport()); + + #region SkinnedMeshRenderer public bool Skinned; + int[] JointIndexMap; + /// + /// glTF は skinning の boneList の重複を許可しない + /// (unity は ok) + /// + /// + /// + public int GetJointIndex(int index) + { + if (index < 0) + { + return index; + } + + if (JointIndexMap != null) + { + return JointIndexMap[index]; + } + else + { + return index; + } + } + + public IEnumerable GetBindPoses() + { + var used = new HashSet(); + for (int i = 0; i < JointIndexMap.Length; ++i) + { + var index = JointIndexMap[i]; + if (used.Add(index)) + { + yield return Mesh.bindposes[i]; + } + } + } + #endregion + + #region VertexAttribute public bool HasNormal => Mesh != null && Mesh.normals != null && Mesh.normals.Length == Mesh.vertexCount; public bool HasUV => Mesh != null && Mesh.uv != null && Mesh.uv.Length == Mesh.vertexCount; @@ -42,163 +160,236 @@ namespace UniGLTF /// [SkinningWeight] /// public int ExportVertexSize; + #endregion + #region Triangles public int IndexCount; // int 決め打ち public int IndicesSize => IndexCount * 4; + #endregion + #region BlendShape public int ExportBlendShapeVertexSize; public int TotalBlendShapeCount; public int ExportBlendShapeCount; + #endregion + #region Summary public int ExportByteSize => ExportVertexSize * VertexCount + IndicesSize + ExportBlendShapeCount * ExportBlendShapeVertexSize * VertexCount; public string Summary; + #endregion - MeshExportInfo(Renderer renderer) + public MeshExportInfo(Transform t) { - Materials = renderer.sharedMaterials; - Renderers = new List { renderer }; + } - /// - /// ヒエラルキーからエクスポートする Mesh の情報を収集する - /// - /// - /// - /// - /// blendShape の export を filtering する - public static void GetInfo(GameObject exportRoot, List list, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) - { - list.Clear(); - if (exportRoot == null) - { - return; - } - - foreach (var renderer in exportRoot.GetComponentsInChildren(true)) - { - if (TryGetMeshInfo(exportRoot, renderer, settings, blendShapeFilter, out MeshExportInfo info)) - { - list.Add(info); - } - } - } - - static bool TryGetMeshInfo(GameObject root, Renderer renderer, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter, out MeshExportInfo info) + MeshExportInfo(GameObject root, Renderer renderer, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) { if (root == null) { - info = default; - return false; + throw new ArgumentNullException(); } if (renderer == null) { - info = default; - return false; + throw new ArgumentNullException(); } + Materials = renderer.sharedMaterials; + _renderers = new List<(Renderer, Transform[])>(); if (renderer is SkinnedMeshRenderer smr) { - info = new MeshExportInfo(renderer); - info.Skinned = true; - info.Mesh = smr.sharedMesh; - info.IsRendererActive = smr.EnableForExport(); + Skinned = true; + Mesh = smr.sharedMesh; } else if (renderer is MeshRenderer mr) { - info = new MeshExportInfo(renderer); var filter = mr.GetComponent(); if (filter != null) { - info.Mesh = filter.sharedMesh; + Mesh = filter.sharedMesh; } - info.IsRendererActive = mr.EnableForExport(); } else { throw new NotImplementedException(); } - if (info.Mesh == null) + if (Mesh == null) { - info.Summary = "no mesh"; + Summary = "no mesh"; } - info.VertexColor = VertexColorUtility.DetectVertexColor(info.Mesh, info.Materials); + VertexColor = VertexColorUtility.DetectVertexColor(Mesh, Materials); var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); - CalcMeshSize(ref info, relativePath, settings, blendShapeFilter); + CalcMeshSize(relativePath, settings, blendShapeFilter); + + PushRenderer(renderer); + } + + public void PushRenderer(Renderer renderer) + { + if (renderer is SkinnedMeshRenderer smr) + { + if (smr.bones != null && smr.bones.Length > 0) + { + var uniqueBones = smr.bones.Distinct().ToArray(); + var jointIndexMap = new int[smr.bones.Length]; + var bones = smr.bones; + for (int i = 0; i < bones.Length; ++i) + { + jointIndexMap[i] = Array.IndexOf(uniqueBones, bones[i]); + } + _renderers.Add((smr, uniqueBones)); + + if (JointIndexMap != null) + { + if (!JointIndexMap.SequenceEqual(jointIndexMap)) + { + // edge case + throw new NotImplementedException("different jointIndexMap is not supported"); + } + } + JointIndexMap = jointIndexMap; + } + else + { + // maybe blendshape only SkinnedMeshRenderer + _renderers.Add((smr, null)); + } + } + else if (renderer is MeshRenderer mr) + { + _renderers.Add((mr, null)); + } + else + { + throw new NotImplementedException(); + } + } + + /// + /// ヒエラルキーからエクスポートする Mesh の情報を収集する + /// + /// + /// + /// + /// blendShape の export を filtering する + public static void GetInfo(GameObject root, List list, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) + { + list.Clear(); + if (root == null) + { + return; + } + + GetInfo(root, root.transform.Traverse() + // exclude root object for the symmetry with the importer + .Skip(1), + list, settings, blendShapeFilter); + } + + public static void GetInfo(GameObject root, IEnumerable nodes, List list, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) + { + list.Clear(); + if (root == null) + { + return; + } + + foreach (var node in nodes) + { + var renderer = node.GetComponent(); + if (renderer == null) + { + continue; + } + + var found = list.FirstOrDefault(x => x.IsSameMeshAndMaterials(renderer)); + if (found != null) + { + found.PushRenderer(renderer); + continue; + } + + list.Add(new MeshExportInfo(root, renderer, settings, blendShapeFilter)); + } + } + + static bool TryGetMeshInfo() + { return true; } - static void CalcMeshSize(ref MeshExportInfo info, + void CalcMeshSize( string relativePath, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter ) { var sb = new StringBuilder(); - if (!info.IsRendererActive) + if (!IsRendererActive) { sb.Append("[NotActive]"); } - info.VertexCount = info.Mesh.vertexCount; - info.ExportVertexSize = 0; - info.TotalBlendShapeCount = 0; - info.ExportBlendShapeCount = 0; + VertexCount = Mesh.vertexCount; + ExportVertexSize = 0; + TotalBlendShapeCount = 0; + ExportBlendShapeCount = 0; // float4 x 3 // vertices sb.Append($"(Pos"); - if (info.HasNormal) + if (HasNormal) { sb.Append("+Nom"); - info.ExportVertexSize += 4 * 3; + ExportVertexSize += 4 * 3; } - if (info.HasUV) + if (HasUV) { sb.Append("+UV"); - info.ExportVertexSize += 4 * 2; + ExportVertexSize += 4 * 2; } - if (info.HasVertexColor) + if (HasVertexColor) { sb.Append("+Col"); - info.ExportVertexSize += 4 * 4; + ExportVertexSize += 4 * 4; } - if (info.HasSkinning) + if (HasSkinning) { // short, float x 4 weights sb.Append("+Skin"); - info.ExportVertexSize += (2 + 4) * 4; + ExportVertexSize += (2 + 4) * 4; } // indices - info.IndexCount = info.Mesh.triangles.Length; + IndexCount = Mesh.triangles.Length; // postion + normal ?. always tangent is ignored - info.TotalBlendShapeCount = info.Mesh.blendShapeCount; - info.ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); - for (var i = 0; i < info.Mesh.blendShapeCount; ++i) + TotalBlendShapeCount = Mesh.blendShapeCount; + ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); + for (var i = 0; i < Mesh.blendShapeCount; ++i) { if (!blendShapeFilter.UseBlendShape(i, relativePath)) { continue; } - ++info.ExportBlendShapeCount; + ++ExportBlendShapeCount; } - if (info.ExportBlendShapeCount > 0) + if (ExportBlendShapeCount > 0) { - sb.Append($"+Morph x {info.ExportBlendShapeCount}"); + sb.Append($"+Morph x {ExportBlendShapeCount}"); } - sb.Append($") x {info.Mesh.vertexCount}"); - switch (info.VertexColor) + sb.Append($") x {Mesh.vertexCount}"); + switch (VertexColor) { case VertexColorState.ExistsAndIsUsed: case VertexColorState.ExistsAndMixed: // エクスポートする @@ -208,14 +399,14 @@ namespace UniGLTF sb.Insert(0, "[remove vcolor]"); break; } - if (info.ExportBlendShapeCount > 0 && !info.HasSkinning) + if (ExportBlendShapeCount > 0 && !HasSkinning) { sb.Insert(0, "[morph without skin]"); } // total bytes - sb.Insert(0, $"{info.ExportByteSize:#,0} Bytes = "); - info.Summary = sb.ToString(); + sb.Insert(0, $"{ExportByteSize:#,0} Bytes = "); + Summary = sb.ToString(); } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs index 22b72471d..f0a8159cf 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs @@ -8,7 +8,7 @@ namespace UniGLTF public static class MeshExporter_DividedVertexBuffer { public static (glTFMesh, Dictionary) Export(glTF gltf, int bufferIndex, - MeshWithRenderer unityMesh, List unityMaterials, + MeshExportInfo unityMesh, List unityMaterials, IAxisInverter axisInverter, MeshExportSettings settings) { var mesh = unityMesh.Mesh; @@ -58,7 +58,7 @@ namespace UniGLTF } } - var material = unityMesh.Renderer.sharedMaterials[i]; + var material = unityMesh.Materials[i]; var materialIndex = -1; if (material != null) { diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs index fc7c1fa8b..23aefbca8 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs @@ -24,11 +24,11 @@ namespace UniGLTF /// /// public static (glTFMesh, Dictionary blendShapeIndexMap) Export(glTF gltf, int bufferIndex, - MeshWithRenderer unityMesh, List unityMaterials, + MeshExportInfo unityMesh, List unityMaterials, IAxisInverter axisInverter, MeshExportSettings settings) { var mesh = unityMesh.Mesh; - var materials = unityMesh.Renderer.sharedMaterials; + var materials = unityMesh.Materials; var positions = mesh.vertices.Select(axisInverter.InvertVector3).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(); @@ -135,7 +135,7 @@ namespace UniGLTF if (j >= materials.Length) { - Debug.LogWarningFormat("{0}.materials is not enough", unityMesh.Renderer.name); + Debug.LogWarningFormat("{0}.materials is not enough", unityMesh.Mesh.name); break; } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs deleted file mode 100644 index ad7190766..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace UniGLTF -{ - public struct MeshWithRenderer - { - public readonly Mesh Mesh; - public readonly Renderer Renderer; - public readonly Transform[] UniqueBones; - readonly int[] JointIndexMap; - - public MeshWithRenderer(Transform x) - { - Mesh = x.GetSharedMesh(); - Renderer = x.GetComponent(); - - if (Renderer is SkinnedMeshRenderer skin && skin.bones != null && skin.bones.Length > 0) - { - // has joints - var uniqueBones = skin.bones.Distinct().ToArray(); - UniqueBones = uniqueBones; - JointIndexMap = new int[skin.bones.Length]; - - var bones = skin.bones; - for (int i = 0; i < bones.Length; ++i) - { - JointIndexMap[i] = Array.IndexOf(uniqueBones, bones[i]); - } - } - else - { - UniqueBones = null; - JointIndexMap = null; - } - } - - /// - /// glTF は skinning の boneList の重複を許可しない - /// (unity は ok) - /// - /// - /// - public int GetJointIndex(int index) - { - if (index < 0) - { - return index; - } - - if (JointIndexMap != null) - { - return JointIndexMap[index]; - } - else - { - return index; - } - } - - public IEnumerable GetBindPoses() - { - var used = new HashSet(); - for (int i = 0; i < JointIndexMap.Length; ++i) - { - var index = JointIndexMap[i]; - if (used.Add(index)) - { - yield return Mesh.bindposes[i]; - } - } - } - - public static IEnumerable FromNodes(IEnumerable nodes) - { - foreach (var node in nodes) - { - var x = new MeshWithRenderer(node); - if (x.Mesh == null) - { - continue; ; - } - if (x.Renderer == null - || x.Renderer.sharedMaterials == null - || x.Renderer.sharedMaterials.Length == 0) - { - continue; - } - - yield return x; - } - } - - public bool IsSameMeshAndMaterials(MeshWithRenderer other) - { - return IsSameMeshAndMaterials(other.Mesh, other.Renderer.sharedMaterials); - } - - public bool IsSameMeshAndMaterials(Mesh mesh, Material[] materials) - { - if (Mesh != mesh) return false; - if (Renderer.sharedMaterials.Length != materials.Length) return false; - for (var i = 0; i < Renderer.sharedMaterials.Length; i++) - { - if (Renderer.sharedMaterials[i] != materials[i]) return false; - } - return true; - } - } -} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs.meta deleted file mode 100644 index 0472adb35..000000000 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshWithRenderer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ed51e6c1221d3b744a914e977e875122 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index 54a9a2707..ac836c051 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -138,7 +138,7 @@ namespace UniGLTF } #region Export - static glTFNode ExportNode(Transform x, List nodes, List meshWithRenderers, List skins) + static glTFNode ExportNode(Transform x, List nodes, List meshWithRenderers, List skins) { var node = new glTFNode { @@ -160,7 +160,7 @@ namespace UniGLTF { var mesh = meshFilter.sharedMesh; var materials = meshRenderer.sharedMaterials; - if (TryGetSameMeshIndex(meshWithRenderers, mesh, materials, out int meshIndex)) + if (MeshExportInfo.TryGetSameMeshIndex(meshWithRenderers, mesh, materials, out int meshIndex)) { node.mesh = meshIndex; } @@ -182,7 +182,7 @@ namespace UniGLTF { var mesh = skinnedMeshRenderer.sharedMesh; var materials = skinnedMeshRenderer.sharedMaterials; - if (TryGetSameMeshIndex(meshWithRenderers, mesh, materials, out int meshIndex)) + if (MeshExportInfo.TryGetSameMeshIndex(meshWithRenderers, mesh, materials, out int meshIndex)) { node.mesh = meshIndex; node.skin = skins.IndexOf(skinnedMeshRenderer); @@ -203,28 +203,18 @@ namespace UniGLTF return node; } - private static bool TryGetSameMeshIndex(List meshWithRenderers, Mesh mesh, Material[] materials, out int meshIndex) - { - for (var i = 0; i < meshWithRenderers.Count; i++) - { - if (meshWithRenderers[i].IsSameMeshAndMaterials(mesh, materials)) - { - meshIndex = i; - return true; - } - } - - meshIndex = -1; - return false; - } - public virtual void ExportExtensions(ITextureSerializer textureSerializer) { // do nothing } - public virtual void Export(MeshExportSettings meshExportSettings, ITextureSerializer textureSerializer) + public virtual void Export(MeshExportSettings meshExportSettings, ITextureSerializer textureSerializer, IBlendShapeExportFilter blendShapeFilter = null) { + if (blendShapeFilter == null) + { + blendShapeFilter = new DefualtBlendShapeExportFilter(); + } + var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); var bufferIndex = glTF.AddBuffer(bytesBuffer); @@ -232,15 +222,11 @@ namespace UniGLTF .Skip(1) // exclude root object for the symmetry with the importer .ToList(); - var unityMeshes = MeshWithRenderer.FromNodes(Nodes).Where(x => x.Mesh.vertices.Any()).ToList(); - var uniqueUnityMeshes = new List(); - foreach (var um in unityMeshes) - { - if (!uniqueUnityMeshes.Any(x => x.IsSameMeshAndMaterials(um))) uniqueUnityMeshes.Add(um); - } + var uniqueUnityMeshes = new List(); + MeshExportInfo.GetInfo(Copy, Nodes, uniqueUnityMeshes, meshExportSettings, blendShapeFilter); #region Materials and Textures - Materials = uniqueUnityMeshes.SelectMany(x => x.Renderer.sharedMaterials).Where(x => x != null).Distinct().ToList(); + Materials = uniqueUnityMeshes.SelectMany(x => x.Materials).Where(x => x != null).Distinct().ToList(); TextureExporter = new TextureExporter(textureSerializer); @@ -267,10 +253,17 @@ namespace UniGLTF #endregion #region Nodes and Skins - var unitySkins = uniqueUnityMeshes - .Where(x => x.UniqueBones != null) - .ToList(); - glTF.nodes = Nodes.Select(x => ExportNode(x, Nodes, uniqueUnityMeshes, unitySkins.Select(y => y.Renderer as SkinnedMeshRenderer).ToList())).ToList(); + var skins = uniqueUnityMeshes + .SelectMany(x => x.Renderers) + .Where(x => x.Item1 is SkinnedMeshRenderer && x.UniqueBones != null) + .Select(x => x.Item1 as SkinnedMeshRenderer) + .ToList() + ; + foreach (var node in Nodes) + { + var gltfNode = ExportNode(node, Nodes, uniqueUnityMeshes, skins); + glTF.nodes.Add(gltfNode); + } glTF.scenes = new List { new gltfScene @@ -279,26 +272,31 @@ namespace UniGLTF } }; - foreach (var x in unitySkins) + foreach (var x in uniqueUnityMeshes) { var matrices = x.GetBindPoses().Select(m_axisInverter.InvertMat4).ToArray(); var accessor = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE); - var renderer = x.Renderer as SkinnedMeshRenderer; - var skin = new glTFSkin + foreach (var (renderer, uniqueBones) in x.Renderers) { - inverseBindMatrices = accessor, - joints = x.UniqueBones.Select(y => Nodes.IndexOf(y)).ToArray(), - skeleton = Nodes.IndexOf(renderer.rootBone), - }; - var skinIndex = glTF.skins.Count; - glTF.skins.Add(skin); + if (uniqueBones != null && renderer is SkinnedMeshRenderer smr) + { + var skin = new glTFSkin + { + inverseBindMatrices = accessor, + joints = uniqueBones.Select(y => Nodes.IndexOf(y)).ToArray(), + skeleton = Nodes.IndexOf(smr.rootBone), + }; + var skinIndex = glTF.skins.Count; + glTF.skins.Add(skin); - foreach (var z in Nodes.Where(y => y.Has(x.Renderer))) - { - var nodeIndex = Nodes.IndexOf(z); - var node = glTF.nodes[nodeIndex]; - node.skin = skinIndex; + foreach (var z in Nodes.Where(y => y.Has(renderer))) + { + var nodeIndex = Nodes.IndexOf(z); + var node = glTF.nodes[nodeIndex]; + node.skin = skinIndex; + } + } } } #endregion diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs index c9a4aa3ea..8f69afa19 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs @@ -134,7 +134,7 @@ namespace UniGLTF }; var axisInverter = Axes.X.Create(); - var unityMesh = new MeshWithRenderer(go.transform); + var unityMesh = new MeshExportInfo(go.transform); var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer ? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings) : MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings) @@ -182,7 +182,7 @@ namespace UniGLTF }; var axisInverter = Axes.X.Create(); - var unityMesh = new MeshWithRenderer(go.transform); + var unityMesh = new MeshExportInfo(go.transform); var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer ? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings) : MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings) From 8b8f21f536bd9681b8a7464a52d9477170cf5550 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 3 Jun 2021 20:04:30 +0900 Subject: [PATCH 6/7] fix text. MeshExportInfo.Create --- .../Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs | 14 ++++++++------ Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs | 5 ++--- Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs index 25d15131b..e115d0a33 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs @@ -183,11 +183,6 @@ namespace UniGLTF public string Summary; #endregion - public MeshExportInfo(Transform t) - { - - } - MeshExportInfo(GameObject root, Renderer renderer, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) { if (root == null) @@ -232,7 +227,7 @@ namespace UniGLTF PushRenderer(renderer); } - public void PushRenderer(Renderer renderer) + void PushRenderer(Renderer renderer) { if (renderer is SkinnedMeshRenderer smr) { @@ -273,6 +268,13 @@ namespace UniGLTF } } + public static MeshExportInfo Create(GameObject go) + { + var list = new List(); + GetInfo(go, list, MeshExportSettings.Default, new DefualtBlendShapeExportFilter()); + return list[0]; + } + /// /// ヒエラルキーからエクスポートする Mesh の情報を収集する /// diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index ac836c051..fbfdd7371 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -274,13 +274,12 @@ namespace UniGLTF foreach (var x in uniqueUnityMeshes) { - var matrices = x.GetBindPoses().Select(m_axisInverter.InvertMat4).ToArray(); - var accessor = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE); - foreach (var (renderer, uniqueBones) in x.Renderers) { if (uniqueBones != null && renderer is SkinnedMeshRenderer smr) { + var matrices = x.GetBindPoses().Select(m_axisInverter.InvertMat4).ToArray(); + var accessor = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE); var skin = new glTFSkin { inverseBindMatrices = accessor, diff --git a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs index 8f69afa19..1ef275bd5 100644 --- a/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs +++ b/Assets/UniGLTF/Tests/UniGLTF/MeshTests.cs @@ -134,7 +134,7 @@ namespace UniGLTF }; var axisInverter = Axes.X.Create(); - var unityMesh = new MeshExportInfo(go.transform); + var unityMesh = MeshExportInfo.Create(go); var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer ? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings) : MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings) @@ -182,7 +182,7 @@ namespace UniGLTF }; var axisInverter = Axes.X.Create(); - var unityMesh = new MeshExportInfo(go.transform); + var unityMesh = MeshExportInfo.Create(go); var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer ? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings) : MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings) From 506460665a94d90add764adf384583c44b73534d Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 3 Jun 2021 20:21:10 +0900 Subject: [PATCH 7/7] null check. public MeshExportInfo.CalcMeshSize --- .../ExportDialog/MeshExportValidator.cs | 6 +- .../UniGLTF/IO/MeshIO/MeshExportInfo.cs | 184 +++++++++--------- .../Runtime/UniGLTF/IO/gltfExporter.cs | 9 +- 3 files changed, 98 insertions(+), 101 deletions(-) diff --git a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs index 7137b8549..f00644a14 100644 --- a/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs +++ b/Assets/UniGLTF/Editor/UniGLTF/ExportDialog/MeshExportValidator.cs @@ -33,7 +33,11 @@ namespace UniGLTF public void SetRoot(GameObject ExportRoot, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) { - MeshExportInfo.GetInfo(ExportRoot, Meshes, settings, blendShapeFilter); + MeshExportInfo.GetInfo(ExportRoot.transform.Traverse().Skip(1), Meshes, settings); + foreach(var info in Meshes) + { + info.CalcMeshSize(ExportRoot, info.Renderers[0].Item1, settings, blendShapeFilter); + } } public Func GltfMaterialFromUnityShaderName = DefaultGltfMaterialType; diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs index e115d0a33..aa4f58667 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportInfo.cs @@ -143,12 +143,12 @@ namespace UniGLTF public bool HasNormal => Mesh != null && Mesh.normals != null && Mesh.normals.Length == Mesh.vertexCount; public bool HasUV => Mesh != null && Mesh.uv != null && Mesh.uv.Length == Mesh.vertexCount; - public bool HasVertexColor => Mesh.colors != null && Mesh.colors.Length == Mesh.vertexCount + public bool HasVertexColor => Mesh != null && Mesh.colors != null && Mesh.colors.Length == Mesh.vertexCount && VertexColor == VertexColorState.ExistsAndIsUsed || VertexColor == VertexColorState.ExistsAndMixed // Export する ; - public bool HasSkinning => Mesh.boneWeights != null && Mesh.boneWeights.Length == Mesh.vertexCount; + public bool HasSkinning => Mesh != null && Mesh.boneWeights != null && Mesh.boneWeights.Length == Mesh.vertexCount; public VertexColorState VertexColor; @@ -183,12 +183,8 @@ namespace UniGLTF public string Summary; #endregion - MeshExportInfo(GameObject root, Renderer renderer, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) + MeshExportInfo(Renderer renderer, MeshExportSettings settings) { - if (root == null) - { - throw new ArgumentNullException(); - } if (renderer == null) { throw new ArgumentNullException(); @@ -221,9 +217,6 @@ namespace UniGLTF VertexColor = VertexColorUtility.DetectVertexColor(Mesh, Materials); - var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); - CalcMeshSize(relativePath, settings, blendShapeFilter); - PushRenderer(renderer); } @@ -271,7 +264,7 @@ namespace UniGLTF public static MeshExportInfo Create(GameObject go) { var list = new List(); - GetInfo(go, list, MeshExportSettings.Default, new DefualtBlendShapeExportFilter()); + GetInfo(go.transform.Traverse(), list, MeshExportSettings.Default); return list[0]; } @@ -282,28 +275,9 @@ namespace UniGLTF /// /// /// blendShape の export を filtering する - public static void GetInfo(GameObject root, List list, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) + public static void GetInfo(IEnumerable nodes, List list, MeshExportSettings settings) { list.Clear(); - if (root == null) - { - return; - } - - GetInfo(root, root.transform.Traverse() - // exclude root object for the symmetry with the importer - .Skip(1), - list, settings, blendShapeFilter); - } - - public static void GetInfo(GameObject root, IEnumerable nodes, List list, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter) - { - list.Clear(); - if (root == null) - { - return; - } - foreach (var node in nodes) { var renderer = node.GetComponent(); @@ -319,7 +293,11 @@ namespace UniGLTF continue; } - list.Add(new MeshExportInfo(root, renderer, settings, blendShapeFilter)); + var info = new MeshExportInfo(renderer, settings); + if (info.Mesh != null) + { + list.Add(info); + } } } @@ -329,7 +307,19 @@ namespace UniGLTF return true; } - void CalcMeshSize( + + public void CalcMeshSize( + GameObject root, + Renderer renderer, + MeshExportSettings settings, + IBlendShapeExportFilter blendShapeFilter + ) + { + var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform); + CalcMeshSize(relativePath, settings, blendShapeFilter); + } + + public void CalcMeshSize( string relativePath, MeshExportSettings settings, IBlendShapeExportFilter blendShapeFilter @@ -341,73 +331,81 @@ namespace UniGLTF sb.Append("[NotActive]"); } - VertexCount = Mesh.vertexCount; - ExportVertexSize = 0; - TotalBlendShapeCount = 0; - ExportBlendShapeCount = 0; + if (Mesh == null) + { + sb.Append("[NoMesh]"); + } + else + { - // float4 x 3 - // vertices - sb.Append($"(Pos"); - if (HasNormal) - { - sb.Append("+Nom"); - ExportVertexSize += 4 * 3; - } - if (HasUV) - { - sb.Append("+UV"); - ExportVertexSize += 4 * 2; - } - if (HasVertexColor) - { - sb.Append("+Col"); - ExportVertexSize += 4 * 4; - } - if (HasSkinning) - { - // short, float x 4 weights - sb.Append("+Skin"); - ExportVertexSize += (2 + 4) * 4; - } - // indices - IndexCount = Mesh.triangles.Length; + VertexCount = Mesh.vertexCount; + ExportVertexSize = 0; + TotalBlendShapeCount = 0; + ExportBlendShapeCount = 0; - // postion + normal ?. always tangent is ignored - TotalBlendShapeCount = Mesh.blendShapeCount; - ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); - for (var i = 0; i < Mesh.blendShapeCount; ++i) - { - if (!blendShapeFilter.UseBlendShape(i, relativePath)) + // float4 x 3 + // vertices + sb.Append($"(Pos"); + if (HasNormal) { - continue; + sb.Append("+Nom"); + ExportVertexSize += 4 * 3; + } + if (HasUV) + { + sb.Append("+UV"); + ExportVertexSize += 4 * 2; + } + if (HasVertexColor) + { + sb.Append("+Col"); + ExportVertexSize += 4 * 4; + } + if (HasSkinning) + { + // short, float x 4 weights + sb.Append("+Skin"); + ExportVertexSize += (2 + 4) * 4; + } + // indices + IndexCount = Mesh.triangles.Length; + + // postion + normal ?. always tangent is ignored + TotalBlendShapeCount = Mesh.blendShapeCount; + ExportBlendShapeVertexSize = settings.ExportOnlyBlendShapePosition ? 4 * 3 : 4 * (3 + 3); + for (var i = 0; i < Mesh.blendShapeCount; ++i) + { + if (!blendShapeFilter.UseBlendShape(i, relativePath)) + { + continue; + } + + ++ExportBlendShapeCount; } - ++ExportBlendShapeCount; - } + if (ExportBlendShapeCount > 0) + { + sb.Append($"+Morph x {ExportBlendShapeCount}"); + } + sb.Append($") x {Mesh.vertexCount}"); + switch (VertexColor) + { + case VertexColorState.ExistsAndIsUsed: + case VertexColorState.ExistsAndMixed: // エクスポートする + sb.Insert(0, "[use vcolor]"); + break; + case VertexColorState.ExistsButNotUsed: + sb.Insert(0, "[remove vcolor]"); + break; + } + if (ExportBlendShapeCount > 0 && !HasSkinning) + { + sb.Insert(0, "[morph without skin]"); + } - if (ExportBlendShapeCount > 0) - { - sb.Append($"+Morph x {ExportBlendShapeCount}"); + // total bytes + sb.Insert(0, $"{ExportByteSize:#,0} Bytes = "); } - sb.Append($") x {Mesh.vertexCount}"); - switch (VertexColor) - { - case VertexColorState.ExistsAndIsUsed: - case VertexColorState.ExistsAndMixed: // エクスポートする - sb.Insert(0, "[use vcolor]"); - break; - case VertexColorState.ExistsButNotUsed: - sb.Insert(0, "[remove vcolor]"); - break; - } - if (ExportBlendShapeCount > 0 && !HasSkinning) - { - sb.Insert(0, "[morph without skin]"); - } - - // total bytes - sb.Insert(0, $"{ExportByteSize:#,0} Bytes = "); Summary = sb.ToString(); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs index fbfdd7371..dc4cb567d 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/gltfExporter.cs @@ -208,13 +208,8 @@ namespace UniGLTF // do nothing } - public virtual void Export(MeshExportSettings meshExportSettings, ITextureSerializer textureSerializer, IBlendShapeExportFilter blendShapeFilter = null) + public virtual void Export(MeshExportSettings meshExportSettings, ITextureSerializer textureSerializer) { - if (blendShapeFilter == null) - { - blendShapeFilter = new DefualtBlendShapeExportFilter(); - } - var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); var bufferIndex = glTF.AddBuffer(bytesBuffer); @@ -223,7 +218,7 @@ namespace UniGLTF .ToList(); var uniqueUnityMeshes = new List(); - MeshExportInfo.GetInfo(Copy, Nodes, uniqueUnityMeshes, meshExportSettings, blendShapeFilter); + MeshExportInfo.GetInfo(Nodes, uniqueUnityMeshes, meshExportSettings); #region Materials and Textures Materials = uniqueUnityMeshes.SelectMany(x => x.Materials).Where(x => x != null).Distinct().ToList();