Beispiel #1
0
 public ScaleInputMapping(RyneCamera camera, EditAxis axis, float speed = 1.0f) : base(camera)
 {
     Speed = speed;
     AddInput(new MouseAxisInput {
         Axis = new Float2(1, 0), Action = new InputScalingAction(new Float3(1, 0, 0), Speed)
     });
     AddInput(new MouseAxisInput {
         Axis = new Float2(0, 1), Action = new InputScalingAction(new Float3(0, 1, 0), Speed)
     });
 }
Beispiel #2
0
        public TranslationInputMapping(RyneCamera camera, EditAxis axis, float speed = 1.0f) : base(camera)
        {
            Speed = speed;

            AddInput(new MouseAxisInput {
                Axis = new Float2(1, 0), Action = new InputMovementAction(new Float3(0.0f), Speed)
            });
            AddInput(new MouseAxisInput {
                Axis = new Float2(0, 1), Action = new InputMovementAction(new Float3(0.0f), Speed)
            });
            UpdateMapping(camera, axis);
        }
Beispiel #3
0
        public sealed override void UpdateMapping(RyneCamera camera, EditAxis axis)
        {
            Float3 xAxis, yAxis;

            if (axis == EditAxis.All)
            {
                xAxis = new Float3(1, 0, 0);
                yAxis = new Float3(0, 1, 0);
            }
            else
            {
                xAxis = AxisToFloat3(axis);
                yAxis = xAxis;
            }

            MouseAxisInputs[0] = new MouseAxisInput {
                Axis = new Float2(1, 0), Action = new InputScalingAction(xAxis, Speed)
            };
            MouseAxisInputs[1] = new MouseAxisInput {
                Axis = new Float2(0, 1), Action = new InputScalingAction(yAxis, Speed)
            };
        }
Beispiel #4
0
        public sealed override void UpdateMapping(RyneCamera camera, EditAxis axis)
        {
            Float3 xAxis, yAxis;

            if (axis == EditAxis.All)
            {
                // Set axes from plane tangents relative to camera
                Float3 planeNormal = (camera.Focus - new Float3(camera.GetPosition())).Normalize();
                xAxis = planeNormal.Cross(camera.Up).Normalize() * -1.0f;
                yAxis = xAxis.Cross(planeNormal).Normalize();
            }
            else
            {
                xAxis = AxisToFloat3(axis);
                yAxis = xAxis;
            }

            MouseAxisInputs[0] = new MouseAxisInput {
                Axis = new Float2(1, 0), Action = new InputMovementAction(xAxis, Speed, false)
            };
            MouseAxisInputs[1] = new MouseAxisInput {
                Axis = new Float2(0, 1), Action = new InputMovementAction(yAxis, Speed, false)
            };
        }
