public void UpdateCamera(GameTime gameTime, KeyboardState keyboard, MouseState mouse)
 {
     //Find the three spatial directions
     Vector3 forward = Vector3.Normalize(-CameraLocation);
     Vector3 side = Vector3.Normalize(Vector3.Cross(forward, CameraUp));
     CameraUp = Vector3.Normalize(Vector3.Cross(side, forward));
     float panSpeed = 0.75f * CameraLocation.Length();
     //The arrow pad rotates the screen
     if (keyboard.IsKeyDown(Keys.Up))
     {
         CameraLocation = Vector3.Transform(CameraLocation
             , Matrix.CreateFromAxisAngle(side, 0.75f * (float)gameTime.ElapsedGameTime.TotalSeconds));
     }
     if (keyboard.IsKeyDown(Keys.Down))
     {
         CameraLocation = Vector3.Transform(CameraLocation
             , Matrix.CreateFromAxisAngle(side, -0.75f * (float)gameTime.ElapsedGameTime.TotalSeconds));
     }
     if (keyboard.IsKeyDown(Keys.Q))
     {
         CameraUp = Vector3.Transform(CameraUp
             , Matrix.CreateFromAxisAngle(forward, -0.75f * (float)gameTime.ElapsedGameTime.TotalSeconds));
     }
     if (keyboard.IsKeyDown(Keys.E))
     {
         CameraUp = Vector3.Transform(CameraUp
             , Matrix.CreateFromAxisAngle(forward, 0.75f * (float)gameTime.ElapsedGameTime.TotalSeconds));
     }
     float endLength = CameraLocation.Length();
     endLength += (PreviousMouse.ScrollWheelValue - mouse.ScrollWheelValue)
          * panSpeed / 8.0f * (float)gameTime.ElapsedGameTime.TotalSeconds;
     //Page up/down and the mouse wheel controls zoom level
     if (keyboard.IsKeyDown(Keys.PageUp))
     {
         endLength -= panSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
     }
     if (keyboard.IsKeyDown(Keys.PageDown))
     {
         endLength += panSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
     }
     CameraLocation =
         Vector3.Normalize(CameraLocation)
         * endLength;
     if (endLength < 1.0f)
     {
         endLength = 1.0f;
     }
     Projection = Matrix.CreatePerspectiveFieldOfView(
         MathHelper.PiOver4
         , MyGame.graphics.GraphicsDevice.Viewport.AspectRatio
         , endLength * 0.0005f
         , 1000.0f + endLength * 25.0f);
     //WASD controls panning
     if (keyboard.IsKeyDown(Keys.Left))
     {
         CameraLocation = Vector3.Transform(CameraLocation
             , Matrix.CreateFromAxisAngle(CameraUp, 0.75f * (float)gameTime.ElapsedGameTime.TotalSeconds));
     }
     if (keyboard.IsKeyDown(Keys.Right))
     {
         CameraLocation = Vector3.Transform(CameraLocation
             , Matrix.CreateFromAxisAngle(CameraUp, -0.75f * (float)gameTime.ElapsedGameTime.TotalSeconds));
     }
     if (keyboard.IsKeyDown(Keys.W))
     {
         CameraFocus += forward * panSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
         FocalBody = null;
     }
     if (keyboard.IsKeyDown(Keys.S))
     {
         CameraFocus -= forward * panSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
         FocalBody = null;
     }
     if (keyboard.IsKeyDown(Keys.D))
     {
         CameraFocus += side * panSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
         FocalBody = null;
     }
     if (keyboard.IsKeyDown(Keys.A))
     {
         CameraFocus -= side * panSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
         FocalBody = null;
     }
     if (FocalBody != null)
     {
         FocalBodyFocusTimer -= gameTime.ElapsedGameTime.TotalSeconds;
         if (FocalBodyFocusTimer < 0.0)
         {
             FocalBodyFocusTimer = 0.0;
         }
         CameraFocus = Vector3.Lerp(CameraFocus, FocalBody.Bounds.Center
             , (float)Math.Pow(1.0 - FocalBodyFocusTimer, 1.5) + (float)gameTime.ElapsedGameTime.TotalSeconds);
     }
     //Recalculate the camera
     View = Matrix.CreateLookAt(
         CameraLocation + CameraFocus
         , CameraFocus
         , CameraUp);
 }
        public void Update(GameTime gameTime)
        {
            DebugText = "";

            KeyboardState keyboard = Keyboard.GetState();
            MouseState mouse = Mouse.GetState();
            UpdateCamera(gameTime, keyboard, mouse);
            cursor.Update();

            //Update the _3DObjects
            for (int i = 0; i < CelestialBodies.Count; i++)
            {
                CelestialBodies[i].Update(gameTime, Vector3.Zero, 0.0f);
                if (CelestialBodies[i].isInactive)
                {
                    CelestialBodies.RemoveAt(i--);
                    continue;
                }
            }
            #region Mouse Processing
            ContainingBodies.Clear();
            VisibleBodies.Clear();
            Ray ScreenCenter = Cursor.Unproject(new Vector2(GameWindow.Width, GameWindow.Height) / 2.0f);
            BoundingFrustum VisibleArea = new BoundingFrustum(
                View * Projection);
            Body.PartiallySortBodies(ScreenCenter, VisibleArea, ref CelestialBodies, ref VisibleBodies, ref ContainingBodies);
            for (int i = 0; i < VisibleBodies.Count; i++)
            {
                if (mouse.LeftButton == ButtonState.Pressed
                    && PreviousMouse.LeftButton == ButtonState.Released)
                {
                    float ButtonScale = 250.0f / (i + 10);
                    float DistanceToButtonCenter = (float)Math.Sqrt(Math.Pow(mouse.X - VisibleBodies[i].ScreenPosition.X, 2.0)
                        + Math.Pow(mouse.Y - VisibleBodies[i].ScreenPosition.Y, 2.0));
                    if (DistanceToButtonCenter <= ButtonScale)
                    {
                        FocalBody = VisibleBodies[i];
                        FocalBodyFocusTimer = 1.0;
                    }
                }
            }
            #endregion

            PreviousKeyboard = keyboard;
            PreviousMouse = mouse;
        }