You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
9.0 KiB
C#

using UnityEngine;
using System.Collections;
using UnityEditor;
namespace RootMotion.Dynamics {
public enum JointAxis {
Primary,
Secondary,
Tertiary
}
// Tools for editing Joints.
public class JointTools: Editor {
public static Quaternion LocalToJointSpace(ConfigurableJoint joint) {
Vector3 forward = Vector3.Cross (joint.axis, joint.secondaryAxis).normalized;
Vector3 up = Vector3.Cross(forward, joint.axis).normalized;
if (forward == up) {
Debug.LogWarning("Joint " + joint.name + " secondaryAxis is in the exact same direction as its axis. Please make sure they are not aligned.");
}
return Quaternion.LookRotation(forward, up);
}
public static Quaternion LocalToJointSpace(CharacterJoint joint) {
Vector3 forward = Vector3.Cross (joint.axis, joint.swingAxis).normalized;
Vector3 up = Vector3.Cross(forward, joint.axis).normalized;
if (forward == up) {
Debug.LogWarning("Joint " + joint.name + " swingAxis is in the exact same direction as its axis. Please make sure they are not aligned.");
}
return Quaternion.LookRotation(forward, up);
}
public static Quaternion JointToLocalSpace(ConfigurableJoint joint) {
return Quaternion.Inverse(LocalToJointSpace(joint));
}
public static Quaternion JointToLocalSpace(CharacterJoint joint) {
return Quaternion.Inverse(LocalToJointSpace(joint));
}
public static JointAxis GetJointAxis(ConfigurableJoint joint, Vector3 vLocal) {
return GetJointAxis(joint.axis, joint.secondaryAxis, vLocal);
}
public static JointAxis GetJointAxis(CharacterJoint joint, Vector3 vLocal) {
return GetJointAxis(joint.axis, joint.swingAxis, vLocal);
}
public static JointAxis GetJointAxis(Vector3 axis, Vector3 secondaryAxis, Vector3 vLocal) {
vLocal = vLocal.normalized;
float axisDot = Mathf.Abs(Vector3.Dot(axis, vLocal));
float secondaryAxisDot = Mathf.Abs(Vector3.Dot(secondaryAxis, vLocal));
float tertiaryAxisDot = Mathf.Abs(Vector3.Dot(Vector3.Cross(axis, secondaryAxis), vLocal));
if (axisDot > secondaryAxisDot && axisDot > tertiaryAxisDot) return JointAxis.Primary;
if (secondaryAxisDot > axisDot && secondaryAxisDot > tertiaryAxisDot) return JointAxis.Secondary;
return JointAxis.Tertiary;
}
public static JointAxis GetSymmetricJointAxis(ConfigurableJoint joint, JointAxis jointAxis, ConfigurableJoint symmetricJoint, Transform root) {
return GetSymmetricJointAxis(joint.transform, joint.axis, joint.secondaryAxis, jointAxis, symmetricJoint.transform, symmetricJoint.axis, symmetricJoint.secondaryAxis, root);
}
public static JointAxis GetSymmetricJointAxis(CharacterJoint joint, JointAxis jointAxis, CharacterJoint symmetricJoint, Transform root) {
return GetSymmetricJointAxis(joint.transform, joint.axis, joint.swingAxis, jointAxis, symmetricJoint.transform, symmetricJoint.axis, symmetricJoint.swingAxis, root);
}
public static JointAxis GetSymmetricJointAxis(Transform jointTransform, Vector3 axis, Vector3 secondaryAxis, JointAxis jointAxis, Transform symmetricTransform, Vector3 symmetricAxis, Vector3 symmetricSecondaryAxis, Transform root) {
Vector3 a = JointAxisToVector3(axis, secondaryAxis, jointAxis);
Vector3 aWorld = jointTransform.rotation * a;
Vector3 aWorldMirror = SymmetryTools.Mirror(aWorld, root);
Vector3 aLocalMirror = Quaternion.Inverse(symmetricTransform.rotation) * aWorldMirror;
Vector3 sAVector = AxisTools.GetAxisVectorToDirection(symmetricTransform, aWorldMirror);
Vector3 sA = Vector3.Project(aLocalMirror, sAVector);
return GetJointAxis(symmetricAxis, symmetricSecondaryAxis, sA);
}
public static Vector3 JointAxisToVector3(ConfigurableJoint joint, JointAxis jointAxis) {
return JointAxisToVector3(joint.axis, joint.secondaryAxis, jointAxis);
}
public static Vector3 JointAxisToVector3(CharacterJoint joint, JointAxis jointAxis) {
return JointAxisToVector3(joint.axis, joint.swingAxis, jointAxis);
}
public static Vector3 JointAxisToVector3(Vector3 axis, Vector3 secondaryAxis, JointAxis jointAxis) {
switch(jointAxis) {
case JointAxis.Primary: return axis;
case JointAxis.Secondary: return secondaryAxis;
default: return Vector3.Cross(axis, secondaryAxis);
}
}
public static void ApplyXDeltaToJointLimit(ref ConfigurableJoint joint, float delta, JointAxis jointAxis, bool low) {
switch(jointAxis) {
case JointAxis.Primary:
if (low) {
SoftJointLimit lowX = joint.lowAngularXLimit;
lowX.limit += delta;
joint.lowAngularXLimit = lowX;
} else {
SoftJointLimit highX = joint.highAngularXLimit;
highX.limit -= delta;
joint.highAngularXLimit = highX;
}
break;
case JointAxis.Secondary:
SoftJointLimit y = joint.angularYLimit;
y.limit += delta * 0.5f;
joint.angularYLimit = y;
break;
case JointAxis.Tertiary:
SoftJointLimit z = joint.angularZLimit;
z.limit += delta * 0.5f;
joint.angularZLimit = z;
break;
}
}
public static void ApplyXDeltaToJointLimit(ref CharacterJoint joint, float delta, JointAxis jointAxis, bool low) {
switch(jointAxis) {
case JointAxis.Primary:
if (low) {
SoftJointLimit lowX = joint.lowTwistLimit;
lowX.limit += delta;
joint.lowTwistLimit = lowX;
} else {
SoftJointLimit highX = joint.highTwistLimit;
highX.limit -= delta;
joint.highTwistLimit = highX;
}
break;
case JointAxis.Secondary:
SoftJointLimit y = joint.swing1Limit;
y.limit += delta * 0.5f;
joint.swing1Limit = y;
break;
case JointAxis.Tertiary:
SoftJointLimit z = joint.swing2Limit;
z.limit += delta * 0.5f;
joint.swing2Limit = z;
break;
}
}
public static void ApplyDeltaToJointLimit(ref ConfigurableJoint joint, float delta, JointAxis jointAxis) {
switch(jointAxis) {
case JointAxis.Primary:
SoftJointLimit lowX = joint.lowAngularXLimit;
lowX.limit += delta;
joint.lowAngularXLimit = lowX;
SoftJointLimit highX = joint.highAngularXLimit;
highX.limit += delta;
joint.highAngularXLimit = highX;
break;
case JointAxis.Secondary:
SoftJointLimit y = joint.angularYLimit;
y.limit += delta;
joint.angularYLimit = y;
break;
case JointAxis.Tertiary:
SoftJointLimit z = joint.angularZLimit;
z.limit += delta;
joint.angularZLimit = z;
break;
}
}
public static void ApplyDeltaToJointLimit(ref CharacterJoint joint, float delta, JointAxis jointAxis) {
switch(jointAxis) {
case JointAxis.Primary:
SoftJointLimit lowX = joint.lowTwistLimit;
lowX.limit += delta;
joint.lowTwistLimit = lowX;
SoftJointLimit highX = joint.highTwistLimit;
highX.limit += delta;
joint.highTwistLimit = highX;
break;
case JointAxis.Secondary:
SoftJointLimit y = joint.swing1Limit;
y.limit += delta;
joint.swing1Limit = y;
break;
case JointAxis.Tertiary:
SoftJointLimit z = joint.swing2Limit;
z.limit += delta;
joint.swing2Limit = z;
break;
}
}
public static Vector3 GetLowXAxisWorld(Joint joint) {
return joint.transform.rotation * joint.axis;
}
public static Vector3 GetHighXAxisWorld(Joint joint) {
return joint.transform.rotation * -joint.axis;
}
public static void SwitchXY(ref ConfigurableJoint joint) {
Undo.RecordObject(joint, "Switch Yellow/Green Joint Axis");
Vector3 axis = joint.axis;
joint.axis = joint.secondaryAxis;
joint.secondaryAxis = axis;
}
public static void SwitchXZ(ref ConfigurableJoint joint) {
Undo.RecordObject(joint, "Switch Yellow/Blue Joint Axis");
Vector3 cross = Vector3.Cross(joint.axis, joint.secondaryAxis).normalized;
joint.axis = cross;
}
public static void SwitchYZ(ref ConfigurableJoint joint) {
Undo.RecordObject(joint, "Switch Green/Blue Joint Axis");
Vector3 cross = Vector3.Cross(joint.axis, joint.secondaryAxis).normalized;
joint.secondaryAxis = cross;
}
public static void SwitchXY(ref CharacterJoint joint) {
Undo.RecordObject(joint, "Switch Yellow/Green Joint Axis");
Vector3 axis = joint.axis;
joint.axis = joint.swingAxis;
joint.swingAxis = axis;
}
public static void SwitchXZ(ref CharacterJoint joint) {
Undo.RecordObject(joint, "Switch Yellow/Blue Joint Axis");
Vector3 cross = Vector3.Cross(joint.axis, joint.swingAxis).normalized;
joint.axis = cross;
}
public static void SwitchYZ(ref CharacterJoint joint) {
Undo.RecordObject(joint, "Switch Green/Blue Joint Axis");
Vector3 cross = Vector3.Cross(joint.axis, joint.swingAxis).normalized;
joint.swingAxis = cross;
}
public static void InvertAxis(ref Joint joint) {
Undo.RecordObject(joint, "Invert Axis");
joint.axis = -joint.axis;
}
public static void InvertSecondaryAxis(ref Joint joint) {
if (joint is ConfigurableJoint) {
var j = joint as ConfigurableJoint;
Undo.RecordObject(j, "Invert Secondary Axis");
j.secondaryAxis = -j.secondaryAxis;
}
if (joint is CharacterJoint) {
var j = joint as CharacterJoint;
Undo.RecordObject(j, "Invert Swing Axis");
j.swingAxis = -j.swingAxis;
}
}
}
}