/// <summary> /// Displays the linear limit handles. /// </summary> /// <param name="joint">Joint.</param> /// <param name="bindpose">Bindpose.</param> /// <returns><see langword="true"/> if the handles changed; otherwise, <see langword="false"/>.</returns> public static bool DisplayLinearLimitHandles(Joint joint, Matrix4x4 bindpose) { if (joint is ConfigurableJoint) { ConfigurableJoint thisJoint = joint as ConfigurableJoint; float newLinearLimit = 0f; if (SceneGUI.BeginHandles(thisJoint, "Change Linear Limits")) { newLinearLimit = JointHandles.LinearLimit(thisJoint, bindpose); } if (SceneGUI.EndHandles()) { SoftJointLimit limit = thisJoint.linearLimit; limit.limit = newLinearLimit; thisJoint.linearLimit = limit; return(true); } } else if (joint is SpringJoint) { SpringJoint thisJoint = joint as SpringJoint; Vector2 newLinearLimits = new Vector2(thisJoint.minDistance, thisJoint.maxDistance); if (SceneGUI.BeginHandles(thisJoint, "Change Linear Limits")) { newLinearLimits = JointHandles.SpringLimit(thisJoint, bindpose); } if (SceneGUI.EndHandles()) { thisJoint.minDistance = newLinearLimits.x; thisJoint.maxDistance = newLinearLimits.y; return(true); } } return(false); }
/* * Draw the handle if it is enabled * */ void OnSceneGUI() { // viewport gui controls Handles.BeginGUI(); { ViewportControls.BeginArea(viewportControlsWidth, GUIAnchor.TopLeft); { GUILayout.BeginVertical(); { JointHandleToggle(); GUILayout.BeginHorizontal(); { JointHandleSizeSlider(viewportControlsWidth); } GUILayout.EndHorizontal(); CustomHandleUtilities.ViewportIntegratorFidelityControls(viewportControlsWidth); } GUILayout.EndVertical(); } ViewportControls.EndArea(); } Handles.EndGUI(); // handles if (!isHandleEnabled) { return; } Undo.SetSnapshotTarget(target, "Change Configurable Joint"); JointHandles.JointLimit(joint, jointHandleSize); EditorUtility.SetDirty(target); }
/// <summary> /// Displays the angular limit handles. /// </summary> /// <param name="joint">Joint.</param> /// <param name="bindpose">Bindpose.</param> /// <returns><see langword="true"/> if the handles changed; otherwise, <see langword="false"/>.</returns> public static bool DisplayAngularLimitHandles(Joint joint, Matrix4x4 bindpose) { if (joint == null) { return(false); } Matrix4x4 oldMatrix = Handles.matrix; Handles.matrix = Matrix4x4.identity; bool result = false; if (joint is ConfigurableJoint) { JointAngularLimits newAngularLimits = new JointAngularLimits(joint as ConfigurableJoint); if (SceneGUI.BeginHandles(joint, "Change Angular Limits")) { newAngularLimits = JointHandles.AngularLimit( joint as ConfigurableJoint, bindpose, AngularLimitHandleSize ); } if (SceneGUI.EndHandles()) { newAngularLimits.ApplyToJoint(joint as ConfigurableJoint); result = true; } } else if (joint is CharacterJoint) { JointAngularLimits newAngularLimits = new JointAngularLimits(joint as CharacterJoint); if (SceneGUI.BeginHandles(joint, "Change Angular Limits")) { newAngularLimits = JointHandles.AngularLimit( joint as CharacterJoint, bindpose, AngularLimitHandleSize ); } if (SceneGUI.EndHandles()) { newAngularLimits.ApplyToJoint(joint as CharacterJoint); result = true; } } else if (joint is HingeJoint) { JointLimits newLimits = (joint as HingeJoint).limits; if (SceneGUI.BeginHandles(joint, "Change Angular Limits")) { newLimits = JointHandles.AngularLimit( joint as HingeJoint, bindpose, AngularLimitHandleSize ); } if (SceneGUI.EndHandles()) { (joint as HingeJoint).limits = newLimits; result = true; } } Handles.matrix = oldMatrix; return(result); }
/* * Draw a joint limit gizmo for a specified part * */ public static void DrawJointHandle(BodyPart part, bool drawOpposite) { // early out if joint handles are disabled or the part is null if (!ConfigurableJointEditor.isHandleEnabled || part == null || !part.isRigidbody) { return; } // set undo snapshot BodyPart[] parts = new BodyPart[1]; if (isSymmetrical && part.oppositePart != null) { parts = new BodyPart[2]; parts[1] = part.oppositePart; parts[1].oppositePart = part; // BUG: No idea why I need to do this } parts[0] = part; Undo.SetSnapshotTarget(parts, string.Format("Change Joint Limits")); Quaternion parentRotation = (part.bone.parent == null)?Quaternion.identity:part.bone.parent.rotation; JointHandles.JointLimit(ref part.xMin, ref part.xMax, ref part.yMax, ref part.zMax, part.bone.position, parentRotation * part.initialRotation, part.jointAxis, part.jointSecondaryAxis, ConfigurableJointEditor.jointHandleSize, 1f); if (isSymmetrical && part.oppositePart != null) { // TODO: there may be something math smart to reflect axes in a general way // NOTE: this works assuming the axes have been correctly set correspondingly parts[1].xMax = part.xMax; parts[1].xMin = part.xMin; parts[1].yMax = part.yMax; parts[1].zMax = part.zMax; parentRotation = (parts[1].bone.parent == null)?Quaternion.identity:parts[1].bone.parent.rotation; JointHandles.JointLimit(ref parts[1].xMin, ref parts[1].xMax, ref parts[1].yMax, ref parts[1].zMax, parts[1].bone.position, parentRotation * parts[1].initialRotation, parts[1].jointAxis, parts[1].jointSecondaryAxis, ConfigurableJointEditor.jointHandleSize, 0.5f); part.xMax = parts[1].xMax; part.xMin = parts[1].xMin; part.yMax = parts[1].yMax; part.zMax = parts[1].zMax; } }