Beispiel #1
0
        private void ShowSphericalLimits(JointAngularLimitHandle handle, ArticulationBody body, Matrix4x4 parentAnchorSpace)
        {
            using (new Handles.DrawingScope(parentAnchorSpace))
            {
                handle.xMin = body.xDrive.lowerLimit;
                handle.xMax = body.xDrive.upperLimit;

                handle.yMin = body.yDrive.lowerLimit;
                handle.yMax = body.yDrive.upperLimit;

                handle.zMin = body.zDrive.lowerLimit;
                handle.zMax = body.zDrive.upperLimit;

                EditorGUI.BeginChangeCheck();

                handle.radius = HandleUtility.GetHandleSize(Vector3.zero);
                handle.DrawHandle(true);

                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(target, "Changing Articulation body parent anchor rotation limits");

                    body.xDrive = SetDriveLimits(body.xDrive, handle.xMin, handle.xMax);
                    body.yDrive = SetDriveLimits(body.yDrive, handle.yMin, handle.yMax);
                    body.zDrive = SetDriveLimits(body.zDrive, handle.zMin, handle.zMax);
                }
            }
        }
Beispiel #2
0
    public static void JointAngularLimitHandle(Vector3 center, Quaternion rotation, Vector3 size, ref Vector3 minAngles, ref Vector3 maxAngles, Color xHandleColor, Color yHandleColor, Color zHandleColor)
    {
        Matrix4x4 trs = Matrix4x4.TRS(center, rotation, size);

        using (new Handles.DrawingScope(trs)) {
            jointAngularLimitHandle.xHandleColor = xHandleColor;
            jointAngularLimitHandle.yHandleColor = yHandleColor;
            jointAngularLimitHandle.zHandleColor = zHandleColor;

            jointAngularLimitHandle.xMin = minAngles.x;
            jointAngularLimitHandle.yMin = minAngles.y;
            jointAngularLimitHandle.zMin = minAngles.z;
            jointAngularLimitHandle.xMax = maxAngles.x;
            jointAngularLimitHandle.yMax = maxAngles.y;
            jointAngularLimitHandle.zMax = maxAngles.z;

            jointAngularLimitHandle.DrawHandle();

            minAngles.x = jointAngularLimitHandle.xMin;
            minAngles.y = jointAngularLimitHandle.yMin;
            minAngles.z = jointAngularLimitHandle.zMin;
            maxAngles.x = jointAngularLimitHandle.xMax;
            maxAngles.y = jointAngularLimitHandle.yMax;
            maxAngles.z = jointAngularLimitHandle.zMax;
        }
    }
        public override void OnSceneGUI()
        {
            var action = target as HutongGames.PlayMaker.Actions.SmoothLookAt2d;

            if (action == null) // shouldn't happen!
            {
                return;
            }

            var go = action.Fsm.GetOwnerDefaultTarget(action.gameObject);

            if (go == null)
            {
                return;
            }

            var transform  = go.transform;
            var handleSize = HandleUtility.GetHandleSize(transform.position);

            angularLimitHandle.radius = 2f * handleSize;

            var handleDirection = Quaternion.Euler(0, 0, action.rotationOffset.Value) * transform.right;

            using (new Handles.DrawingScope(PlayMakerPrefs.ArrowColor))
            {
                // Arrow is a little heavy. Would be nice to have smaller flat arrow style...
                //Handles.ArrowHandleCap(0, transform.position, lookRotation, minHandle.radius*1.2f, EventType.Repaint);
                Handles.DrawLine(transform.position, transform.position + handleDirection * handleSize * 2.3f);

                if (action.useLimits.Value)
                {
                    angularLimitHandle.zMin = -action.maxAngle.Value;
                    angularLimitHandle.zMax = -action.minAngle.Value;

                    var rotation     = transform.parent != null ? transform.parent.rotation : Quaternion.identity;
                    var handleMatrix = Matrix4x4.TRS(go.transform.position, rotation, Vector3.one);

                    EditorGUI.BeginChangeCheck();

                    using (new Handles.DrawingScope(handleMatrix))
                    {
                        angularLimitHandle.DrawHandle();
                    }

                    if (EditorGUI.EndChangeCheck())
                    {
                        action.minAngle.Value = -angularLimitHandle.zMax;
                        action.maxAngle.Value = -angularLimitHandle.zMin;
                    }
                }
            }
        }