Beispiel #5
0
        /// <summary>
        /// Displays a shape handle of the specified type.
        /// </summary>
        /// <remarks> If the user is holding Alt, the center will stay locked in place.</remarks>
        /// <param name="baseId">Base identifier.</param>
        /// <param name="size">Size.</param>
        /// <param name="center">Center.</param>
        /// <param name="orientation">Orientation.</param>
        /// <param name="type">Type.</param>
        private static void DoShapeHandle(
            int baseId, ref Vector3 size, ref Vector3 center, Quaternion orientation, WireShapeType type
            )
        {
            // set handle matrix
            Matrix4x4 oldMatrix = Handles.matrix;

            Handles.matrix *= Matrix4x4.TRS(center, orientation, Vector3.one);
            // generate control Ids
            int rightId   = ObjectX.GenerateHashCode(baseId, (int)type, (int)EditAxis.X, 1);
            int leftId    = ObjectX.GenerateHashCode(baseId, (int)type, (int)EditAxis.X, 2);
            int upId      = ObjectX.GenerateHashCode(baseId, (int)type, (int)EditAxis.Y, 1);
            int downId    = ObjectX.GenerateHashCode(baseId, (int)type, (int)EditAxis.Y, 2);
            int forwardId = ObjectX.GenerateHashCode(baseId, (int)type, (int)EditAxis.Z, 1);
            int backId    = ObjectX.GenerateHashCode(baseId, (int)type, (int)EditAxis.Z, 2);
            int currentId = GUIUtility.hotControl;
            int nearestId = HandleUtility.nearestControl;

            // cache the center and size when a handle is clicked to use for shift/alt dragging
            switch (Event.current.type)
            {
            case EventType.MouseDown:
                if (
                    nearestId == leftId || nearestId == rightId ||
                    nearestId == upId || nearestId == downId ||
                    nearestId == forwardId || nearestId == backId
                    )
                {
                    s_OnClickCenter[baseId] = center;
                    s_OnClickSize[baseId]   = size;
                }
                break;

            case EventType.MouseUp:
                s_OnClickCenter.Remove(baseId);
                s_OnClickSize.Remove(baseId);
                currentId = 0;
                break;
            }
            // make sure size is not negative on any dimension
            size = new Vector3(Mathf.Max(0f, size.x), Mathf.Max(0f, size.y), Mathf.Max(0f, size.z));
            // display right/left handles
            float   right  = size.x * 0.5f;
            float   left   = -size.x * 0.5f;
            Vector3 offset = Handles.matrix.GetScale();

            offset = new Vector3(
                offset.x == 0f ? 0f : 1f / offset.x,
                offset.y == 0f ? 0f : 1f / offset.y,
                offset.z == 0f ? 0f : 1f / offset.z
                );
            offset *= s_HandleOffset;
            right   = LinearHandles.Dot(
                rightId, val: right, origin: Vector3.right * offset.x, direction: Vector3.right
                );
            right = Mathf.Max(right, left);
            left  =
                LinearHandles.Dot(leftId, val: left, origin: Vector3.left * offset.x, direction: Vector3.right);
            left = Mathf.Min(right, left);
            // display up/down handles
            float up   = size.y * 0.5f;
            float down = -size.y * 0.5f;

            up   = LinearHandles.Dot(upId, val: up, origin: Vector3.up * offset.y, direction: Vector3.up);
            up   = Mathf.Max(up, down);
            down = LinearHandles.Dot(downId, val: down, origin: Vector3.down * offset.y, direction: Vector3.up);
            down = Mathf.Min(up, down);
            // display forward/back handles
            float forward = size.z * 0.5f;
            float back    = -size.z * 0.5f;

            forward = LinearHandles.Dot(
                forwardId, val: forward, origin: Vector3.forward * offset.z, direction: Vector3.forward
                );
            forward = Mathf.Max(forward, back);
            back    =
                LinearHandles.Dot(backId, val: back, origin: Vector3.back * offset.z, direction: Vector3.forward);
            back = Mathf.Min(forward, back);
            // store which axes are being edited
            EditAxis editAxis = EditAxis.None;

            if (currentId == rightId || currentId == leftId)
            {
                editAxis = EditAxis.X;
            }
            else if (currentId == upId || currentId == downId)
            {
                editAxis = EditAxis.Y;
            }
            else if (currentId == forwardId || currentId == backId)
            {
                editAxis = EditAxis.Z;
            }
            // apply constraints to size based on shape type
            size.x = Mathf.Max(0f, right - left);
            size.y = Mathf.Max(0f, up - down);
            size.z = Mathf.Max(0f, forward - back);
            Vector3 deltaCenter = 0.5f * new Vector3(right + left, up + down, forward + back);
            float   delta;

            switch (type)
            {
            case WireShapeType.Capsule:
                switch (editAxis)
                {
                case EditAxis.X:
                    delta          = Mathf.Min(size.x, size.y) - size.x;
                    size.x        += delta;
                    size.z         = size.x;
                    deltaCenter.x += delta * 0.5f;
                    break;

                case EditAxis.Y:
                    delta          = Mathf.Max(size.y, size.x, size.z) - size.y;
                    size.y        += delta;
                    deltaCenter.y += delta * 0.5f;
                    break;

                case EditAxis.Z:
                    delta          = Mathf.Min(size.z, size.y) - size.z;
                    size.z        += delta;
                    size.x         = size.z;
                    deltaCenter.z += delta * 0.5f;
                    break;
                }
                break;

            case WireShapeType.Cylinder:
                switch (editAxis)
                {
                case EditAxis.X:
                    delta          = Mathf.Min(size.x, size.y) - size.x;
                    size.x        += delta;
                    size.z         = size.x;
                    deltaCenter.x += delta * 0.5f;
                    break;

                case EditAxis.Z:
                    delta          = Mathf.Min(size.z, size.y) - size.z;
                    size.z        += delta;
                    size.x         = size.z;
                    deltaCenter.z += delta * 0.5f;
                    break;
                }
                break;

            case WireShapeType.Sphere:
                switch (editAxis)
                {
                case EditAxis.X:
                    size.y = size.z = size.x;
                    break;

                case EditAxis.Y:
                    size.x = size.z = size.y;
                    break;

                case EditAxis.Z:
                    size.x = size.y = size.z;
                    break;
                }
                break;
            }
            // apply new center
            center += orientation * deltaCenter;
            // scale uniformly using cached size if holding shift key
            if (s_OnClickSize.ContainsKey(baseId) && Event.current.shift)
            {
                float scaleFactor = 1f;
                switch (editAxis)
                {
                case EditAxis.X:
                    scaleFactor = s_OnClickSize[baseId].x > 0f ? size.x / s_OnClickSize[baseId].x : 0f;
                    break;

                case EditAxis.Y:
                    scaleFactor = s_OnClickSize[baseId].y > 0f ? size.y / s_OnClickSize[baseId].y : 0f;
                    break;

                case EditAxis.Z:
                    scaleFactor = s_OnClickSize[baseId].z > 0f ? size.z / s_OnClickSize[baseId].z : 0f;
                    break;
                }
                size = s_OnClickSize[baseId] * scaleFactor;
            }
            // use cached center if holding alt key
            if (s_OnClickCenter.ContainsKey(baseId) && Event.current.alt)
            {
                center = s_OnClickCenter[baseId];
            }
            // draw wire shape
            switch (type)
            {
            case WireShapeType.Box:
                DrawWireBox(size);
                break;

            case WireShapeType.Capsule:
                DrawWireCylinder(new CylinderProperties(height: size.y, radius: size.x * 0.5f), CylinderCap.Capsule);
                break;

            case WireShapeType.Cylinder:
                DrawWireCylinder(new CylinderProperties(height: size.y, radius: size.x * 0.5f), CylinderCap.Cylinder);
                break;

            case WireShapeType.Sphere:
                float radius = size.x * 0.5f;
                Handles.DrawWireDisc(Vector3.zero, Vector3.right, radius);
                Handles.DrawWireDisc(Vector3.zero, Vector3.up, radius);
                Handles.DrawWireDisc(Vector3.zero, Vector3.forward, radius);
                // TODO: get this working in non-identity orientations
//				Vector3 nml = Handles.matrix.MultiplyPoint(Vector3.zero) - Camera.current.transform.position;
//				float sqrMagRecip = 1f / nml.sqrMagnitude;
//				float sqrRadius = radius * radius;
//				radius = Mathf.Sqrt(sqrRadius - (sqrRadius * sqrRadius * sqrMagRecip));
//				Handles.DrawWireDisc(
//					Vector3.zero - sqrRadius * nml * sqrMagRecip, Handles.matrix.inverse.MultiplyVector(nml), radius
//				);
                break;
            }
            // reset handle matrix
            Handles.matrix = oldMatrix;
        }