Beispiel #1
0
        /// <returns>true, if an iteraction with the gizmo is happening</returns>
        public bool MouseMoved(Matrix4x4 viewProjection, Ray ray)
        {
            if (!DrawGizmo || _mode == GizmoMode.None)
            {
                return(false);
            }

            bool upside       = Orientation == GizmoOrientation.UpsideDown;
            bool flippedScale = false;

            // Flip sizing dimensions if object is rotateable on Y axis
            if ((_mode == GizmoMode.ScaleX || _mode == GizmoMode.ScaleZ) && SupportRotationY)
            {
                flippedScale = MathC.RadToDeg(RotationY) % 180.0f >= 45.0f;
            }

            // First get the ray in 3D space from X, Y mouse coordinates
            switch (_mode)
            {
            case GizmoMode.TranslateX:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitY, Vector3.UnitZ, out intersection))
                {
                    GizmoMove(new Vector3(intersection.X - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier, Position.Y, Position.Z));
                    GizmoMoveDelta(new Vector3(intersection.X - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier - Position.X, 0.0f, 0.0f));
                }
            }
            break;

            case GizmoMode.TranslateY:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitZ, out intersection))
                {
                    GizmoMove(new Vector3(Position.X, intersection.Y - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier, Position.Z));
                    GizmoMoveDelta(new Vector3(0.0f, intersection.Y - (upside ? -Size : Size) * _arrowHeadOffsetMultiplier - Position.Y, 0.0f));
                }
            }
            break;

            case GizmoMode.TranslateZ:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitY, out intersection))
                {
                    GizmoMove(new Vector3(Position.X, Position.Y, intersection.Z + (upside ? -Size : Size) * _arrowHeadOffsetMultiplier));
                    GizmoMoveDelta(new Vector3(0.0f, 0.0f, intersection.Z + (upside ? -Size : Size) * _arrowHeadOffsetMultiplier - Position.Z));
                }
            }
            break;

            case GizmoMode.ScaleX:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitY, Vector3.UnitZ, out intersection))
                {
                    if (flippedScale)
                    {
                        GizmoScaleZ(_scaleBase.Z * (float)Math.Exp(_scaleSpeed * (intersection.X - Position.X)));
                    }
                    else
                    {
                        GizmoScaleX(_scaleBase.X * (float)Math.Exp(_scaleSpeed * (intersection.X - Position.X)));
                    }
                }
            }
            break;

            case GizmoMode.ScaleY:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitZ, out intersection))
                {
                    GizmoScaleY(_scaleBase.Y * (float)Math.Exp(_scaleSpeed * (intersection.Y - Position.Y)));
                }
            }
            break;

            case GizmoMode.ScaleZ:
            {
                Vector3 intersection;
                if (ConstructPlaneIntersection(Position, viewProjection, ray, Vector3.UnitX, Vector3.UnitY, out intersection))
                {
                    if (flippedScale)
                    {
                        GizmoScaleX(_scaleBase.X * (float)Math.Exp(_scaleSpeed * -(intersection.Z - Position.Z)));
                    }
                    else
                    {
                        GizmoScaleZ(_scaleBase.Z * (float)Math.Exp(_scaleSpeed * -(intersection.Z - Position.Z)));
                    }
                }
            }
            break;

            case GizmoMode.RotateY:
            {
                Plane   rotationPlane = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitY, RotateMatrixY));
                Vector3 rotationIntersection;
                if (Collision.RayIntersectsPlane(ray, rotationPlane, out rotationIntersection))
                {
                    Vector3 direction = rotationIntersection - Position;
                    _rotationLastMouseRadius = direction.Length();
                    direction = Vector3.Normalize(direction);

                    float sin = Vector3.Dot(Vector3.UnitZ, direction);
                    float cos = Vector3.Dot(rotationPlane.Normal, Vector3.Cross(Vector3.UnitZ, direction));
                    _rotationLastMouseAngle = (float)Math.Atan2(-sin, cos);
                    GizmoRotateY(SimplifyAngle(_rotationPickAngleOffset + _rotationLastMouseAngle));
                }
            }
            break;

            case GizmoMode.RotateX:
            {
                Plane   rotationPlane = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitX, RotateMatrixX));
                Vector3 rotationIntersection;
                if (Collision.RayIntersectsPlane(ray, rotationPlane, out rotationIntersection))
                {
                    Vector3 direction = rotationIntersection - Position;
                    _rotationLastMouseRadius = direction.Length();
                    direction = Vector3.Normalize(direction);

                    float sin = Vector3.Dot(Vector3.UnitY, direction);
                    float cos = Vector3.Dot(rotationPlane.Normal, Vector3.Cross(Vector3.UnitY, direction));
                    _rotationLastMouseAngle = (float)Math.Atan2(-sin, cos);
                    GizmoRotateX(SimplifyAngle(_rotationPickAngleOffset + _rotationLastMouseAngle));
                }
            }
            break;

            case GizmoMode.RotateZ:
            {
                Plane   rotationPlane = MathC.CreatePlaneAtPoint(Position, MathC.HomogenousTransform(Vector3.UnitZ, RotateMatrixZ));
                Vector3 rotationIntersection;
                if (Collision.RayIntersectsPlane(ray, rotationPlane, out rotationIntersection))
                {
                    Vector3 direction = rotationIntersection - Position;
                    _rotationLastMouseRadius = direction.Length();
                    direction = Vector3.Normalize(direction);

                    float sin = Vector3.Dot(Vector3.UnitY, direction);
                    float cos = Vector3.Dot(rotationPlane.Normal, Vector3.Cross(Vector3.UnitY, direction));
                    _rotationLastMouseAngle = (float)Math.Atan2(-sin, cos);
                    GizmoRotateZ(SimplifyAngle(_rotationPickAngleOffset + _rotationLastMouseAngle));
                }
            }
            break;
            }

            return(true);
        }