Beispiel #4
0
        public static void EditLimits(RigidTransform worldFromA, RigidTransform worldFromB, float3 pivotA, float3 axisA, float3 axisB, float3 perpendicularA, float3 perpendicularB,
                                      ref float minLimit, ref float maxLimit, JointAngularLimitHandle limitHandle, Object target)
        {
            // Transform to world space
            float3 pivotAinW         = math.transform(worldFromA, pivotA);
            float3 axisAinW          = math.rotate(worldFromA, axisA);
            float3 perpendicularAinW = math.rotate(worldFromA, perpendicularA);
            float3 axisBinW          = math.rotate(worldFromA, axisB);
            float3 perpendicularBinW = math.rotate(worldFromB, perpendicularB);

            // Get rotations from joint space
            // JointAngularLimitHandle uses axis = (1, 0, 0) with angle = 0 at (0, 0, 1), so choose the rotations to point those in the directions of our axis and perpendicular
            float3x3 worldFromJointA = new float3x3(axisAinW, -math.cross(axisAinW, perpendicularAinW), perpendicularAinW);
            float3x3 worldFromJointB = new float3x3(axisBinW, -math.cross(axisBinW, perpendicularBinW), perpendicularBinW);
            float3x3 jointBFromA     = math.mul(math.transpose(worldFromJointB), worldFromJointA);

            // Set orientation for the angular limit control
            float      angle            = CalculateTwistAngle(new quaternion(jointBFromA), 0); // index = 0 because axis is the first column in worldFromJoint
            quaternion limitOrientation = math.mul(quaternion.AxisAngle(axisAinW, angle), new quaternion(worldFromJointA));
            Matrix4x4  handleMatrix     = Matrix4x4.TRS(pivotAinW, limitOrientation, Vector3.one);

            float size = HandleUtility.GetHandleSize(pivotAinW) * 0.75f;

            limitHandle.xMin         = -maxLimit;
            limitHandle.xMax         = -minLimit;
            limitHandle.xMotion      = ConfigurableJointMotion.Limited;
            limitHandle.yMotion      = ConfigurableJointMotion.Locked;
            limitHandle.zMotion      = ConfigurableJointMotion.Locked;
            limitHandle.yHandleColor = new Color(0, 0, 0, 0);
            limitHandle.zHandleColor = new Color(0, 0, 0, 0);
            limitHandle.radius       = size;

            using (new Handles.DrawingScope(handleMatrix))
            {
                // Draw the reference axis
                float3 z = new float3(0, 0, 1); // ArrowHandleCap() draws an arrow pointing in (0, 0, 1)
                Handles.ArrowHandleCap(0, float3.zero, Quaternion.FromToRotation(z, new float3(1, 0, 0)), size, Event.current.type);

                // Draw the limit editor handle
                EditorGUI.BeginChangeCheck();
                limitHandle.DrawHandle();
                if (EditorGUI.EndChangeCheck())
                {
                    // Record the target object before setting new limits so changes can be undone/redone
                    Undo.RecordObject(target, "Edit joint angular limits");
                    minLimit = -limitHandle.xMax;
                    maxLimit = -limitHandle.xMin;
                }
            }
        }
    // the OnSceneGUI callback uses the Scene view camera for drawing handles by default
    protected virtual void OnSceneGUI()
    {
        var jointExample = (JointExample)target;

        // copy the target object's data to the handle
        m_Handle.xMin = jointExample.xMin;
        m_Handle.xMax = jointExample.xMax;

        // CharacterJoint and ConfigurableJoint implement y- and z-axes symmetrically
        m_Handle.yMin = -jointExample.yMax;
        m_Handle.yMax = jointExample.yMax;

        m_Handle.zMin = -jointExample.zMax;
        m_Handle.zMax = jointExample.zMax;

        // set the handle matrix to match the object's position/rotation with a uniform scale
        Matrix4x4 handleMatrix = Matrix4x4.TRS(
            jointExample.transform.position,
            jointExample.transform.rotation,
            Vector3.one
            );

        EditorGUI.BeginChangeCheck();

        using (new Handles.DrawingScope(handleMatrix))
        {
            // maintain a constant screen-space size for the handle's radius based on the origin of the handle matrix
            m_Handle.radius = 2 * HandleUtility.GetHandleSize(Vector3.zero);

            // draw the handle
            EditorGUI.BeginChangeCheck();
            m_Handle.DrawHandle();
            if (EditorGUI.EndChangeCheck())
            {
                // record the target object before setting new values so changes can be undone/redone
                Undo.RecordObject(jointExample, "Change Joint Example Properties");

                // copy the handle's updated data back to the target object
                jointExample.xMin = m_Handle.xMin;
                jointExample.xMax = m_Handle.xMax;

                jointExample.yMax = m_Handle.yMax == jointExample.yMax ? -m_Handle.yMin : m_Handle.yMax;

                jointExample.zMax = m_Handle.zMax == jointExample.zMax ? -m_Handle.zMin : m_Handle.zMax;
            }
        }
    }
