Пример #1
0
            /// <summary>
            /// Rotates the trackball.
            /// </summary>
            /// <param name="cameraMode">The camera mode.</param>
            /// <param name="p1">The p1.</param>
            /// <param name="p2">The p2.</param>
            /// <param name="rotateAround">The rotate around.</param>
            /// <param name="sensitivity">The sensitivity.</param>
            /// <param name="viewportWidth">Width of the viewport.</param>
            /// <param name="viewportHeight">Height of the viewport.</param>
            /// <param name="camera">The camera.</param>
            /// <param name="invertFactor">The invert factor. Right Handed System = 1; LeftHandedSystem = -1;</param>
            /// <param name="newPosition">The new position.</param>
            /// <param name="newLookDirection">The new look direction.</param>
            /// <param name="newUpDirection">The new up direction.</param>
            public static void RotateTrackball(CameraMode cameraMode, ref Vector2 p1, ref Vector2 p2, ref Vector3 rotateAround,
                                               float sensitivity,
                                               int viewportWidth, int viewportHeight, CameraCore camera, int invertFactor,
                                               out Vector3 newPosition, out Vector3 newLookDirection, out Vector3 newUpDirection)
            {
                // http://viewport3d.com/trackball.htm
                // http://www.codeplex.com/3DTools/Thread/View.aspx?ThreadId=22310
                var v1  = ProjectToTrackball(p1, viewportWidth, viewportHeight);
                var v2  = ProjectToTrackball(p2, viewportWidth, viewportHeight);
                var cUP = Vector3.Normalize(camera.UpDirection);
                // transform the trackball coordinates to view space
                var viewZ = Vector3.Normalize(camera.LookDirection * invertFactor);
                var viewX = Vector3.Normalize(Vector3.Cross(cUP, viewZ)) * invertFactor;
                var viewY = Vector3.Cross(viewX, viewZ);
                var u1    = (viewZ * v1.Z) + (viewX * v1.X) + (viewY * v1.Y);
                var u2    = (viewZ * v2.Z) + (viewX * v2.X) + (viewY * v2.Y);

                // Could also use the Camera ViewMatrix
                // var vm = Viewport3DHelper.GetViewMatrix(this.ActualCamera);
                // vm.Invert();
                // var ct = new MatrixTransform3D(vm);
                // var u1 = ct.Transform(v1);
                // var u2 = ct.Transform(v2);

                // Find the rotation axis and angle
                var axis = Vector3.Cross(u1, u2);

                if (axis.LengthSquared() < 1e-8)
                {
                    newPosition      = camera.Position;
                    newLookDirection = camera.LookDirection;
                    newUpDirection   = camera.UpDirection;
                    return;
                }

                var angle = VectorExtensions.AngleBetween(u1, u2);

                // Create the transform
                var rotate = Matrix.RotationAxis(Vector3.Normalize(axis), -angle * sensitivity * 5);

                // Find vectors relative to the rotate-around point
                var relativeTarget   = rotateAround - camera.Target;
                var relativePosition = rotateAround - camera.Position;

                // Rotate the relative vectors
                var newRelativeTarget   = Vector3.TransformCoordinate(relativeTarget, rotate);
                var newRelativePosition = Vector3.TransformCoordinate(relativePosition, rotate);

                newUpDirection = Vector3.TransformNormal(cUP, rotate);

                // Find new camera position
                var newTarget = rotateAround - newRelativeTarget;

                newPosition = rotateAround - newRelativePosition;

                newLookDirection = newTarget - newPosition;
                if (cameraMode != CameraMode.Inspect)
                {
                    newPosition = camera.Position;
                }
            }