rabidus-test/Assets/BNG Framework/HandPoser/Editor/HandPoserEditor.cs

263 lines
9.7 KiB
C#
Raw Permalink Normal View History

2023-07-24 16:38:13 +03:00
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace BNG {
[CustomEditor(typeof(HandPoser))]
[CanEditMultipleObjects]
public class HandPoserEditor : Editor {
SerializedProperty currentPose;
SerializedProperty animationSpeed;
SerializedProperty updateJointRotations;
SerializedProperty updateJointPositions;
SerializedProperty updateWristPosition;
// Auto Pose properties
SerializedProperty openHandPose;
SerializedProperty closedHandPose;
SerializedProperty autoUpdateAutoPose;
SerializedProperty fingerTipRadius;
SerializedProperty fingerTipOffsets;
SerializedProperty WristJoint;
SerializedProperty ThumbJoints;
SerializedProperty IndexJoints;
SerializedProperty MiddleJoints;
SerializedProperty RingJoints;
SerializedProperty PinkyJoints;
SerializedProperty OtherJoints;
HandPoser poser;
void OnEnable() {
currentPose = serializedObject.FindProperty("CurrentPose");
animationSpeed = serializedObject.FindProperty("AnimationSpeed");
updateJointRotations = serializedObject.FindProperty("UpdateJointRotations");
updateJointPositions = serializedObject.FindProperty("UpdateJointPositions");
updateWristPosition = serializedObject.FindProperty("UpdateWristPosition");
openHandPose = serializedObject.FindProperty("OpenHandPose");
closedHandPose = serializedObject.FindProperty("ClosedHandPose");
autoUpdateAutoPose = serializedObject.FindProperty("UpdateContinuously");
fingerTipRadius = serializedObject.FindProperty("FingerTipRadius");
fingerTipOffsets = serializedObject.FindProperty("FingerTipOffsets");
WristJoint = serializedObject.FindProperty("WristJoint");
ThumbJoints = serializedObject.FindProperty("ThumbJoints");
IndexJoints = serializedObject.FindProperty("IndexJoints");
MiddleJoints = serializedObject.FindProperty("MiddleJoints");
RingJoints = serializedObject.FindProperty("RingJoints");
PinkyJoints = serializedObject.FindProperty("PinkyJoints");
OtherJoints = serializedObject.FindProperty("OtherJoints");
}
bool showTransformProps, showAnimationProps;
public override void OnInspectorGUI() {
poser = (HandPoser)target;
serializedObject.Update();
GUILayout.Label("Hand Pose", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(currentPose);
// Show option to auto assign if nothing has been set yet
bool notYetSpecified = (poser.ThumbJoints == null || poser.ThumbJoints != null && poser.ThumbJoints.Count == 0) &&
(poser.IndexJoints == null || poser.IndexJoints != null && poser.IndexJoints.Count == 0) &&
(poser.MiddleJoints == null || poser.MiddleJoints != null && poser.MiddleJoints.Count == 0) &&
(poser.RingJoints == null || poser.RingJoints != null && poser.RingJoints.Count == 0) &&
(poser.PinkyJoints == null || poser.PinkyJoints != null && poser.PinkyJoints.Count == 0) &&
(poser.OtherJoints == null || poser.OtherJoints != null && poser.OtherJoints.Count == 0);
if (notYetSpecified ) {
EditorGUILayout.HelpBox("No Bone Transforms have been assigned, would you like to auto assign them now?", MessageType.Warning);
if (GUILayout.Button("Auto Assign")) {
AutoAssignBones();
// Toggle props
showTransformProps = true;
}
}
// Show Transform Properties
showTransformProps = EditorGUILayout.Foldout(showTransformProps, "Transform Definitions (" + poser.GetTotalJointsCount() + ")");
if (showTransformProps) {
EditorGUILayout.Separator();
EditorGUI.indentLevel++;
if (GUILayout.Button("Auto Assign")) {
AutoAssignBones();
}
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(ThumbJoints);
EditorGUILayout.PropertyField(IndexJoints);
EditorGUILayout.PropertyField(MiddleJoints);
EditorGUILayout.PropertyField(RingJoints);
EditorGUILayout.PropertyField(PinkyJoints);
EditorGUILayout.PropertyField(OtherJoints);
EditorGUILayout.PropertyField(WristJoint);
EditorGUI.indentLevel--;
}
EditorGUILayout.Separator();
EditorGUILayout.PropertyField(animationSpeed);
showAnimationProps = EditorGUILayout.Foldout(showAnimationProps, "Update Options");
if (showAnimationProps) {
EditorGUILayout.PropertyField(updateJointRotations);
EditorGUILayout.PropertyField(updateJointPositions);
EditorGUILayout.PropertyField(updateWristPosition);
}
EditorGUILayout.Separator();
GUILayout.Label("Save Pose", EditorStyles.boldLabel);
GUILayout.BeginHorizontal();
var initialColor = GUI.backgroundColor;
//GUI.backgroundColor = Color.green;
if (GUILayout.Button("Save Pose...")) {
SaveHandPoseAs(poser);
}
// Reset color
GUI.backgroundColor = initialColor;
GUILayout.EndHorizontal();
EditorGUILayout.Separator();
// Gizmos
serializedObject.ApplyModifiedProperties();
}
public void AutoAssignBones() {
// Reset bones
poser.WristJoint = null;
poser.ThumbJoints = new List<Transform>();
poser.IndexJoints = new List<Transform>();
poser.MiddleJoints = new List<Transform>();
poser.RingJoints= new List<Transform>();
poser.PinkyJoints = new List<Transform>();
poser.OtherJoints = new List<Transform>();
bool wristFound = false;
Transform[] children = poser.GetComponentsInChildren<Transform>();
int childCount = children.Length;
for (int x = 0; x < childCount; x++) {
Transform child = children[x];
if(child == null || child.name == null || child == poser.transform) {
continue;
}
// Ignore this bone
if(ShouldIgnoreJoint(child)) {
continue;
}
string formattedName = child.name.ToLower();
// Assign Bones to appropriate containers
if (formattedName.Contains("thumb")) {
poser.ThumbJoints.Add(child);
}
else if (formattedName.Contains("index")) {
poser.IndexJoints.Add(child);
}
else if (formattedName.Contains("middle")) {
poser.MiddleJoints.Add(child);
}
else if (formattedName.Contains("ring")) {
poser.RingJoints.Add(child);
}
else if (formattedName.Contains("pinky")) {
poser.PinkyJoints.Add(child);
}
else if(wristFound == false && formattedName.Contains("wrist") || (formattedName.EndsWith("hand") && child.childCount > 3)) {
poser.WristJoint = child;
wristFound = true;
}
else {
poser.OtherJoints.Add(child);
}
}
}
public virtual bool ShouldIgnoreJoint(Transform theJoint) {
if(!theJoint.gameObject.activeSelf) {
return true; ;
}
// Don't store the handsmodel location. This is only for rendering
string loweredName = theJoint.name.ToLower();
if (loweredName == "handsmodel" || loweredName == "lhand" || loweredName == "rhand" || loweredName.StartsWith("tip_collider") || loweredName.StartsWith("hands_col")) {
return true;
}
return false;
}
public void SaveHandPoseAs(HandPoser poser) {
// Open Window
HandPoseSaveAs window = (HandPoseSaveAs)EditorWindow.GetWindow(typeof(HandPoseSaveAs));
window.ShowWindow(poser);
}
//public void LoadHandPose(string poseName) {
// var pose = Resources.Load<HandPose>(poseName);
// if (pose != null) {
// // Update position / rotations
// foreach (var f in pose.Joints.OtherJoints) {
// Transform thisT = FindChildTransformByName(f.TransformName);
// if (thisT) {
// thisT.localPosition = f.LocalPosition;
// thisT.localRotation = f.LocalRotation;
// }
// }
// poser.CurrentPose = pose;
// poser.PoseName = poseName;
// }
//}
public Transform FindChildTransformByName(string transformName) {
Transform[] children = poser.GetComponentsInChildren<Transform>();
int childCount = children.Length;
for (int x = 0; x < childCount; x++) {
Transform child = children[x];
if (child != null && child.name == transformName) {
return child;
}
}
return poser.transform.Find(transformName);
}
}
}