You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
6.4 KiB
207 lines
6.4 KiB
|
1 month ago
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using Unity.VisualScripting;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace UDE_HAND_INTERACTION
|
||
|
|
{
|
||
|
|
[CustomEditor(typeof(HandStaticPose))]
|
||
|
|
public class HandStaticPoseEditor : Editor
|
||
|
|
{
|
||
|
|
private HandStaticPose _handStaticPose;
|
||
|
|
|
||
|
|
private VirtualHand virtualHand;
|
||
|
|
|
||
|
|
private Handedness _lastHandedness;
|
||
|
|
|
||
|
|
private const float GIZMO_SCALE = 0.007f;
|
||
|
|
|
||
|
|
SerializedProperty _virtualHand;
|
||
|
|
|
||
|
|
private void OnEnable()
|
||
|
|
{
|
||
|
|
_handStaticPose = target as HandStaticPose;
|
||
|
|
_virtualHand = serializedObject.FindProperty("_virtualHand");
|
||
|
|
AssignMissingGhostProvider();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnDisable()
|
||
|
|
{
|
||
|
|
DestroyGhost();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public override void OnInspectorGUI()
|
||
|
|
{
|
||
|
|
base.OnInspectorGUI();
|
||
|
|
GUILayout.Space(10);
|
||
|
|
if (GUILayout.Button("Create Visual Pose Model"))
|
||
|
|
{
|
||
|
|
_handStaticPose.CreateVisualModel();
|
||
|
|
}
|
||
|
|
if(_handStaticPose._virtualHand != null)
|
||
|
|
{
|
||
|
|
EditorGUILayout.PropertyField(_virtualHand);
|
||
|
|
}
|
||
|
|
DrawGhostMenu(_handStaticPose.HandPose);
|
||
|
|
serializedObject.ApplyModifiedProperties();
|
||
|
|
}
|
||
|
|
|
||
|
|
public void OnSceneGUI()
|
||
|
|
{
|
||
|
|
if (SceneView.currentDrawingSceneView == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (virtualHand == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
EditFingers();
|
||
|
|
}
|
||
|
|
private void DestroyGhost()
|
||
|
|
{
|
||
|
|
if (virtualHand == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
DestroyImmediate(virtualHand.gameObject);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void DrawGhostMenu(HandPose handPose)
|
||
|
|
{
|
||
|
|
if (virtualHand == null || _lastHandedness != handPose.Handedness)
|
||
|
|
{
|
||
|
|
RegenerateGhost();
|
||
|
|
}
|
||
|
|
_lastHandedness = handPose.Handedness;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void EditFingers()
|
||
|
|
{
|
||
|
|
DollHand puppet = virtualHand.GetComponent<DollHand>();
|
||
|
|
if (puppet != null && puppet.JointSets != null)
|
||
|
|
{
|
||
|
|
DrawBonesRotator(puppet.JointSets);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void DrawBonesRotator(List<HandJointsSet> bones)
|
||
|
|
{
|
||
|
|
bool anyChanged = false;
|
||
|
|
for (int i = 0; i < FingersData.HAND_JOINT_IDS.Length; i++)
|
||
|
|
{
|
||
|
|
bool changed = false;
|
||
|
|
HandJointId joint = FingersData.HAND_JOINT_IDS[i];
|
||
|
|
HandFinger finger = FingersData.JOINT_TO_FINGER[(int)joint];
|
||
|
|
|
||
|
|
if (_handStaticPose.HandPose.FingersFreedom[(int)finger] == JointFreedom.Free)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
HandJointsSet jointSet = bones.Find(b => b.id == joint);
|
||
|
|
if (jointSet == null)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
Transform transform = jointSet.transform;
|
||
|
|
transform.localRotation = jointSet.RotationOffset * _handStaticPose.HandPose.JointRotations[i];
|
||
|
|
|
||
|
|
float scale = GIZMO_SCALE * _handStaticPose.transform.lossyScale.x;
|
||
|
|
Handles.color = EditorConstants.PRIMARY_COLOR;
|
||
|
|
Quaternion entryRotation = transform.rotation;
|
||
|
|
Quaternion rotation = Handles.Disc(entryRotation, transform.position,
|
||
|
|
transform.forward, scale, false, 0);
|
||
|
|
if (rotation != entryRotation)
|
||
|
|
{
|
||
|
|
changed = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FingersData.HAND_JOINT_CAN_SPREAD[i])
|
||
|
|
{
|
||
|
|
Handles.color = EditorConstants.SECONDARY_COLOR;
|
||
|
|
Quaternion curlRotation = rotation;
|
||
|
|
rotation = Handles.Disc(curlRotation, transform.position,
|
||
|
|
transform.up, scale, false, 0);
|
||
|
|
if (rotation != curlRotation)
|
||
|
|
{
|
||
|
|
changed = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!changed)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
transform.rotation = rotation;
|
||
|
|
Undo.RecordObject(_handStaticPose, "Bone Rotation");
|
||
|
|
_handStaticPose.HandPose.JointRotations[i] = jointSet.TrackedRotation;
|
||
|
|
anyChanged = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (anyChanged)
|
||
|
|
{
|
||
|
|
EditorUtility.SetDirty(_handStaticPose);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RegenerateGhost()
|
||
|
|
{
|
||
|
|
DestroyGhost();
|
||
|
|
CreateGhost();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void CreateGhost()
|
||
|
|
{
|
||
|
|
if (_handStaticPose._HPResource == null || PrefabUtility.IsPartOfPrefabAsset(_handStaticPose))
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
Transform relativeTo = _handStaticPose.transform;
|
||
|
|
VirtualHand ghostPrototype = _handStaticPose._HPResource.GetHand(_handStaticPose.HandPose.Handedness);
|
||
|
|
virtualHand = Instantiate(ghostPrototype, relativeTo);
|
||
|
|
virtualHand.gameObject.hideFlags = HideFlags.HideAndDontSave;
|
||
|
|
Pose relativePose = _handStaticPose.transform.GetPose(Space.World);
|
||
|
|
Pose pose = PoseManager.GlobalPoseScaled(relativeTo, relativePose);
|
||
|
|
virtualHand.SetPose(_handStaticPose.HandPose, relativePose);
|
||
|
|
}
|
||
|
|
|
||
|
|
void AssignMissingGhostProvider()
|
||
|
|
{
|
||
|
|
if (_handStaticPose._HPResource != null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
TryGetDefaultResProvider(out _handStaticPose._HPResource);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool TryGetDefaultResProvider(out HandPerfabResource provider)
|
||
|
|
{
|
||
|
|
provider = null;
|
||
|
|
HandPerfabResource[] providers = Resources.FindObjectsOfTypeAll<HandPerfabResource>();
|
||
|
|
if (providers != null && providers.Length > 0)
|
||
|
|
{
|
||
|
|
provider = providers[0];
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
string[] assets = AssetDatabase.FindAssets($"t:{nameof(HandPerfabResource)}");
|
||
|
|
if (assets != null && assets.Length > 0)
|
||
|
|
{
|
||
|
|
string pathPath = AssetDatabase.GUIDToAssetPath(assets[0]);
|
||
|
|
provider = AssetDatabase.LoadAssetAtPath<HandPerfabResource>(pathPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
return provider != null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|