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.
140 lines
5.0 KiB
C#
140 lines
5.0 KiB
C#
|
3 years ago
|
using UnityEngine;
|
||
|
|
using UnityEditor;
|
||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
|
||
|
|
namespace RootMotion.Dynamics {
|
||
|
|
|
||
|
|
public class JointInspector : Editor {
|
||
|
|
|
||
|
|
#region Public methods
|
||
|
|
|
||
|
|
private static bool isDragging;
|
||
|
|
|
||
|
|
public static float DrawJointLimit(Joint joint, string label, Vector3 axis, float limit, Color color, float openValue, bool drawHandles) {
|
||
|
|
if (Event.current.type == EventType.MouseDown) isDragging = false;
|
||
|
|
if (Event.current.type == EventType.MouseUp) isDragging = false;
|
||
|
|
|
||
|
|
float radius = HandleUtility.GetHandleSize(joint.transform.position);
|
||
|
|
Vector3 center = joint.transform.TransformPoint(joint.anchor);
|
||
|
|
|
||
|
|
Quaternion axisOffset = Quaternion.AngleAxis(GetViewOffset(joint, axis), axis);
|
||
|
|
Vector3 limitAxis = joint.transform.TransformDirection(axisOffset * axis).normalized;
|
||
|
|
Vector3 limitAxisOrtho = joint.transform.TransformDirection(axisOffset * new Vector3(axis.z, axis.x, axis.y)).normalized;
|
||
|
|
Vector3 limitAxisCross = Vector3.Cross(limitAxis, limitAxisOrtho);
|
||
|
|
|
||
|
|
Handles.color = color;
|
||
|
|
Handles.DrawSolidArc(center, limitAxis, limitAxisCross, -limit, radius);
|
||
|
|
|
||
|
|
Handles.color = new Color(color.r, color.g, color.b, 1f);
|
||
|
|
GUI.color = new Color(color.r, color.g, color.b, 1f);
|
||
|
|
|
||
|
|
//if (limitAxis != Vector3.zero) Handles.CircleCap(0, center, Quaternion.LookRotation(limitAxis), radius);
|
||
|
|
|
||
|
|
Quaternion angleAxis = Quaternion.AngleAxis(-limit, limitAxis);
|
||
|
|
Vector3 handleVector = angleAxis * limitAxisCross;
|
||
|
|
|
||
|
|
Quaternion handleRotation = Quaternion.AngleAxis(-limit, limitAxis);
|
||
|
|
if (limitAxisCross != Vector3.zero && limitAxisOrtho != Vector3.zero) {
|
||
|
|
handleRotation = Quaternion.AngleAxis(-limit, limitAxis) * Quaternion.LookRotation(limitAxisCross) * Quaternion.LookRotation(limitAxisOrtho);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!drawHandles) return limit;
|
||
|
|
|
||
|
|
float newLimit = Inspector.ScaleValueHandleSphere(limit, center + handleVector * radius, Quaternion.identity, radius, 1);
|
||
|
|
//float newLimit = Handles.han(handleRotation, center + handleVector * radius, limit);
|
||
|
|
|
||
|
|
string labelInfo = label;
|
||
|
|
|
||
|
|
if (newLimit == 0) {
|
||
|
|
labelInfo = "Open " + label;
|
||
|
|
if (Inspector.SphereButton(center + handleVector * radius, handleRotation, radius * 0.2f, radius * 0.07f)) {
|
||
|
|
newLimit = openValue;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Handles.Label(center + handleVector * radius * 1.2f, labelInfo);
|
||
|
|
|
||
|
|
if (newLimit != limit) {
|
||
|
|
if (!isDragging) {
|
||
|
|
Undo.RecordObject(joint, "Change Joint Limits");
|
||
|
|
isDragging = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
GUI.color = Color.white;
|
||
|
|
return newLimit;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static SoftJointLimit NewJointLimit(float limit, SoftJointLimit referenceJointLimit, float min, float max) {
|
||
|
|
SoftJointLimit newJointLimit = new SoftJointLimit();
|
||
|
|
newJointLimit.limit = Mathf.Clamp(limit, min, max);
|
||
|
|
newJointLimit.bounciness = referenceJointLimit.bounciness;
|
||
|
|
return newJointLimit;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Color MlpAlpha(Color color, float alphaMlp) {
|
||
|
|
return new Color(color.r, color.g, color.b, color.a * alphaMlp);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endregion
|
||
|
|
|
||
|
|
private static float GetViewOffset(Joint joint, Vector3 axis) {
|
||
|
|
if (joint.connectedBody == null) return 0;
|
||
|
|
|
||
|
|
Vector3 directionAxis = joint.transform.right;
|
||
|
|
Axis viewAxis = GetViewAxis(joint);
|
||
|
|
|
||
|
|
switch(viewAxis) {
|
||
|
|
case Axis.Y: directionAxis = joint.transform.up; break;
|
||
|
|
case Axis.Z: directionAxis = joint.transform.forward; break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (FlipAxis(joint, viewAxis)) directionAxis = -directionAxis;
|
||
|
|
|
||
|
|
Vector3 axisWorld = joint.transform.TransformDirection(axis).normalized;
|
||
|
|
Vector3 axisWorldOrtho = joint.transform.TransformDirection(new Vector3(axis.z, axis.x, axis.y)).normalized;
|
||
|
|
|
||
|
|
float dot = Vector3.Dot(axisWorldOrtho, directionAxis);
|
||
|
|
float dot2 = Vector3.Dot(axisWorldOrtho, Vector3.Cross(directionAxis, axisWorld));
|
||
|
|
|
||
|
|
if (dot >= 0.5f) return -90;
|
||
|
|
if (dot2 >= 0.5f) return 0;
|
||
|
|
if (dot < -0.5f) return 90;
|
||
|
|
if (dot2 < -0.5f) return 180;
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static Axis GetViewAxis(Joint joint) {
|
||
|
|
if (joint.connectedBody == null) return Axis.Z;
|
||
|
|
|
||
|
|
CapsuleCollider capsule = joint.GetComponent<CapsuleCollider>();
|
||
|
|
if (capsule != null && capsule.center != Vector3.zero) return AxisTools.ToAxis(capsule.center);
|
||
|
|
else {
|
||
|
|
BoxCollider box = joint.GetComponent<BoxCollider>();
|
||
|
|
if (box != null && box.center != Vector3.zero) return AxisTools.ToAxis(box.center);
|
||
|
|
}
|
||
|
|
|
||
|
|
return AxisTools.GetAxisToPoint(joint.transform, joint.connectedBody.worldCenterOfMass);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static bool FlipAxis(Joint joint, Axis axis) {
|
||
|
|
Vector3 direction = Vector3.Normalize(joint.transform.position - joint.connectedBody.worldCenterOfMass);
|
||
|
|
|
||
|
|
CapsuleCollider capsuleCollider = joint.GetComponent<CapsuleCollider>();
|
||
|
|
if (capsuleCollider != null) {
|
||
|
|
direction = Vector3.Normalize(joint.transform.position - (joint.transform.position - (joint.transform.rotation * capsuleCollider.center)));
|
||
|
|
}
|
||
|
|
|
||
|
|
switch(axis) {
|
||
|
|
case Axis.X:
|
||
|
|
return Vector3.Dot(joint.transform.right, direction) < 0;
|
||
|
|
case Axis.Y:
|
||
|
|
return Vector3.Dot(joint.transform.up, direction) < 0;
|
||
|
|
default: return Vector3.Dot(joint.transform.forward, direction) < 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|