841 lines
29 KiB
C#

using UnityEngine;
using UnityEditor;
namespace BioIK {
[CustomEditor(typeof(BioIK))]
public class BioIKEditor : Editor {
public BioIK Target;
public Transform TargetTransform;
private Color Color1 = Color.white;
//private Color Color2 = Color.black;
private Color Color3 = new Color(0.6f, 0.6f, 0.6f, 1f);
private Color Color4 = new Color(0.3f, 0.8f, 0.8f, 1f);
private Color Color5 = new Color(1f, 0.7f, 0.3f, 1f);
private Color Color6 = new Color(0.9f, 0.3f, 0.9f, 1f);
private Color Color7 = new Color(1.0f, 0.3f, 0.3f, 1f);
private Color Color8 = new Color(0.3f, 0.6f, 0.6f, 1f);
private Color Color9 = new Color(0.4f, 0.9f, 0.4f, 1f);
//private Color Color10 = new Color(1f, 0.5f, 1f, 1f);
private Color Color11 = new Color(0.3f, 0.3f, 0.3f, 1f);
//private Color Color12 = new Color(0.9f, 0.6f, 0.9f, 1f);
private Color Color13 = new Color(0.5f, 0.5f, 0.5f, 1f);
private Color Color14 = new Color(0.75f, 0.75f, 0.75f, 1f);
private bool ChosingObjectiveType = false;
private bool IsPlaying = false;
private bool IsEnabled = false;
private int DoF;
void Awake() {
EditorApplication.playmodeStateChanged += PlaymodeStateChanged;
Target = (BioIK)target;
TargetTransform = Target.transform;
Target.Refresh(false);
DoF = 0;
//MakeVisible(TargetTransform);
//MakeInvisible(TargetTransform);
}
void OnEnable() {
IsEnabled = true;
}
void OnDisable() {
IsEnabled = false;
}
private void MakeVisible(Transform t) {
if(t.GetComponent<BioSegment>()) {
t.GetComponent<BioSegment>().hideFlags = HideFlags.None;
}
foreach(BioObjective o in t.GetComponents<BioObjective>()) {
o.hideFlags = HideFlags.None;
}
if(t.GetComponent<BioJoint>()) {
t.GetComponent<BioJoint>().hideFlags = HideFlags.None;
}
for(int i=0; i<t.childCount; i++) {
MakeVisible(t.GetChild(i));
}
}
private void MakeInvisible(Transform t) {
if(t.GetComponent<BioSegment>()) {
t.GetComponent<BioSegment>().hideFlags = HideFlags.HideInInspector;
}
foreach(BioObjective o in t.GetComponents<BioObjective>()) {
o.hideFlags = HideFlags.HideInInspector;
}
if(t.GetComponent<BioJoint>()) {
t.GetComponent<BioJoint>().hideFlags = HideFlags.HideInInspector;
}
for(int i=0; i<t.childCount; i++) {
MakeInvisible(t.GetChild(i));
}
}
void OnDestroy() {
if(
Target == null
&&
TargetTransform != null
&&
!IsPlaying
&&
!IsEnabled
&&
!EditorApplication.isPlayingOrWillChangePlaymode
) {
Utility.Cleanup(TargetTransform);
}
}
private void PlaymodeStateChanged() {
IsPlaying = Application.isPlaying;
}
public override void OnInspectorGUI() {
Undo.RecordObject(Target, Target.name);
SetGUIColor(Color3);
using(new EditorGUILayout.VerticalScope ("Button")) {
SetGUIColor(Color5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox(" Settings ", MessageType.None);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
//SetGUIColor(Color1);
//Target.SolveInEditMode = EditorGUILayout.Toggle("Solve In Edit Mode", Target.SolveInEditMode);
SetGUIColor(Color1);
Target.SetThreading(EditorGUILayout.Toggle("Use Threading", Target.GetThreading()));
SetGUIColor(Color1);
Target.SetGenerations(EditorGUILayout.IntField("Generations", Target.GetGenerations()));
SetGUIColor(Color1);
Target.SetPopulationSize(EditorGUILayout.IntField("Individuals", Target.GetPopulationSize()));
SetGUIColor(Color1);
Target.SetElites(EditorGUILayout.IntField("Elites", Target.GetElites()));
SetGUIColor(Color1);
Target.Smoothing = EditorGUILayout.Slider("Smoothing", Target.Smoothing, 0f, 1f);
SetGUIColor(Color1);
Target.AnimationWeight = EditorGUILayout.Slider("Animation Weight", Target.AnimationWeight, 0f, 1f);
SetGUIColor(Color1);
Target.AnimationBlend = EditorGUILayout.Slider("Animation Blend", Target.AnimationBlend, 0f, 1f);
SetGUIColor(Color1);
Target.MotionType = (MotionType)EditorGUILayout.EnumPopup("Motion Type", Target.MotionType);
if(Target.MotionType == MotionType.Realistic) {
Target.MaximumVelocity = EditorGUILayout.FloatField("Maximum Velocity", Target.MaximumVelocity);
Target.MaximumAcceleration = EditorGUILayout.FloatField("Maximum Acceleration", Target.MaximumAcceleration);
}
SetGUIColor(Color1);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button(" Reset Posture ")) {
Target.ResetPosture(Target.Root);
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
SetGUIColor(Color3);
using(new EditorGUILayout.VerticalScope ("Button")) {
SetGUIColor(Color5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox(" Character ", MessageType.None);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
//SetGUIColor(Color5);
//EditorGUILayout.HelpBox("Degree of Freedom: " + new Model(Target).GetDoF() + " / " + DoF, MessageType.None);
int maxIndent = 0;
ComputeMaxIndentLevel(Target.transform, 0, ref maxIndent);
Target.Scroll = EditorGUILayout.BeginScrollView(Target.Scroll, GUILayout.Height(500f));
InspectBody(Target.FindSegment(Target.transform), 0, maxIndent);
EditorGUILayout.EndScrollView();
}
SetGUIColor(Color1);
if(Target != null) {
EditorUtility.SetDirty(Target);
}
}
private void InspectBody(BioSegment segment, int indent, int maxIndent) {
SetGUIColor(Color11);
using(new EditorGUILayout.VerticalScope ("Box")) {
EditorGUILayout.BeginHorizontal();
if(Target.SelectedSegment != segment) {
if(indent > 0) {
SetGUIColor(Color13);
using(new EditorGUILayout.VerticalScope ("Box")) {
int width = 10*(indent-1);
EditorGUILayout.LabelField("", GUILayout.Width(width));
}
}
}
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
if(segment == Target.SelectedSegment) {
SetGUIColor(Color5);
} else {
SetGUIColor(Color.Lerp(Color4, Color8, (float)indent / (float)maxIndent));
}
if(GUILayout.Button(segment.Transform.name, GUILayout.Height(25f), GUILayout.ExpandWidth(true))) {
if(Target.SelectedSegment == segment) {
Target.SelectedSegment = null;
ChosingObjectiveType = false;
} else {
Target.SelectedSegment = segment;
}
}
EditorGUILayout.EndHorizontal();
if(Target.SelectedSegment == segment) {
InspectSegment(segment);
} else {
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(segment.Joint != null) {
SetGUIColor(Color6);
GUILayout.Box(" Joint ");
}
foreach(BioObjective objective in segment.Objectives) {
SetGUIColor(Color9);
GUILayout.Box(" " + objective.GetObjectiveType().ToString() + " ");
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
}
for(int i=0; i<segment.Childs.Length; i++) {
InspectBody(segment.Childs[i], indent+1, maxIndent);
}
}
private void InspectSegment(BioSegment segment) {
Undo.RecordObject(segment, segment.name);
SetGUIColor(Color13);
using(new EditorGUILayout.VerticalScope ("Box")) {
SetGUIColor(Color4);
Vector3 A = segment.Parent == null ? segment.GetAnchoredPosition() : segment.Parent.GetAnchoredPosition();
Vector3 B = segment.GetAnchoredPosition();
EditorGUILayout.HelpBox("Link Length: " + Vector3.Distance(A,B), MessageType.None);
SetGUIColor(Color6);
using(new EditorGUILayout.VerticalScope ("Box")) {
if(segment.Joint == null) {
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
SetGUIColor(Color1);
if(GUILayout.Button("Add Joint")) {
segment.AddJoint();
}
} else {
InspectJoint(segment.Joint);
}
}
}
for(int i=0; i<segment.Objectives.Length; i++) {
SetGUIColor(Color13);
using(new EditorGUILayout.VerticalScope ("Box")) {
SetGUIColor(Color9);
using(new EditorGUILayout.VerticalScope ("Box")) {
InspectObjective(segment.Objectives[i]);
}
}
}
SetGUIColor(Color13);
using(new EditorGUILayout.VerticalScope ("Box")) {
SetGUIColor(Color9);
using(new EditorGUILayout.VerticalScope ("Box")) {
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
SetGUIColor(ChosingObjectiveType ? Color14 : Color1);
if(GUILayout.Button("Add Objective")) {
ChosingObjectiveType = !ChosingObjectiveType;
}
if(ChosingObjectiveType) {
SetGUIColor(Color8);
using(new EditorGUILayout.VerticalScope ("Box")) {
int count = System.Enum.GetValues(typeof(ObjectiveType)).Length;
string[] names = System.Enum.GetNames(typeof(ObjectiveType));
for(int i=0; i<count; i++) {
SetGUIColor(Color1);
if(GUILayout.Button(names[i])) {
ChosingObjectiveType = false;
segment.AddObjective((ObjectiveType)i);
}
}
}
}
}
}
if(segment != null) {
EditorUtility.SetDirty(segment);
}
}
private void InspectJoint(BioJoint joint) {
Undo.RecordObject(joint, joint.name);
SetGUIColor(Color13);
using(new EditorGUILayout.VerticalScope ("Box")) {
SetGUIColor(Color5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox(" Joint ", MessageType.None);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
SetGUIColor(Color1);
joint.enabled = EditorGUILayout.Toggle("Enabled", joint.enabled);
SetGUIColor(Color4);
EditorGUILayout.HelpBox("Geometry", MessageType.None);
SetGUIColor(Color1);
joint.JointType = (JointType)EditorGUILayout.EnumPopup("Joint Type", joint.JointType);
SetGUIColor(Color1);
joint.SetAnchor(EditorGUILayout.Vector3Field("Anchor", joint.GetAnchor()));
SetGUIColor(Color1);
joint.SetOrientation(EditorGUILayout.Vector3Field("Orientation", joint.GetOrientation()));
SetGUIColor(Color4);
EditorGUILayout.HelpBox("Default Frame", MessageType.None);
SetGUIColor(Color1);
Vector3 defaultPosition = EditorGUILayout.Vector3Field("Position", joint.GetDefaultPosition());
SetGUIColor(Color1);
Quaternion defaultRotation = Quaternion.Euler(EditorGUILayout.Vector3Field("Rotation", joint.GetDefaultRotation().eulerAngles));
joint.SetDefaultFrame(defaultPosition, defaultRotation);
InspectMotion(joint.X, " X Motion ");
InspectMotion(joint.Y, " Y Motion ");
InspectMotion(joint.Z, " Z Motion ");
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
SetGUIColor(Color7);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button("Remove", GUILayout.Width(100f))) {
joint.Remove();
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
if(joint != null) {
joint.PrecaptureAnimation();
joint.PostcaptureAnimation();
joint.UpdateData();
joint.ProcessMotion();
EditorUtility.SetDirty(joint);
}
}
private void InspectMotion(BioJoint.Motion motion, string name) {
SetGUIColor(Color8);
using(new EditorGUILayout.VerticalScope ("Box")) {
SetGUIColor(Color5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox(name, MessageType.None);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
if(motion.IsEnabled()) {
SetGUIColor(Color1);
motion.Constrained = EditorGUILayout.Toggle("Constrained", motion.Constrained);
if(motion.Constrained) {
SetGUIColor(Color1);
motion.SetLowerLimit(EditorGUILayout.DoubleField("Lower Limit", motion.GetLowerLimit()));
SetGUIColor(Color1);
motion.SetUpperLimit(EditorGUILayout.DoubleField("Upper Limit", motion.GetUpperLimit()));
SetGUIColor(Color1);
motion.SetTargetValue(EditorGUILayout.Slider("Target Value", (float)motion.GetTargetValue(), (float)motion.GetLowerLimit(), (float)motion.GetUpperLimit()));
} else {
SetGUIColor(Color1);
motion.SetTargetValue(EditorGUILayout.DoubleField("Target Value", motion.GetTargetValue()));
}
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
SetGUIColor(Color1);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button("Disable", GUILayout.Width(250f), GUILayout.Height(20f))) {
motion.SetEnabled(false);
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
} else {
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
SetGUIColor(Color1);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button("Enable", GUILayout.Width(250f), GUILayout.Height(20f))) {
motion.SetEnabled(true);
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
}
}
private void InspectObjective(BioObjective objective) {
Undo.RecordObject(objective, objective.name);
SetGUIColor(Color13);
using(new EditorGUILayout.VerticalScope ("Box")) {
SetGUIColor(Color5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox(" Objective (" + objective.GetObjectiveType().ToString() + ") ", MessageType.None);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
SetGUIColor(Color1);
objective.enabled = EditorGUILayout.Toggle("Enabled", objective.enabled);
SetGUIColor(Color1);
objective.Weight = EditorGUILayout.DoubleField("Weight", objective.Weight);
switch(objective.GetObjectiveType()) {
case ObjectiveType.Position:
InspectPosition((Position)objective);
break;
case ObjectiveType.Orientation:
InspectOrientation((Orientation)objective);
break;
case ObjectiveType.LookAt:
InspectLookAt((LookAt)objective);
break;
case ObjectiveType.Distance:
InspectDistance((Distance)objective);
break;
case ObjectiveType.JointValue:
InspectJointValue((JointValue)objective);
break;
case ObjectiveType.Displacement:
InspectDisplacement((Displacement)objective);
break;
case ObjectiveType.Projection:
InspectProjection((Projection)objective);
break;
}
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
SetGUIColor(Color7);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if(GUILayout.Button("Remove", GUILayout.Width(100f))) {
objective.Remove();
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
if(objective != null) {
EditorUtility.SetDirty(objective);
}
}
private void InspectPosition(Position objective) {
SetGUIColor(Color1);
objective.SetTargetTransform(EditorGUILayout.ObjectField("Target Transform", objective.GetTargetTransform(), typeof(Transform), true) as Transform);
SetGUIColor(Color1);
objective.SetTargetPosition(EditorGUILayout.Vector3Field("Target Position", objective.GetTargetPosition()));
SetGUIColor(Color1);
objective.SetMaximumError(EditorGUILayout.DoubleField("Maximum Error", objective.GetMaximumError()));
}
private void InspectOrientation(Orientation objective) {
SetGUIColor(Color1);
objective.SetTargetTransform(EditorGUILayout.ObjectField("Target Transform", objective.GetTargetTransform(), typeof(Transform), true) as Transform);
SetGUIColor(Color1);
objective.SetTargetRotation(EditorGUILayout.Vector3Field("Target Rotation", objective.GetTargetRotattion()));
SetGUIColor(Color1);
objective.SetMaximumError(EditorGUILayout.DoubleField("Maximum Error", objective.GetMaximumError()));
}
private void InspectLookAt(LookAt objective) {
SetGUIColor(Color1);
objective.SetTargetTransform(EditorGUILayout.ObjectField("Target Transform", objective.GetTargetTransform(), typeof(Transform), true) as Transform);
SetGUIColor(Color1);
objective.SetTargetPosition(EditorGUILayout.Vector3Field("Target Position", objective.GetTargetPosition()));
SetGUIColor(Color1);
objective.SetViewingDirection(EditorGUILayout.Vector3Field("Viewing Direction", objective.GetViewingDirection()));
SetGUIColor(Color1);
objective.SetMaximumError(EditorGUILayout.DoubleField("Maximum Error", objective.GetMaximumError()));
}
private void InspectDistance(Distance objective) {
SetGUIColor(Color1);
objective.SetRadius(EditorGUILayout.DoubleField("Radius", objective.GetRadius()));
SetGUIColor(Color1);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox("Points", MessageType.None);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
DistancePoint[] points = objective.GetPoints();
for(int i=0; i<points.Length; i++) {
SetGUIColor(Color8);
using(new EditorGUILayout.VerticalScope ("Box")) {
SetGUIColor(Color1);
points[i].SetTargetTransform(EditorGUILayout.ObjectField("Target", points[i].Target, typeof(Transform), true) as Transform);
SetGUIColor(Color1);
points[i].SetRadius(EditorGUILayout.DoubleField("Radius", points[i].Radius));
}
}
SetGUIColor(Color8);
if(GUILayout.Button("+")) {
objective.AddPoint();
}
SetGUIColor(Color8);
if(GUILayout.Button("-")) {
objective.RemovePoint();
}
}
private void InspectJointValue(JointValue objective) {
SetGUIColor(Color1);
objective.SetTargetValue(EditorGUILayout.DoubleField("Target Value", objective.GetTargetValue()));
SetGUIColor(Color1);
objective.SetXMotion(EditorGUILayout.Toggle("X Motion", objective.IsXMotion()));
SetGUIColor(Color1);
objective.SetYMotion(EditorGUILayout.Toggle("Y Motion", objective.IsYMotion()));
SetGUIColor(Color1);
objective.SetZMotion(EditorGUILayout.Toggle("Z Motion", objective.IsZMotion()));
}
private void InspectDisplacement(Displacement objective) {
}
private void InspectProjection(Projection objective) {
SetGUIColor(Color1);
objective.SetTargetTransform(EditorGUILayout.ObjectField("Target Transform", objective.GetTargetTransform(), typeof(Transform), true) as Transform);
SetGUIColor(Color1);
objective.SetTargetPosition(EditorGUILayout.Vector3Field("Target Position", objective.GetTargetPosition()));
SetGUIColor(Color1);
objective.SetTargetRotation(EditorGUILayout.Vector3Field("Target Rotation", objective.GetTargetRotation()));
SetGUIColor(Color1);
objective.SetNormal(EditorGUILayout.Vector3Field("Projection Normal", objective.GetNormal()));
SetGUIColor(Color1);
objective.SetLength(EditorGUILayout.FloatField("Projection Length", objective.GetLength()));
SetGUIColor(Color1);
objective.SetSensitivity(EditorGUILayout.Slider("Projection Sensitivitiy", objective.GetSensitivity(), 0f, 1f));
SetGUIColor(Color1);
objective.SetMaximumError(EditorGUILayout.DoubleField("Maximum Error", objective.GetMaximumError()));
}
public void OnSceneGUI() {
DoF = 0;
DrawSkeleton(Target.FindSegment(Target.transform));
DrawSetup(Target.FindSegment(Target.transform), false);
if(Target.SelectedSegment != null) {
DrawSegment(Target.SelectedSegment, true);
}
}
private bool StopDraw(BioSegment segment) {
if(segment.Parent == null) {
return false;
}
return false;
//return segment.Parent.name == "Kopf" && segment.name != "Head" && segment.name != "Ohr_R" && segment.name != "Ohr_L" || segment.name == "Ohr_L_end" || segment.name == "Ohr_R_end";
}
private void DrawSkeleton(BioSegment segment) {
if(!StopDraw(segment)) {
if(segment.Parent != null) {
DrawLine(segment.Parent.GetAnchoredPosition(), segment.GetAnchoredPosition(), 5f, Color.cyan);
}
for(int i=0; i<segment.Childs.Length; i++) {
DrawSkeleton(segment.Childs[i]);
}
}
}
private void DrawSetup(BioSegment segment, bool final) {
if(!StopDraw(segment)) {
DrawSegment(segment, final);
for(int i=0; i<segment.Childs.Length; i++) {
DrawSetup(segment.Childs[i], final);
}
}
}
private void DrawSegment(BioSegment segment, bool final) {
Vector3 P = segment.GetAnchoredPosition();
if(Target.SelectedSegment == segment && final) {
DrawSphere(P, 0.25f, new Color(0f, 0f, 0f, 0.4f));
DrawSphere(P, 0.02f, Color5);
} else if(Target.SelectedSegment != segment) {
DrawSphere(P, 0.02f, Color.cyan);
}
if(segment.Joint != null) {
DrawJoint(segment.Joint, final);
}
for(int i=0; i<segment.Objectives.Length; i++) {
DrawObjective(segment.Objectives[i], final);
}
}
private void DrawJoint(BioJoint joint, bool final) {
if(!final) {
DoF += joint.GetDoF();
}
//DrawDottedLine(joint.Segment.Transform.position, joint.GetAnchorInWorldSpace(), 5f, Color.magenta);
DrawCube(joint.GetAnchorInWorldSpace(), joint.Segment.Transform.rotation * Quaternion.Euler(joint.GetOrientation()), 0.025f, Color.magenta);
DrawMotion(joint.X, Color.red, final);
DrawMotion(joint.Y, Color.green, final);
DrawMotion(joint.Z, Color.blue, final);
}
private void DrawMotion(BioJoint.Motion motion, Color color, bool final) {
if(Target.SelectedSegment == motion.Joint.Segment && final) {
DrawArrow(motion.Joint.GetAnchorInWorldSpace(), motion.Joint.Segment.Transform.rotation * Quaternion.LookRotation(motion.Axis), 0.125f, motion.IsEnabled() ? color : Color.grey);
if(!motion.IsEnabled() || !motion.Constrained) {
return;
}
if(motion.Joint.JointType == JointType.Rotational) {
if(motion == motion.Joint.X) {
DrawSolidArc(
motion.Joint.GetAnchorInWorldSpace(),
motion.Joint.Segment.Transform.rotation * motion.Axis,
Quaternion.AngleAxis((float)motion.GetLowerLimit(), motion.Joint.Segment.Transform.rotation * motion.Axis) * motion.Joint.Segment.Transform.rotation * motion.Joint.Y.Axis,
(float)motion.GetUpperLimit() - (float)motion.GetLowerLimit(),
0.125f,
new Color(1f, 0f, 0f, 0.25f)
);
}
if(motion == motion.Joint.Y) {
DrawSolidArc(
motion.Joint.GetAnchorInWorldSpace(),
motion.Joint.Segment.Transform.rotation * motion.Axis,
Quaternion.AngleAxis((float)motion.GetLowerLimit(), motion.Joint.Segment.Transform.rotation * motion.Axis) * motion.Joint.Segment.Transform.rotation * motion.Joint.Z.Axis,
(float)motion.GetUpperLimit() - (float)motion.GetLowerLimit(),
0.125f,
new Color(0f, 1f, 0f, 0.25f)
);
}
if(motion == motion.Joint.Z) {
DrawSolidArc(
motion.Joint.GetAnchorInWorldSpace(),
motion.Joint.Segment.Transform.rotation * motion.Axis,
Quaternion.AngleAxis((float)motion.GetLowerLimit(), motion.Joint.Segment.Transform.rotation * motion.Axis) * motion.Joint.Segment.Transform.rotation * motion.Joint.X.Axis,
(float)motion.GetUpperLimit() - (float)motion.GetLowerLimit(),
0.125f,
new Color(0f, 0f, 1f, 0.25f)
);
}
}
if(motion.Joint.JointType == JointType.Translational) {
Vector3 A = motion.Joint.GetAnchorInWorldSpace() + (float)motion.GetLowerLimit() * (motion.Joint.Segment.Transform.rotation * motion.Axis);
Vector3 B = motion.Joint.GetAnchorInWorldSpace() + (float)motion.GetUpperLimit() * (motion.Joint.Segment.Transform.rotation * motion.Axis);
Color c = Color.white;
if(motion == motion.Joint.X) {
c = Color.red;
}
if(motion == motion.Joint.Y) {
c = Color.green;
}
if(motion == motion.Joint.Z) {
c = Color.blue;
}
DrawLine(A, B, 3f, c);
DrawCube(A, motion.Joint.Segment.Transform.rotation, 0.0125f, new Color(c.r, c.g, c.b, 0.5f));
DrawCube(B, motion.Joint.Segment.Transform.rotation, 0.0125f, new Color(c.r, c.g, c.b, 0.5f));
}
} else if(Target.SelectedSegment != motion.Joint.Segment) {
DrawArrow(motion.Joint.GetAnchorInWorldSpace(), motion.Joint.Segment.Transform.rotation * Quaternion.LookRotation(motion.Axis), 0.05f, motion.IsEnabled() ? color : Color.clear);
}
}
private void DrawObjective(BioObjective objective, bool selected) {
if(!selected) {
return;
}
switch(objective.GetObjectiveType()) {
case ObjectiveType.Position:
DrawPosition((Position)objective);
break;
case ObjectiveType.Orientation:
DrawOrientation((Orientation)objective);
break;
case ObjectiveType.LookAt:
DrawLookAt((LookAt)objective);
break;
case ObjectiveType.Distance:
DrawDistance((Distance)objective);
break;
case ObjectiveType.JointValue:
DrawJointValue((JointValue)objective);
break;
case ObjectiveType.Displacement:
DrawDisplacement((Displacement)objective);
break;
case ObjectiveType.Projection:
DrawProjection((Projection)objective);
break;
}
}
private void DrawPosition(Position objective) {
DrawSphere(objective.GetTargetPosition(), 0.1f, new Color(1f, 0f, 0f, 0.75f));
Handles.Label(objective.GetTargetPosition(), "Target");
}
private void DrawOrientation(Orientation objective) {
Quaternion rotation = Quaternion.Euler(objective.GetTargetRotattion());
Vector3 right = rotation * Vector3.right;
Vector3 up = rotation * Vector3.up;
Vector3 forward = rotation * Vector3.forward;
float length = 0.1f;
DrawLine(objective.Segment.Transform.position - length * right, objective.Segment.Transform.position + length * right, 5f, new Color(1f, 0f, 0f, 0.75f));
DrawLine(objective.Segment.Transform.position - length * up, objective.Segment.Transform.position + length * up, 5f, new Color(0f, 1f, 0f, 0.75f));
DrawLine(objective.Segment.Transform.position - length * forward, objective.Segment.Transform.position + length * forward, 5f, new Color(0f, 0f, 1f, 0.75f));
Handles.Label(objective.Segment.Transform.position, "Target");
}
private void DrawLookAt(LookAt objective) {
if(objective.GetViewingDirection().magnitude != 0f) {
DrawArrow(objective.transform.position, objective.transform.rotation*Quaternion.LookRotation((objective.GetViewingDirection())), 0.125f, Color5);
}
}
private void DrawDistance(Distance objective) {
DrawSphere(objective.transform.position, (float)objective.GetRadius(), new Color(0f, 1f, 0f, 0.5f));
DistancePoint[] points = objective.GetPoints();
for(int i=0; i<points.Length; i++) {
DistancePoint point = points[i];
if(point != null) {
DrawSphere(point.GetTargetPoint(), (float)point.GetRadius(), new Color(1f, 0f, 0f, 0.5f));
}
}
}
private void DrawJointValue(JointValue objective) {
}
private void DrawDisplacement(Displacement objective) {
}
private void DrawProjection(Projection objective) {
Vector3 normal = objective.Segment.Transform.rotation * objective.GetNormal();
Vector3 start = objective.Segment.Transform.position - objective.GetLength() * normal;
Vector3 end = start + objective.GetLength() * normal;
DrawSphere(start, 0.025f, Color5);
DrawArrow(start, Quaternion.FromToRotation(Vector3.forward, end-start), objective.GetLength(), Color5);
DrawSphere(objective.GetTargetPosition(), 0.025f, Color.red);
/*
Quaternion rotation = Quaternion.Euler(objective.GetTargetRotation());
Vector3 right = rotation * Vector3.right;
Vector3 up = rotation * Vector3.up;
Vector3 forward = rotation * Vector3.forward;
//float length = 0.05f;
//DrawLine(objective.Segment.Transform.position - length * right, objective.Segment.Transform.position + length * right, 5f, Color.red);
//DrawLine(objective.Segment.Transform.position - length * up, objective.Segment.Transform.position + length * up, 5f, Color.green);
//DrawLine(objective.Segment.Transform.position - length * forward, objective.Segment.Transform.position + length * forward, 5f, Color.blue);
//for(int i=0; i<Corrections.Length; i++) {
// normal = transform.rotation * Corrections[i].Direction;
// start = transform.position + transform.rotation * Corrections[i].Offset;
// end = start + Corrections[i].Length * normal;
// Gizmos.color = Color.cyan;
// Gizmos.DrawSphere(start, 0.025f);
// Gizmos.DrawLine(start, end);
// Gizmos.DrawSphere(end, 0.025f);
//}
*/
}
private void DrawSphere(Vector3 position, float radius, Color color) {
Handles.color = color;
Handles.SphereHandleCap(0, position, Quaternion.identity, radius, EventType.Repaint);
}
private void DrawCube(Vector3 position, Quaternion rotation, float size, Color color) {
Handles.color = color;
Handles.CubeHandleCap(0, position, rotation, size, EventType.Repaint);
}
private void DrawLine(Vector3 a, Vector3 b, float width, Color color) {
Handles.color = color;
Handles.DrawAAPolyLine(width, new Vector3[2] {a,b});
}
private void DrawDottedLine(Vector3 a, Vector3 b, float width, Color color) {
Handles.color = color;
Handles.DrawDottedLine(a, b, width);
}
private void DrawArrow(Vector3 position, Quaternion rotation, float length, Color color) {
Handles.color = color;
Handles.ArrowHandleCap(0, position, rotation, length, EventType.Repaint);
}
private void DrawSolidArc(Vector3 position, Vector3 normal, Vector3 from, float angle, float radius, Color color) {
Handles.color = color;
Handles.DrawSolidArc(position, normal, from, angle, radius);
}
private void SetGUIColor(Color color) {
GUI.backgroundColor = color;
}
private void ComputeMaxIndentLevel(Transform t, int level, ref int maxIndent) {
maxIndent = System.Math.Max(maxIndent, level);
for(int i=0; i<t.childCount; i++) {
ComputeMaxIndentLevel(t.GetChild(i), level+1, ref maxIndent);
}
}
}
}