Beispiel #6
0
        private void DrawJointHandles()
        {
            if (tgt.previewBones[tgt.selectedBoneID].IsRoot || !tgt.showJointSettings)
            {
                return;
            }

            PreviewBone bone      = tgt.previewBones[tgt.selectedBoneID];
            Quaternion  globalRot = tgt.transform.rotation * bone.rotation;

            if (tgt.rotationHandle)
            {
                Quaternion rot = globalRot * Quaternion.LookRotation(Vector3.Cross(bone.axis, bone.swingAxis), bone.swingAxis);
                EditorGUI.BeginChangeCheck();
                rot = Quaternion.Inverse(globalRot) * Handles.RotationHandle(rot, bone.tr.position);
                if (EditorGUI.EndChangeCheck())
                {
                    bone.axis      = -Vector3.Cross(rot * Vector3.forward, bone.swingAxis).Round(2);
                    bone.swingAxis = (rot * Vector3.up).Round(2);
                }
            }

            Matrix4x4 jointMatrix = Matrix4x4.TRS(bone.tr.position, globalRot * Quaternion.LookRotation(Vector3.Cross(bone.axis, bone.swingAxis), bone.swingAxis), Vector3.one);

            using (new Handles.DrawingScope(jointMatrix)) {
                jointAngularLimitHandle.xMin = bone.lowTwistLimit;
                jointAngularLimitHandle.xMax = bone.highTwistLimit;
                jointAngularLimitHandle.yMin = -bone.swing1Limit;
                jointAngularLimitHandle.yMax = bone.swing1Limit;
                jointAngularLimitHandle.zMin = -bone.swing2Limit;
                jointAngularLimitHandle.zMax = bone.swing2Limit;
                EditorGUI.BeginChangeCheck();
                jointAngularLimitHandle.DrawHandle();
                if (EditorGUI.EndChangeCheck())
                {
                    bone.lowTwistLimit  = jointAngularLimitHandle.xMin;
                    bone.highTwistLimit = jointAngularLimitHandle.xMax;
                    bone.swing1Limit    = jointAngularLimitHandle.yMax == bone.swing1Limit ? -jointAngularLimitHandle.yMin : jointAngularLimitHandle.yMax;
                    bone.swing2Limit    = jointAngularLimitHandle.zMax == bone.swing2Limit ? -jointAngularLimitHandle.zMin : jointAngularLimitHandle.zMax;
                }
            }
        }
        new public void OnSceneGUI()
        {
            if (!target)
            {
                return;
            }
            var hingeJoint2D = (HingeJoint2D)target;

            // Ignore disabled joint.
            if (!hingeJoint2D.enabled)
            {
                return;
            }

            // Fetch the reference angle which acts as an offset to the absolute angles this gizmo is displaying/editing.
            var referenceAngle = hingeJoint2D.referenceAngle;

            m_AngularLimitHandle.xMotion = hingeJoint2D.useLimits ? ConfigurableJointMotion.Limited : ConfigurableJointMotion.Free;

            JointAngleLimits2D limit = hingeJoint2D.limits;

            m_AngularLimitHandle.xMin = limit.min + referenceAngle;
            m_AngularLimitHandle.xMax = limit.max + referenceAngle;

            // only display control handles on manipulator if in edit mode
            var editMode = EditMode.editMode == EditMode.SceneViewEditMode.JointAngularLimits && EditMode.IsOwner(this);

            if (editMode)
            {
                m_AngularLimitHandle.angleHandleDrawFunction = ArcHandle.DefaultAngleHandleDrawFunction;
            }
            else
            {
                m_AngularLimitHandle.angleHandleDrawFunction = null;
            }

            // to enhance usability, orient the manipulator to best illustrate its affects on the dynamic body in the system
            var dynamicBody = hingeJoint2D.attachedRigidbody;
            var dynamicBodyLocalReferencePosition = Vector3.right;
            var dynamicAnchor           = hingeJoint2D.anchor;
            var connectedBody           = hingeJoint2D.connectedBody;
            var handleOrientationOffset = s_RightHandedHandleOrientationOffset;

            if (
                dynamicBody.bodyType != RigidbodyType2D.Dynamic &&
                hingeJoint2D.connectedBody != null &&
                hingeJoint2D.connectedBody.bodyType == RigidbodyType2D.Dynamic
                )
            {
                dynamicBody = hingeJoint2D.connectedBody;
                dynamicBodyLocalReferencePosition = Vector3.left;
                dynamicAnchor           = hingeJoint2D.connectedAnchor;
                connectedBody           = hingeJoint2D.attachedRigidbody;
                handleOrientationOffset = s_LeftHandedHandleOrientationOffset;
            }

            var handlePosition    = TransformPoint(dynamicBody.transform, dynamicAnchor);
            var handleOrientation = (
                connectedBody == null ?
                Quaternion.identity :
                Quaternion.LookRotation(Vector3.forward, connectedBody.transform.rotation * Vector3.up)
                ) * handleOrientationOffset;
            var dynamicActorReferencePosition =
                handlePosition
                + Quaternion.LookRotation(Vector3.forward, dynamicBody.transform.rotation * Vector3.up)
                * dynamicBodyLocalReferencePosition;

            var handleMatrix = Matrix4x4.TRS(handlePosition, handleOrientation, Vector3.one);

            EditorGUI.BeginChangeCheck();

            using (new Handles.DrawingScope(Styles.handleColor, handleMatrix))
            {
                var radius = HandleUtility.GetHandleSize(Vector3.zero) * Styles.handleRadius;
                m_AngularLimitHandle.radius = radius;

                // reference line within arc to illustrate affected local axis
                Handles.DrawLine(
                    Vector3.zero,
                    handleMatrix.inverse.MultiplyPoint3x4(dynamicActorReferencePosition).normalized *radius
                    );

                m_AngularLimitHandle.DrawHandle();
            }

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(hingeJoint2D, Styles.editAngularLimitsUndoMessage);

                limit               = hingeJoint2D.limits;
                limit.min           = m_AngularLimitHandle.xMin - referenceAngle;
                limit.max           = m_AngularLimitHandle.xMax - referenceAngle;
                hingeJoint2D.limits = limit;

                dynamicBody.WakeUp();
            }

            base.OnSceneGUI();
        }
