summaryrefslogtreecommitdiff
path: root/Assets/ThirdParty/VRM/MeshUtility/Editor/BoneMeshEraserWizard.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/ThirdParty/VRM/MeshUtility/Editor/BoneMeshEraserWizard.cs')
-rw-r--r--Assets/ThirdParty/VRM/MeshUtility/Editor/BoneMeshEraserWizard.cs200
1 files changed, 200 insertions, 0 deletions
diff --git a/Assets/ThirdParty/VRM/MeshUtility/Editor/BoneMeshEraserWizard.cs b/Assets/ThirdParty/VRM/MeshUtility/Editor/BoneMeshEraserWizard.cs
new file mode 100644
index 00000000..63bf9045
--- /dev/null
+++ b/Assets/ThirdParty/VRM/MeshUtility/Editor/BoneMeshEraserWizard.cs
@@ -0,0 +1,200 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+
+
+namespace MeshUtility
+{
+ [CustomPropertyDrawer(typeof(BoneMeshEraser.EraseBone))]
+ public class EraseBoneDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+ {
+ //EditorGUI.BeginProperty(position, label, property);
+
+ var leftWidth = 0.6f;
+ var rightWidth = 1.0f - leftWidth;
+
+ var leftSide = new Rect(position.x, position.y, position.width * leftWidth, position.height);
+ var rightSide = new Rect(position.width * leftWidth, position.y, position.width * rightWidth, position.height);
+ {
+ EditorGUI.PropertyField(leftSide, property.FindPropertyRelative("Bone"), new GUIContent("", ""));
+ EditorGUI.PropertyField(rightSide, property.FindPropertyRelative("Erase"));
+ }
+
+ //EditorGUI.EndProperty();
+ }
+
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ var height = base.GetPropertyHeight(property, label);
+ return height;
+ }
+ }
+
+ public class BoneMeshEraserWizard : ScriptableWizard
+ {
+ const string ASSET_SUFFIX = ".asset";
+
+ [SerializeField]
+ SkinnedMeshRenderer m_skinnedMesh;
+
+ [SerializeField]
+ Animator m_animator;
+
+ [SerializeField]
+ Transform EraseRoot;
+
+ [SerializeField]
+ BoneMeshEraser.EraseBone[] m_eraseBones;
+
+ [MenuItem(MeshUtility.MENU_PARENT + "BoneMeshEraser Wizard", priority = 4)]
+ static void CreateWizard()
+ {
+ ScriptableWizard.DisplayWizard<BoneMeshEraserWizard>("BoneMeshEraser", "Erase triangles by bone", "Erase");
+ }
+
+ private void OnEnable()
+ {
+ var root = Selection.activeGameObject;
+ if (root != null)
+ {
+ m_animator = root.GetComponent<Animator>();
+ m_skinnedMesh = root.GetComponent<SkinnedMeshRenderer>();
+ OnValidate();
+ }
+ }
+
+ void OnValidate()
+ {
+ //Debug.Log("OnValidate");
+ if (m_skinnedMesh == null)
+ {
+ m_eraseBones = new BoneMeshEraser.EraseBone[] { };
+ return;
+ }
+
+ if (EraseRoot == null)
+ {
+ if (m_animator != null)
+ {
+ EraseRoot = m_animator.GetBoneTransform(HumanBodyBones.Head);
+ //Debug.LogFormat("head: {0}", EraseRoot);
+ }
+ }
+
+ m_eraseBones = m_skinnedMesh.bones.Select(x =>
+ {
+ var eb = new BoneMeshEraser.EraseBone
+ {
+ Bone = x,
+ };
+
+ if (EraseRoot != null)
+ {
+ // 首の子孫を消去
+ if (eb.Bone.Ancestor().Any(y => y == EraseRoot))
+ {
+ //Debug.LogFormat("erase {0}", x);
+ eb.Erase = true;
+ }
+ }
+
+ return eb;
+ })
+ .ToArray();
+ }
+
+ void OnWizardUpdate()
+ {
+ helpString = "select target skinnedMesh and animator";
+ }
+
+
+
+ static int IndexOf(Transform[] list, Transform target)
+ {
+ for (int i = 0; i < list.Length; ++i)
+ {
+ if (list[i] == target)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ SkinnedMeshRenderer _Erase(GameObject go)
+ {
+ if (go == null)
+ {
+ Debug.LogWarning("select root object in hierarchy");
+ return null;
+ }
+ if (m_skinnedMesh == null)
+ {
+ Debug.LogWarning("no skinnedmesh");
+ return null;
+ }
+
+ var bones = m_skinnedMesh.bones;
+ var eraseBones = m_eraseBones
+ .Where(x => x.Erase)
+ .Select(x => Array.IndexOf(bones, x.Bone))
+ .ToArray();
+
+ var meshNode = new GameObject("BoneMeshEraser");
+ meshNode.transform.SetParent(go.transform, false);
+
+ var erased = meshNode.AddComponent<SkinnedMeshRenderer>();
+ erased.sharedMesh = BoneMeshEraser.CreateErasedMesh(m_skinnedMesh.sharedMesh, eraseBones);
+ erased.sharedMaterials = m_skinnedMesh.sharedMaterials;
+ erased.bones = m_skinnedMesh.bones;
+
+ return erased;
+ }
+
+ void Erase()
+ {
+ var go = Selection.activeGameObject;
+ var renderer = _Erase(go);
+ if (renderer == null)
+ {
+ return;
+ }
+
+ // save mesh to Assets
+ var assetPath = string.Format("{0}{1}", go.name, ASSET_SUFFIX);
+ var prefab = MeshUtility.GetPrefab(go);
+ if (prefab != null)
+ {
+ var prefabPath = AssetDatabase.GetAssetPath(prefab);
+ assetPath = string.Format("{0}/{1}{2}",
+ Path.GetDirectoryName(prefabPath),
+ Path.GetFileNameWithoutExtension(prefabPath),
+ ASSET_SUFFIX
+ );
+ }
+
+ Debug.LogFormat("CreateAsset: {0}", assetPath);
+ AssetDatabase.CreateAsset(renderer.sharedMesh, assetPath);
+ }
+
+ void OnWizardCreate()
+ {
+ //Debug.Log("OnWizardCreate");
+ Erase();
+
+ // close
+ }
+
+ void OnWizardOtherButton()
+ {
+ //Debug.Log("OnWizardOtherButton");
+ Erase();
+ }
+ }
+}