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