Beispiel #8
0
        protected virtual void OnSceneGUI()
        {
            TransformController transformController   = (TransformController)target;
            Vector3             orientationCorrection = new Vector3(0, 0, 0);

            switch (transformController.FreeDOF)
            {
            case 4:
                angularLimitHandle.xMin           = transformController.LockMin;
                angularLimitHandle.xMax           = transformController.LockMax;
                angularLimitHandle.xRange         = new Vector2(-360, 360);
                angularLimitHandle.yMotion        = 0;
                angularLimitHandle.zMotion        = 0;
                transformController.initialOffset = TransformUtils.GetInspectorRotation(transformController.transform).x;
                break;

            case 5:
                angularLimitHandle.yMin           = transformController.LockMin;
                angularLimitHandle.yMax           = transformController.LockMax;
                angularLimitHandle.yRange         = new Vector2(-360, 360);
                angularLimitHandle.xMotion        = 0;
                angularLimitHandle.zMotion        = 0;
                orientationCorrection             = new Vector3(0, 90, 0);
                transformController.initialOffset = TransformUtils.GetInspectorRotation(transformController.transform).y;
                break;

            case 6:
                angularLimitHandle.zMin           = transformController.LockMin;
                angularLimitHandle.zMax           = transformController.LockMax;
                angularLimitHandle.zRange         = new Vector2(-360, 360);
                angularLimitHandle.xMotion        = 0;
                angularLimitHandle.yMotion        = 0;
                orientationCorrection             = new Vector3(0, 180, 90);
                transformController.initialOffset = TransformUtils.GetInspectorRotation(transformController.transform).z;
                break;

            default:
                // this is just for rotation (hinge) joints, if not one of these then return
                return;
            }

            // set the handle matrix to match the object's position/rotation with a uniform scale

            Matrix4x4 handleMatrix = Matrix4x4.TRS(
                transformController.transform.position,
                transformController.transform.parent.gameObject.transform.rotation * Quaternion.Euler(orientationCorrection),
                Vector3.one
                );

            EditorGUI.BeginChangeCheck();

            using (new Handles.DrawingScope(handleMatrix))
            {
                // maintain a constant screen-space size for the handle's radius based on the origin of the handle matrix
                // add 30% to avoid the handle getting lost behind the transform
                angularLimitHandle.radius = HandleUtility.GetHandleSize(Vector3.zero) * 1.3f;

                // draw the handle
                EditorGUI.BeginChangeCheck();
                angularLimitHandle.DrawHandle();
                if (EditorGUI.EndChangeCheck())
                {
                    // undone/redo
                    Undo.RecordObject(transformController, "Change transform lock angles");

                    // update JointController script
                    float[] validated = new float[2] {
                        0, 0
                    };
                    switch (transformController.FreeDOF)
                    {
                    case 4:
                        validated = LockCheckAngle(angularLimitHandle.xMin, angularLimitHandle.xMax);
                        break;

                    case 5:
                        validated = LockCheckAngle(angularLimitHandle.yMin, angularLimitHandle.yMax);
                        break;

                    case 6:
                        validated = LockCheckAngle(angularLimitHandle.zMin, angularLimitHandle.zMax);
                        break;

                    default:
                        // this is just for rotation (hinge) joints, if not one of these then do nothing
                        break;
                    }
                    transformController.LockMin = validated[0];
                    transformController.LockMax = validated[1];
                }
            }
        }