diff --git a/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs b/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs index b1aa8de6f..332324a10 100644 --- a/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs +++ b/Assets/UniGLTF/Editor/MeshUtility/MeshUtilityDialog.cs @@ -71,90 +71,8 @@ namespace UniGLTF.MeshUtility void OnEnable() { - // Clear(HelpMessage.Ready, ValidationError.None); - // OnValidate(); } - // void Clear(HelpMessage help, ValidationError error) - // { - // helpString = help.Msg(); - // errorString = error != ValidationError.None ? error.Msg() : null; - // m_uniqueMaterials = new Material[] { }; - // m_duplicateMaterials = new MaterialList[] { }; - // m_excludes.Clear(); - // isValid = false; - // } - - // void OnValidate() - // { - // isValid = false; - // if (m_root == null) - // { - // Clear(HelpMessage.SetTarget, ValidationError.NoTarget); - // return; - // } - - // if (m_root.GetGameObjectType() != GameObjectType.AssetPrefab) - // { - // Clear(HelpMessage.SetTarget, ValidationError.NotPrefab); - // return; - // } - - // if (m_root.transform.parent != null) - // { - // Clear(HelpMessage.InvalidTarget, ValidationError.HasParent); - // return; - // } - - // var backup = m_excludes.ToArray(); - // Clear(HelpMessage.Ready, ValidationError.None); - // isValid = true; - // m_uniqueMaterials = MeshIntegratorUtility.EnumerateSkinnedMeshRenderer(m_root.transform, MeshEnumerateOption.OnlyWithoutBlendShape) - // .SelectMany(x => x.sharedMaterials) - // .Distinct() - // .ToArray(); - - // m_duplicateMaterials = m_uniqueMaterials - // .GroupBy(x => GetMaterialKey(x), x => x) - // .Select(x => new MaterialList(x.ToArray())) - // .Where(x => x.Materials.Length > 1) - // .ToArray() - // ; - - // UpdateExcludes(backup); - // } - - // void UpdateExcludes(ExcludeItem[] backup) - // { - // var exclude_map = new Dictionary(); - // var excludes = new List(); - // foreach (var x in m_root.GetComponentsInChildren()) - // { - // var mesh = x.GetMesh(); - // if (mesh == null) - // { - // continue; - // } - // if (exclude_map.ContainsKey(mesh)) - // { - // continue; - // } - - // var item = new ExcludeItem - // { - // Mesh = mesh, - // }; - // var found = backup.FirstOrDefault(y => y.Mesh == mesh); - // if (found != null) - // { - // item.Exclude = found.Exclude; - // } - // excludes.Add(item); - // exclude_map[mesh] = item; - // } - // m_excludes.AddRange(excludes); - // } - protected virtual void DialogMessage() { EditorGUILayout.HelpBox(MeshUtilityMessages.MESH_UTILITY.Msg(), MessageType.Info); @@ -290,7 +208,7 @@ namespace UniGLTF.MeshUtility PrefabUtility.UnpackPrefabInstance(copy, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); } - var (results, created) = MeshUtility.Process(copy); + var (results, created) = MeshUtility.Process(_exportTarget, copy); WriteAssets(copy, assetFolder, results); @@ -305,7 +223,7 @@ namespace UniGLTF.MeshUtility { PrefabUtility.UnpackPrefabInstance(_exportTarget, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); } - var (results, created) = MeshUtility.Process(_exportTarget); + var (results, created) = MeshUtility.Process(_exportTarget, null); foreach (var go in created) { Undo.RegisterCreatedObjectUndo(go, "MeshUtility"); diff --git a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs b/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs deleted file mode 100644 index 035c1a6f2..000000000 --- a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using UniGLTF.M17N; -using UnityEditor; -using UnityEngine; - -namespace UniGLTF.MeshUtility -{ - public static class TabMeshIntegrator - { - public static bool TryExecutable(GameObject root, out string msg) - { - // check - if (root == null) - { - msg = MeshUtilityMessages.NO_GAMEOBJECT_SELECTED.Msg(); - return false; - } - - if (HasVrm(root)) - { - msg = MeshUtilityMessages.VRM_DETECTED.Msg(); - return false; - } - - if (root.GetComponentsInChildren().Length == 0 && root.GetComponentsInChildren().Length == 0) - { - msg = MeshUtilityMessages.NO_MESH.Msg(); - return false; - } - - msg = ""; - return true; - } - - const string VRM_META = "VRMMeta"; - static bool HasVrm(GameObject root) - { - var allComponents = root.GetComponents(typeof(Component)); - foreach (var component in allComponents) - { - if (component == null) continue; - var sourceString = component.ToString(); - if (sourceString.Contains(VRM_META)) - { - return true; - } - } - return false; - } - - const string ASSET_SUFFIX = ".mesh.asset"; - - static string GetMeshWritePath(Mesh mesh) - { - if (!string.IsNullOrEmpty((AssetDatabase.GetAssetPath(mesh)))) - { - var directory = Path.GetDirectoryName(AssetDatabase.GetAssetPath(mesh)).Replace("\\", "/"); - return $"{directory}/{Path.GetFileNameWithoutExtension(mesh.name)}{ASSET_SUFFIX}"; - } - else - { - return $"Assets/{Path.GetFileNameWithoutExtension(mesh.name)}{ASSET_SUFFIX}"; - } - } - - /// GameObject instance in scene or prefab - public static bool Execute(GameObject src, bool onlyBlendShapeRenderers) - { - var results = new List(); - - // instance or prefab => copy - var copy = GameObject.Instantiate(src); - copy.name = copy.name + "_mesh_integration"; - - // integrate - if (onlyBlendShapeRenderers) - { - results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithBlendShape)); - results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.OnlyWithoutBlendShape)); - } - else - { - results.Add(MeshIntegratorUtility.Integrate(copy, onlyBlendShapeRenderers: MeshEnumerateOption.All)); - } - - // replace - MeshIntegratorUtility.ReplaceMeshWithResults(copy, results); - - // write mesh asset. - foreach (var result in results) - { - var mesh = result.Integrated.Mesh; - var assetPath = GetMeshWritePath(mesh); - Debug.LogFormat("CreateAsset: {0}", assetPath); - AssetDatabase.CreateAsset(mesh, assetPath); - } - - if (src.GetGameObjectType() == GameObjectType.AssetPrefab) - { - // write prefab. - { - var prefabPath = UnityPath.FromAsset(src); - prefabPath = prefabPath.Parent.Child($"{prefabPath.FileNameWithoutExtension}_integrated.prefab"); - Debug.LogFormat("WritePrefab: {0}", prefabPath); - PrefabUtility.SaveAsPrefabAsset(copy, prefabPath.Value); - } - - // destroy copy in scene. - GameObject.DestroyImmediate(copy); - } - else - { - // do nothing. keep copy. - } - - return true; - } - } -} diff --git a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs.meta b/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs.meta deleted file mode 100644 index 5c60a51fe..000000000 --- a/Assets/UniGLTF/Editor/MeshUtility/TabMeshIntegrator.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 65a227dcf3cb5f34085bd6829894fb64 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/MeshUtility/GltfMeshUtility.cs b/Assets/UniGLTF/Runtime/MeshUtility/GltfMeshUtility.cs index 91c584b1d..0e4f8ebce 100644 --- a/Assets/UniGLTF/Runtime/MeshUtility/GltfMeshUtility.cs +++ b/Assets/UniGLTF/Runtime/MeshUtility/GltfMeshUtility.cs @@ -150,12 +150,31 @@ namespace UniGLTF.MeshUtility return empty; } - protected virtual List CopyMeshIntegrationGroups() + /// + /// + /// + /// MeshIntegrationGroup を作ったとき root + /// go が prefab だった場合に instance されたもの + /// + protected virtual IEnumerable CopyInstantiate(GameObject go, GameObject instance) { - return MeshIntegrationGroups.ToList(); + if (instance == null) + { + foreach (var g in MeshIntegrationGroups) + { + yield return g; + } + } + else + { + foreach (var g in MeshIntegrationGroups) + { + yield return g.CopyInstantiate(go, instance); + } + } } - public virtual (List, List) Process(GameObject go) + public virtual (List, List) Process(GameObject go, GameObject instance) { if (FreezeBlendShape || FreezeRotation || FreezeScaling) { @@ -168,11 +187,11 @@ namespace UniGLTF.MeshUtility BoneNormalizer.Replace(go, newMesh, FreezeRotation, FreezeScaling); } - var copy = CopyMeshIntegrationGroups(); + var copy = CopyInstantiate(go, instance); var newList = new List(); - var empty = GetOrCreateEmpty(go, "mesh"); + var empty = GetOrCreateEmpty(instance ?? go, "mesh"); var results = new List(); foreach (var group in copy) diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationGroup.cs b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationGroup.cs index 7d7158691..bf0b969e4 100644 --- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationGroup.cs +++ b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegrationGroup.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using UnityEngine; @@ -9,9 +8,25 @@ namespace UniGLTF.MeshUtility public string Name; public List Renderers = new List(); - public static List ToList() + public MeshIntegrationGroup CopyInstantiate(GameObject go, GameObject instance) { - throw new NotImplementedException(); + var copy = new MeshIntegrationGroup + { + Name = Name + }; + foreach (var r in Renderers) + { + var relative = r.transform.RelativePathFrom(go.transform); + if (r is SkinnedMeshRenderer smr) + { + copy.Renderers.Add(instance.transform.GetFromPath(relative).GetComponent()); + } + else if (r is MeshRenderer mr) + { + copy.Renderers.Add(instance.transform.GetFromPath(relative).GetComponent()); + } + } + return copy; } } } \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs deleted file mode 100644 index 283fe3fc8..000000000 --- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace UniGLTF.MeshUtility -{ - public static class MeshIntegratorUtility - { - public const string INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME = "Integrated(WithoutBlendShape)"; - public const string INTEGRATED_MESH_WITH_BLENDSHAPE_NAME = "Integrated(WithBlendShape)"; - public const string INTEGRATED_MESH_ALL_NAME = "Integrated(All)"; - - /// - /// go を root としたヒエラルキーから Renderer を集めて、統合された Mesh 作成する - /// - /// - /// - /// true: BlendShapeを保持するSkinnedMeshRendererのみ - /// false: BlendShapeを保持しないSkinnedMeshRenderer + MeshRenderer - /// null: すべてのSkinnedMeshRenderer + MeshRenderer - /// - /// - public static MeshIntegrationResult Integrate(GameObject go, MeshEnumerateOption onlyBlendShapeRenderers, - IEnumerable excludes = null, - bool destroyIntegratedRenderer = false) - { - var exclude = new MeshExclude(excludes); - - var group = new MeshIntegrationGroup(); - bool useBlendShape = false; - - switch (onlyBlendShapeRenderers) - { - case MeshEnumerateOption.OnlyWithBlendShape: - { - group.Name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME; - useBlendShape = true; - - foreach (var x in EnumerateSkinnedMeshRenderer(go.transform, onlyBlendShapeRenderers)) - { - if (exclude.IsExcluded(x)) - { - continue; - } - group.Renderers.Add(x); - } - break; - } - - case MeshEnumerateOption.OnlyWithoutBlendShape: - { - group.Name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME; - useBlendShape = false; - - foreach (var x in EnumerateSkinnedMeshRenderer(go.transform, onlyBlendShapeRenderers)) - { - if (exclude.IsExcluded(x)) - { - continue; - } - group.Renderers.Add(x); - } - - foreach (var x in EnumerateMeshRenderer(go.transform)) - { - if (exclude.IsExcluded(x)) - { - continue; - } - group.Renderers.Add(x); - } - - break; - } - - case MeshEnumerateOption.All: - { - group.Name = INTEGRATED_MESH_ALL_NAME; - useBlendShape = true; - - foreach (var x in EnumerateSkinnedMeshRenderer(go.transform, onlyBlendShapeRenderers)) - { - if (exclude.IsExcluded(x)) - { - continue; - } - group.Renderers.Add(x); - } - - foreach (var x in EnumerateMeshRenderer(go.transform)) - { - if (exclude.IsExcluded(x)) - { - continue; - } - group.Renderers.Add(x); - } - - break; - } - } - - return MeshIntegrator.Integrate(group, useBlendShape - ? MeshIntegrator.BlendShapeOperation.Use - : MeshIntegrator.BlendShapeOperation.None); - } - - public static IEnumerable EnumerateSkinnedMeshRenderer(Transform root, MeshEnumerateOption hasBlendShape) - { - foreach (var x in Traverse(root)) - { - var renderer = x.GetComponent(); - if (renderer != null && - renderer.gameObject.activeInHierarchy && - renderer.sharedMesh != null && - renderer.enabled) - { - switch (hasBlendShape) - { - case MeshEnumerateOption.OnlyWithBlendShape: - if (renderer.sharedMesh.blendShapeCount > 0) - { - yield return renderer; - } - break; - - case MeshEnumerateOption.OnlyWithoutBlendShape: - if (renderer.sharedMesh.blendShapeCount == 0) - { - yield return renderer; - } - break; - - case MeshEnumerateOption.All: - { - yield return renderer; - break; - } - } - } - } - } - - public static IEnumerable EnumerateMeshRenderer(Transform root) - { - foreach (var x in Traverse(root)) - { - var renderer = x.GetComponent(); - var filter = x.GetComponent(); - - if (renderer != null && - filter != null && - renderer.gameObject.activeInHierarchy && - filter.sharedMesh != null) - { - yield return renderer; - } - } - } - - private static IEnumerable Traverse(Transform parent) - { - if (parent.gameObject.activeSelf) - { - yield return parent; - - foreach (Transform child in parent) - { - foreach (var x in Traverse(child)) - { - yield return x; - } - } - } - } - - public static void ReplaceMeshWithResults(GameObject copy, List results) - { - // destroy original meshes - foreach (var skinnedMesh in copy.GetComponentsInChildren()) - { - GameObject.DestroyImmediate(skinnedMesh); - } - foreach (var normalMesh in copy.GetComponentsInChildren()) - { - if (normalMesh.gameObject.GetComponent()) - { - GameObject.DestroyImmediate(normalMesh.gameObject.GetComponent()); - } - GameObject.DestroyImmediate(normalMesh); - } - - // Add integrated - foreach (var result in results) - { - result.AddIntegratedRendererTo(copy); - } - } - } -} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs.meta b/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs.meta deleted file mode 100644 index b9075e71b..000000000 --- a/Assets/UniGLTF/Runtime/MeshUtility/MeshIntegratorUtility.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a982d9d30c0145038245b0214dc2f2e4 -timeCreated: 1560190306 \ No newline at end of file diff --git a/Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs b/Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs index 62ffd4187..afb4d3f3d 100644 --- a/Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs +++ b/Assets/VRM/Runtime/SkinnedMeshUtility/VrmMeshUtility.cs @@ -10,7 +10,7 @@ namespace VRM public class VrmMeshUtility : UniGLTF.MeshUtility.GltfMeshUtility { bool _generateFirstPerson = false; - protected override List CopyMeshIntegrationGroups() + protected override IEnumerable CopyInstantiate(GameObject go, GameObject instance) { var copy = new List(); _generateFirstPerson = false; @@ -84,7 +84,7 @@ namespace VRM /// /// glTF に比べて Humanoid や FirstPerson の処理が追加される /// - public override (List, List) Process(GameObject go) + public override (List, List) Process(GameObject go, GameObject instance) { _vrmInstance = go.GetComponent(); if (_vrmInstance == null) @@ -105,7 +105,7 @@ namespace VRM // TODO: update: spring // TODO: update: constraint // TODO: update: firstPerson offset - var (list, newList) = base.Process(go); + var (list, newList) = base.Process(go, instance); if (FreezeBlendShape || FreezeRotation || FreezeScaling) { diff --git a/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs b/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs index 2b8f039fb..15728a027 100644 --- a/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs +++ b/Assets/VRM10/Runtime/MeshUtility/Vrm10MeshUtility.cs @@ -10,7 +10,7 @@ namespace UniVRM10 public class Vrm10MeshUtility : UniGLTF.MeshUtility.GltfMeshUtility { bool _generateFirstPerson = false; - protected override List CopyMeshIntegrationGroups() + protected override IEnumerable CopyInstantiate(GameObject go, GameObject instance) { var copy = new List(); _generateFirstPerson = false; @@ -89,7 +89,7 @@ namespace UniVRM10 /// /// glTF に比べて Humanoid や FirstPerson の処理が追加される /// - public override (List, List) Process(GameObject go) + public override (List, List) Process(GameObject go, GameObject instance) { _vrmInstance = go.GetComponent(); if (_vrmInstance == null) @@ -110,7 +110,7 @@ namespace UniVRM10 // TODO: update: spring // TODO: update: constraint // TODO: update: firstPerson offset - var (list, newList) = base.Process(go); + var (list, newList) = base.Process(go, instance); if (FreezeBlendShape || FreezeRotation || FreezeScaling) {