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#
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|