Pascal Serrarens 17741d862a First commit
2022-01-12 10:50:57 +01:00

606 lines
25 KiB
C#

using UnityEditor;
using UnityEngine;
namespace Passer {
using Humanoid;
[CanEditMultipleObjects]
[CustomEditor(typeof(FootTarget), true)]
public class FootTarget_Editor : Editor {
private FootTarget footTarget;
private HumanoidControl humanoid;
private TargetProps[] allProps;
#region Enable
public void OnEnable() {
footTarget = (FootTarget)target;
if (footTarget.humanoid == null)
footTarget.humanoid = GetHumanoid(footTarget);
humanoid = footTarget.humanoid;
if (humanoid == null)
return;
InitEditors();
footTarget.InitSensors();
InitConfiguration(footTarget);
InitSettings();
InitEvents();
}
private void InitEditors() {
allProps = new TargetProps[] {
#if hOPENVR && hVIVETRACKER && (UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX)
new ViveTracker_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hKINECT1
new Kinect1_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hKINECT2
new Kinect2_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hKINECT4
new Kinect4_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hORBBEC
new Astra_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hNEURON
new Neuron_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hOPTITRACK
new Optitrack_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hANTILATENCY
new Antilatency_Editor.FootTargetProps(serializedObject, footTarget),
#endif
#if hCUSTOM
new Custom_Editor.FootTargetProps(serializedObject, footTarget),
#endif
};
}
#endregion
#region Disable
public void OnDisable() {
if (humanoid == null) {
// This target is not connected to a humanoid, so we delete it
DestroyImmediate(footTarget, true);
return;
}
if (!Application.isPlaying) {
SetSensor2Target();
}
}
private void SetSensor2Target() {
foreach (TargetProps props in allProps)
props.SetSensor2Target();
}
#endregion
#region Inspector
public override void OnInspectorGUI() {
if (footTarget == null || humanoid == null)
return;
serializedObject.Update();
ControllerInspectors(footTarget);
ConfigurationInspector(footTarget);
SettingsInspector(footTarget);
EventsInspector();
serializedObject.ApplyModifiedProperties();
UpdateBones(footTarget);
}
public static FootTarget Inspector(FootTarget footTarget, string name) {
if (footTarget == null)
return footTarget;
EditorGUILayout.BeginHorizontal();
Transform defaultTargetTransform = footTarget.GetDefaultTarget(footTarget.humanoid);
Transform targetTransform = footTarget.transform ?? defaultTargetTransform;
GUIContent text = new GUIContent(
name,
"The transform controlling the " + name
);
targetTransform = (Transform)EditorGUILayout.ObjectField(text, targetTransform, typeof(Transform), true);
if (!Application.isPlaying) {
if (targetTransform == defaultTargetTransform && GUILayout.Button("Show", GUILayout.MaxWidth(60))) {
// Call static method CreateTarget on target
footTarget = (FootTarget)footTarget.GetType().GetMethod("CreateTarget").Invoke(null, new object[] { footTarget });
}
else if (targetTransform != footTarget.transform) {
footTarget = (FootTarget)footTarget.GetType().GetMethod("SetTarget").Invoke(null, new object[] { footTarget.humanoid, targetTransform, footTarget.isLeft });
}
}
EditorGUILayout.EndHorizontal();
return footTarget;
}
public static HumanoidControl GetHumanoid(HumanoidTarget target) {
HumanoidControl foundHumanoid = target.transform.GetComponentInParent<HumanoidControl>();
if (foundHumanoid != null)
return foundHumanoid;
HumanoidControl[] humanoids = GameObject.FindObjectsOfType<HumanoidControl>();
for (int i = 0; i < humanoids.Length; i++)
if (humanoids[i].leftFootTarget.transform == target.transform ||
humanoids[i].rightFootTarget.transform == target.transform)
foundHumanoid = humanoids[i];
return foundHumanoid;
}
#region Sensors
private static bool showControllers = true;
private void ControllerInspectors(FootTarget footTarget) {
showControllers = EditorGUILayout.Foldout(showControllers, "Controllers", true);
if (showControllers) {
EditorGUI.indentLevel++;
foreach (TargetProps props in allProps)
props.Inspector();
if (humanoid.animatorEnabled)
footTarget.legAnimator.enabled = EditorGUILayout.ToggleLeft("Procedural Animation", footTarget.legAnimator.enabled, GUILayout.MinWidth(80));
EditorGUI.indentLevel--;
}
}
#endregion
#region Configuration
private void InitConfiguration(FootTarget footTarget) {
if (footTarget.humanoid.avatarRig == null)
return;
InitUpperLegConfiguration(footTarget.upperLeg);
InitLowerLegConfiguration(footTarget.lowerLeg);
InitFootConfiguration(footTarget.foot);
InitToesConfiguration(footTarget.toes);
}
private static bool showConfiguration;
private void ConfigurationInspector(FootTarget footTarget) {
//if (!target.jointLimitations)
// return;
footTarget.RetrieveBones();
showConfiguration = EditorGUILayout.Foldout(showConfiguration, "Configuration", true);
if (showConfiguration) {
EditorGUI.indentLevel++;
UpperLegConfigurationInspector(ref footTarget.upperLeg, footTarget.isLeft);
LowerLegConfigurationInspector(ref footTarget.lowerLeg, footTarget.isLeft);
FootConfigurationInspector(ref footTarget.foot, footTarget.isLeft);
ToesConfigurationInspector(ref footTarget.toes, footTarget.isLeft);
EditorGUI.indentLevel--;
}
}
private void UpdateBones(FootTarget target) {
if (target.humanoid.avatarRig == null)
return;
UpdateUpperLegBones(target.upperLeg);
UpdateLowerLegBones(target.lowerLeg);
UpdateFootBones(target.foot);
UpdateToesBones(target.toes);
}
#region UpperLeg
//private string upperLegXname;
//private SerializedProperty upperLegMinX;
//private SerializedProperty upperLegMaxX;
//private string upperLegYname;
//private SerializedProperty upperLegMinY;
//private SerializedProperty upperLegMaxY;
//private string upperLegZname;
//private SerializedProperty upperLegMinZ;
//private SerializedProperty upperLegMaxZ;
private void InitUpperLegConfiguration(FootTarget.TargetedUpperLegBone upperLeg) {
//if (upperLeg.bone.transform == null)
// return;
//upperLegXname = upperLeg.bone.transform.name + "X";
//upperLegMinX = serializedObject.FindProperty("upperLeg.bone.minAngles.x");
//upperLegMaxX = serializedObject.FindProperty("upperLeg.bone.maxAngles.x");
//upperLegYname = upperLeg.bone.transform.name + "Y";
//upperLegMinY = serializedObject.FindProperty("upperLeg.bone.minAngles.y");
//upperLegMaxY = serializedObject.FindProperty("upperLeg.bone.maxAngles.y");
//upperLegZname = upperLeg.bone.transform.name + "Z";
//upperLegMinZ = serializedObject.FindProperty("upperLeg.bone.minAngles.z");
//upperLegMaxZ = serializedObject.FindProperty("upperLeg.bone.maxAngles.z");
}
private void UpperLegConfigurationInspector(ref FootTarget.TargetedUpperLegBone upperLeg, bool isLeft) {
if (upperLeg.bone.transform != null)
GUI.SetNextControlName(upperLeg.bone.transform.name + "00");
upperLeg.bone.transform = (Transform)EditorGUILayout.ObjectField("Upper Leg Bone", upperLeg.bone.transform, typeof(Transform), true);
if (upperLeg.bone.transform != null) {
EditorGUI.indentLevel++;
upperLeg.bone.jointLimitations = EditorGUILayout.Toggle("Joint Limitations", upperLeg.bone.jointLimitations);
if (upperLeg.bone.jointLimitations) {
upperLeg.bone.maxAngle = EditorGUILayout.Slider("Max Angle", upperLeg.bone.maxAngle, 0, 180);
}
//EditorGUILayout.BeginHorizontal();
//upperLeg.bone.maxAngle = EditorGUILayout.Slider("Max Angle", upperLeg.bone.maxAngle, 0, 180);
//if (GUILayout.Button("R", GUILayout.Width(20))) {
// upperLeg.bone.maxAngle = FootTarget.maxUpperLegAngle;
//}
//EditorGUILayout.EndHorizontal();
//if (isLeft) {
// Target_Editor.BoneAngleInspector(upperLegMinX, upperLegMaxX, FootTarget.minLeftUpperLegAngles.x, FootTarget.maxLeftUpperLegAngles.x, upperLegXname, "X Limits");
// Target_Editor.BoneAngleInspector(upperLegMinY, upperLegMaxY, FootTarget.minLeftUpperLegAngles.y, FootTarget.maxLeftUpperLegAngles.y, upperLegYname, "Y Limits");
// Target_Editor.BoneAngleInspector(upperLegMinZ, upperLegMaxZ, FootTarget.minLeftUpperLegAngles.z, FootTarget.maxLeftUpperLegAngles.z, upperLegZname, "Z Limits");
//} else {
// Target_Editor.BoneAngleInspector(upperLegMinX, upperLegMaxX, FootTarget.minRightUpperLegAngles.x, FootTarget.maxRightUpperLegAngles.x, upperLegXname, "X Limits");
// Target_Editor.BoneAngleInspector(upperLegMinY, upperLegMaxY, FootTarget.minRightUpperLegAngles.y, FootTarget.maxRightUpperLegAngles.y, upperLegYname, "Y Limits");
// Target_Editor.BoneAngleInspector(upperLegMinZ, upperLegMaxZ, FootTarget.minRightUpperLegAngles.z, FootTarget.maxRightUpperLegAngles.z, upperLegZname, "Z Limits");
//}
EditorGUI.indentLevel--;
}
}
private void UpdateUpperLegBones(FootTarget.TargetedUpperLegBone upperLeg) {
//if (upperLeg.bone.transform == null)
// return;
//upperLeg.bone.minAngles.x = upperLegMinX.floatValue;
//upperLeg.bone.maxAngles.x = upperLegMaxX.floatValue;
//upperLeg.bone.minAngles.y = upperLegMinY.floatValue;
//upperLeg.bone.maxAngles.y = upperLegMaxY.floatValue;
//upperLeg.bone.minAngles.z = upperLegMinZ.floatValue;
//upperLeg.bone.maxAngles.z = upperLegMaxZ.floatValue;
}
#endregion
#region LowerLeg
//private string lowerLegYname;
//private SerializedProperty lowerLegMinX;
//private SerializedProperty lowerLegMaxX;
private void InitLowerLegConfiguration(FootTarget.TargetedLowerLegBone lowerLeg) {
//if (lowerLeg.bone.transform == null)
// return;
//lowerLegYname = lowerLeg.bone.transform.name + "X";
//lowerLegMinX = serializedObject.FindProperty("lowerLeg.bone.minAngles.x");
//lowerLegMaxX = serializedObject.FindProperty("lowerLeg.bone.maxAngles.x");
}
private void LowerLegConfigurationInspector(ref FootTarget.TargetedLowerLegBone lowerLeg, bool isLeft) {
if (lowerLeg.bone.transform != null)
GUI.SetNextControlName(lowerLeg.bone.transform.name + "00");
lowerLeg.bone.transform = (Transform)EditorGUILayout.ObjectField("Lower Leg Bone", lowerLeg.bone.transform, typeof(Transform), true);
if (lowerLeg.bone.transform != null) {
EditorGUI.indentLevel++;
lowerLeg.bone.jointLimitations = EditorGUILayout.Toggle("Joint Limitations", lowerLeg.bone.jointLimitations);
if (lowerLeg.bone.jointLimitations) {
lowerLeg.bone.maxAngle = EditorGUILayout.Slider("Max Angle", lowerLeg.bone.maxAngle, 0, 180);
}
//EditorGUILayout.BeginHorizontal();
//lowerLeg.bone.maxAngle = EditorGUILayout.Slider("Max Angle", lowerLeg.bone.maxAngle, 0, 180);
//if (GUILayout.Button("R", GUILayout.Width(20))) {
// lowerLeg.bone.maxAngle = FootTarget.maxLowerLegAngle;
//}
//EditorGUILayout.EndHorizontal();
//if (isLeft)
// Target_Editor.BoneAngleInspector(lowerLegMinX, lowerLegMaxX, FootTarget.minLeftLowerLegAngles.x, FootTarget.maxLeftLowerLegAngles.x, lowerLegYname, "X Limits");
//else
// Target_Editor.BoneAngleInspector(lowerLegMinX, lowerLegMaxX, FootTarget.minRightLowerLegAngles.x, FootTarget.maxRightLowerLegAngles.x, lowerLegYname, "X Limits");
EditorGUI.indentLevel--;
}
}
private void UpdateLowerLegBones(FootTarget.TargetedLowerLegBone lowerLeg) {
//if (lowerLeg.bone.transform == null)
// return;
//lowerLeg.bone.minAngles.x = lowerLegMinX.floatValue;
//lowerLeg.bone.maxAngles.x = lowerLegMaxX.floatValue;
}
#endregion
#region Foot
//private string footXname;
//private SerializedProperty footMinX;
//private SerializedProperty footMaxX;
//private string footZname;
//private SerializedProperty footMinZ;
//private SerializedProperty footMaxZ;
private void InitFootConfiguration(FootTarget.TargetedFootBone foot) {
//if (foot.bone.transform == null)
// return;
//footXname = foot.bone.transform.name + "X";
//footMinX = serializedObject.FindProperty("foot.bone.minAngles.x");
//footMaxX = serializedObject.FindProperty("foot.bone.maxAngles.x");
//footZname = foot.bone.transform.name + "Z";
//footMinZ = serializedObject.FindProperty("foot.bone.minAngles.z");
//footMaxZ = serializedObject.FindProperty("foot.bone.maxAngles.z");
}
private void FootConfigurationInspector(ref FootTarget.TargetedFootBone foot, bool isLeft) {
if (foot.bone.transform != null)
GUI.SetNextControlName(foot.bone.transform.name + "00");
foot.bone.transform = (Transform)EditorGUILayout.ObjectField("Foot Bone", foot.bone.transform, typeof(Transform), true);
if (foot.bone.transform != null) {
EditorGUI.indentLevel++;
foot.bone.jointLimitations = EditorGUILayout.Toggle("Joint Limitations", foot.bone.jointLimitations);
if (foot.bone.jointLimitations) {
foot.bone.maxAngle = EditorGUILayout.Slider("Max Angle", foot.bone.maxAngle, 0, 180);
}
//EditorGUILayout.BeginHorizontal();
//foot.bone.maxAngle = EditorGUILayout.Slider("Max Angle", foot.bone.maxAngle, 0, 180);
//if (GUILayout.Button("R", GUILayout.Width(20))) {
// foot.bone.maxAngle = FootTarget.maxFootAngle;
//}
//EditorGUILayout.EndHorizontal();
//if (isLeft) {
// Target_Editor.BoneAngleInspector(footMinX, footMaxX, FootTarget.minLeftFootAngles.x, FootTarget.maxLeftFootAngles.x, footXname, "X Limits");
// Target_Editor.BoneAngleInspector(footMinZ, footMaxZ, FootTarget.minLeftFootAngles.z, FootTarget.maxLeftFootAngles.z, footZname, "Z Limits");
//} else {
// Target_Editor.BoneAngleInspector(footMinX, footMaxX, FootTarget.minRightFootAngles.x, FootTarget.maxRightFootAngles.x, footXname, "X Limits");
// Target_Editor.BoneAngleInspector(footMinZ, footMaxZ, FootTarget.minRightFootAngles.z, FootTarget.maxRightFootAngles.z, footZname, "Z Limtis");
//}
EditorGUI.indentLevel--;
}
}
private void UpdateFootBones(FootTarget.TargetedFootBone foot) {
//if (foot.bone.transform == null)
// return;
//foot.bone.minAngles.x = footMinX.floatValue;
//foot.bone.maxAngles.x = footMaxX.floatValue;
//foot.bone.minAngles.z = footMinZ.floatValue;
//foot.bone.maxAngles.z = footMaxZ.floatValue;
}
#endregion
#region Toes
//private string toesXname;
//private SerializedProperty toesMinX;
//private SerializedProperty toesMaxX;
private void InitToesConfiguration(FootTarget.TargetedToesBone toes) {
//if (toes.bone.transform == null)
// return;
//toesXname = toes.bone.transform.name + "X";
//toesMinX = serializedObject.FindProperty("toes.bone.minAngles.x");
//toesMaxX = serializedObject.FindProperty("toes.bone.maxAngles.x");
}
private void ToesConfigurationInspector(ref FootTarget.TargetedToesBone toes, bool isLeft) {
if (toes.bone.transform != null)
GUI.SetNextControlName(toes.bone.transform.name + "00");
toes.bone.transform = (Transform)EditorGUILayout.ObjectField("Toes Bone", toes.bone.transform, typeof(Transform), true);
if (toes.bone.transform != null) {
EditorGUI.indentLevel++;
toes.bone.jointLimitations = EditorGUILayout.Toggle("Joint Limitations", toes.bone.jointLimitations);
if (toes.bone.jointLimitations) {
toes.bone.maxAngle = EditorGUILayout.Slider("Max Angle", toes.bone.maxAngle, 0, 180);
}
//EditorGUILayout.BeginHorizontal();
//toes.bone.maxAngle = EditorGUILayout.Slider("Max Angle", toes.bone.maxAngle, 0, 180);
//if (GUILayout.Button("R", GUILayout.Width(20))) {
// toes.bone.maxAngle = FootTarget.maxToesAngle;
//}
//EditorGUILayout.EndHorizontal();
//if (isLeft)
// Target_Editor.BoneAngleInspector(toesMinX, toesMaxX, FootTarget.minLeftToesAngles.x, FootTarget.maxLeftToesAngles.x, toesXname, "X Limits");
//else
// Target_Editor.BoneAngleInspector(toesMinX, toesMaxX, FootTarget.minRightToesAngles.x, FootTarget.maxRightToesAngles.x, toesXname, "X Limits");
EditorGUI.indentLevel--;
}
}
private void UpdateToesBones(FootTarget.TargetedToesBone toes) {
//if (toes.bone.transform == null)
// return;
//toes.bone.minAngles.x = toesMinX.floatValue;
//toes.bone.maxAngles.x = toesMaxX.floatValue;
}
#endregion
#endregion
#region Settings
private SerializedProperty rotationSpeedLimitationProp;
private SerializedProperty slidePreventionProp;
private void InitSettings() {
rotationSpeedLimitationProp = serializedObject.FindProperty("rotationSpeedLimitation");
slidePreventionProp = serializedObject.FindProperty("slidePrevention");
}
private static bool showSettings;
private void SettingsInspector(FootTarget footTarget) {
showSettings = EditorGUILayout.Foldout(showSettings, "Settings", true);
if (showSettings) {
EditorGUI.indentLevel++;
//footTarget.jointLimitations = EditorGUILayout.Toggle("Joint Limitations", footTarget.jointLimitations);
bool showRealObjects = EditorGUILayout.Toggle("Show Real Objects", footTarget.showRealObjects);
if (showRealObjects != footTarget.showRealObjects) {
footTarget.ShowControllers(showRealObjects);
footTarget.showRealObjects = showRealObjects;
}
rotationSpeedLimitationProp.boolValue = EditorGUILayout.Toggle("Rotation Speed Limitation", rotationSpeedLimitationProp.boolValue);
slidePreventionProp.boolValue = EditorGUILayout.Toggle("Slide Prevention", slidePreventionProp.boolValue);
EditorGUI.indentLevel--;
}
}
#endregion
#region Events
protected SerializedProperty groundEventProp;
protected virtual void InitEvents() {
groundEventProp = serializedObject.FindProperty("groundEvent");
}
protected int selectedEventSource = -1;
protected int selectedEvent;
protected bool showEvents;
protected virtual void EventsInspector() {
showEvents = EditorGUILayout.Foldout(showEvents, "Events", true);
if (showEvents) {
EditorGUI.indentLevel++;
GameObjectEvent_Editor.EventInspector(groundEventProp, footTarget.groundEvent, ref selectedEventSource, ref selectedEvent);
//EditorGUILayout.BeginHorizontal();
////Labels
//EditorGUILayout.BeginVertical(GUILayout.MinWidth(110));
//GUILayout.Space(3);
//EditorGUILayout.LabelField("Ground", GUILayout.Width(110));
//EditorGUILayout.EndVertical();
//// Buttons
//string[] buttonTexts = new string[1];
//buttonTexts[0] = Event.GetInputButtonLabel(footTarget.groundEvent.gameObjectEvent);
//int oldFontSize = GUI.skin.button.fontSize;
//GUI.skin.button.fontSize = 9;
//selectedEventSource = GUILayout.SelectionGrid(selectedEventSource, buttonTexts, 1);
//GUI.skin.button.fontSize = oldFontSize;
//EditorGUILayout.EndHorizontal();
//// Details
//GUIStyle style = new GUIStyle(GUI.skin.label) {
// fontStyle = FontStyle.Bold
//};
//EditorGUILayout.LabelField("Details", style, GUILayout.ExpandWidth(true));
//EditorGUI.indentLevel++;
//EventDetails(selectedEventSource);
//EditorGUI.indentLevel--;
EditorGUI.indentLevel--;
}
}
//protected void EventDetails(int selectedInputEvent) {
// switch (selectedInputEvent) {
// case 0:
// GameObjectEvent_Editor.DetailsInspector(groundEventProp, "Ground");
// break;
// }
//}
#endregion
#endregion
#region Scene
public void OnSceneGUI() {
if (footTarget == null || humanoid == null)
return;
if (Application.isPlaying)
return;
if (humanoid.pose != null) {
if (humanoid.editPose)
humanoid.pose.UpdatePose(humanoid);
else {
humanoid.pose.Show(humanoid);
footTarget.CopyRigToTarget();
}
}
// update the target rig from the current foot target
footTarget.CopyTargetToRig();
// update the avatar bones from the target rig
humanoid.UpdateMovements();
// match the target rig with the new avatar pose
humanoid.MatchTargetsToAvatar();
// and update all target to match the target rig
humanoid.CopyRigToTargets();
// Update the sensors to match the updated targets
humanoid.UpdateSensorsFromTargets();
}
#endregion
public abstract class TargetProps {
public SerializedProperty enabledProp;
public SerializedProperty sensorTransformProp;
public SerializedProperty sensor2TargetPositionProp;
public SerializedProperty sensor2TargetRotationProp;
public FootTarget footTarget;
public LegSensor sensor;
public TargetProps(SerializedObject serializedObject, LegSensor _sensor, FootTarget _footTarget, string unitySensorName) {
enabledProp = serializedObject.FindProperty(unitySensorName + ".enabled");
sensorTransformProp = serializedObject.FindProperty(unitySensorName + ".sensorTransform");
sensor2TargetPositionProp = serializedObject.FindProperty(unitySensorName + ".sensor2TargetPosition");
sensor2TargetRotationProp = serializedObject.FindProperty(unitySensorName + ".sensor2TargetRotation");
footTarget = _footTarget;
sensor = _sensor;
sensor.Init(footTarget);
}
public virtual void SetSensor2Target() {
if (sensor.sensorTransform == null)
return;
sensor2TargetRotationProp.quaternionValue = Quaternion.Inverse(sensor.sensorTransform.rotation) * footTarget.foot.target.transform.rotation;
sensor2TargetPositionProp.vector3Value = -footTarget.foot.target.transform.InverseTransformPoint(sensor.sensorTransform.position);
}
public abstract void Inspector();
}
}
}