Yet Another Camera Class. [YACC]

Well i forgot all about this, I wrote this after a post between me and kwyky about the createlookat function. I meant to post it and forgot about it. This is like a 3d space sim camera. i could of fixed the y axis or done it a bit more but i never got around to it still its good for what it is a simple camera.

The idea was.

You add a world space object to a class.
You can then control it using the Input class.
Send it to the view space camera transformer.
You get back a combined worldviewprojection matrix.
Then you can send that to your shader.

It comprises of a WorldObjectSpace class made so that you can add a instance of this to your objects to move them around.

A ViewSpaceCameraTransform this is meant to turn any object that has a WorldObjectSpace instance in it into a camera. E.g. you can switch between objects as if they are the camera itself.

There is also a User Input controller class, its not that hot but its there just to move around the camera objects. It’s a work in progress

So here’s my World object camera class.

Edit:
This is the original as i have worked on it i have made and posted amendments.
I have left them in place so you can see the progression as it continued
I add things as i have need of them
Hopefully this will serve as a basic reference for creating a camera.
Edit2 The mouse look won’t work till the third update.

    using System;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;

    namespace CameraOperations
    {
        /// <summary>
        /// Haven't set up a camera ? Don't feel like setting up stuff to move or rotate it
        /// Lazy like me ? Maybe this will help.
        /// Any world object could be a Camera.
        /// </summary>
        public class WorldSpaceObject
        {
            public Matrix world = Matrix.Identity;
            public Vector3 Position
            {
                get { return world.Translation; }
                set { world.Translation = value; }
            }
            public Vector3 Forward
            {
                get { return world.Forward; }
                set { world = Matrix.CreateWorld(world.Translation, value, world.Up); }
            }
            /// <summary>
            /// Move on a dimensional vector axis of the object itself. Note, we dont use the system vectors for this.
            /// </summary>
            public void Move(Vector3 moveSpeedInEachAxis)
            {
                var motion =
                    moveSpeedInEachAxis.X * world.Right +
                    moveSpeedInEachAxis.Y * world.Up +
                    moveSpeedInEachAxis.Z * world.Forward
                    ;
                Position += motion;
            }
            /// <summary>
            /// We designate the dimensional speed of rotation in dimension x y or z upon a perpendicular axis. 
            /// We may change the cc or ccw of rotation by using the reverse inverted axis vector. or just negating
            /// </summary>
            public void Rotate(Vector3 turnSpeedInDimension)
            {
                Vector3 temp = world.Translation;
                world *=
                    Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z) *
                    Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
                    Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
                    ;
                Forward = world.Forward;
                world.Translation = temp;
            }
        }


        /// <summary>
        /// This class takes a world space object to create a view camera. Via CreateCameraViewSpace.
        /// You then get a combined world view projection matrix from GetWorldViewProjection.
        /// </summary>
        public class ViewSpaceCameraTransformer
        {
            public Vector3 OffsetPosition { get; set; }
            public Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver2, GraphicsDeviceManager.DefaultBackBufferWidth / GraphicsDeviceManager.DefaultBackBufferHeight, .5f, 1000);
            private Matrix viewSpace = Matrix.Identity;
            /// <summary>
            /// creates a camera view space matrixs and stores it
            /// </summary>
            public void CreateCameraViewSpace(WorldSpaceObject worldObjectToUseAsCamera)
            {
                viewSpace = Matrix.CreateLookAt
                    (
                    worldObjectToUseAsCamera.Position + OffsetPosition,
                    worldObjectToUseAsCamera.Forward + (worldObjectToUseAsCamera.Position + OffsetPosition),
                    worldObjectToUseAsCamera.world.Up
                    );
            }
            /// <summary>
            /// Takes a world space object matrix and transforms it by view and projection space matrixs into screen space
            /// </summary>
            public Matrix GetWorldViewProjection(WorldSpaceObject worldObject)
            {
                return worldObject.world * viewSpace * projection;
            }
        }

        /// <summary>
        /// Use keys mouse or what not To move WorldSpaceObjects Around.
        /// This could probably be better.
        /// </summary>
        public class UserInputToOrientWorldObject
        {
            Vector3 turnOnAxis = Vector3.Zero;
            Vector3 moveInAxis = Vector3.Zero;
            float SpeedMovement = .01f;
            float SpeedRotational = .01f;
            bool didAnyChangeOccur = false;
            public bool HasChangeOccured { get { return didAnyChangeOccur; } }
            Vector2 windowcenter = new Vector2(GraphicsDeviceManager.DefaultBackBufferWidth * .5f, GraphicsDeviceManager.DefaultBackBufferHeight * .5f);

            public Keys KeyMoveRight = Keys.D;
            public Keys KeyMoveLeft = Keys.A;
            public Keys KeyMoveUp = Keys.W;
            public Keys KeyMoveDown = Keys.S;
            public Keys KeyMoveForward = Keys.E;
            public Keys KeyMoveBack = Keys.Q;

            public Keys KeyLookRight = Keys.Right;
            public Keys KeyLookLeft = Keys.Left;
            public Keys KeyLookUp = Keys.Up;
            public Keys KeyLookDown = Keys.Down;
            public Keys KeySpinCW = Keys.Z;
            public Keys KeySpinCCW = Keys.C;

            private bool useMouseLook = false;
            // if this is never called will just use the default key assignments
            public bool UseMouseLook
            {
                get { return useMouseLook; }
                set
                {
                    if (value)
                    {
                        KeyMoveForward = Keys.W;
                        KeyMoveBack = Keys.S;
                        // just move them out of the way
                        KeyMoveUp = Keys.Home;
                        KeyMoveDown = Keys.PageUp;
                    }
                    else
                    {
                        KeyMoveRight = Keys.D;
                        KeyMoveLeft = Keys.A;
                        KeyMoveUp = Keys.W;
                        KeyMoveDown = Keys.S;
                        KeyMoveForward = Keys.E;
                        KeyMoveBack = Keys.Q;
                    }
                    useMouseLook = value;
                }
            }

            public void SetWindowSizeRequiredForMouseLook(GraphicsDevice g)
            {
                windowcenter = new Vector2(g.Viewport.Width * .5f, g.Viewport.Height * .5f);
            }
            public void SetWindowSizeRequiredForMouseLook(int width, int height)
            {
                windowcenter = new Vector2(width * .5f, height * .5f);
            }

            public WorldSpaceObject UpdateOrientation(WorldSpaceObject worldObj)
            {
                didAnyChangeOccur = false;
                if (useMouseLook)
                {
                    MouseLook();
                    Move();
                }
                else
                {
                    Rotate();
                    Move();
                }
                if (didAnyChangeOccur)
                {
                    worldObj.Move(moveInAxis);
                    worldObj.Rotate(turnOnAxis);
                }
                return worldObj;
            }

            private void Rotate()
            {
                turnOnAxis = Vector3.Zero;
                if (Keyboard.GetState().IsKeyDown(KeySpinCCW)) // roll ccw
                {
                    turnOnAxis.Z = -SpeedRotational;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeySpinCW)) // roll cw
                {
                    turnOnAxis.Z = SpeedRotational;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyLookLeft)) // r ccw
                {
                    turnOnAxis.X = SpeedRotational;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyLookRight)) // r cw
                {
                    turnOnAxis.X = -SpeedRotational;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyLookUp)) // u cw
                {
                    turnOnAxis.Y = SpeedRotational;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyLookDown)) // d ccw
                {
                    turnOnAxis.Y = -SpeedRotational;
                    didAnyChangeOccur = true;
                }
            }

            private void Move()
            {
                moveInAxis = Vector3.Zero;
                if (Keyboard.GetState().IsKeyDown(KeyMoveForward)) // Forward
                {
                    moveInAxis.Z = SpeedMovement;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyMoveBack)) // back
                {
                    moveInAxis.Z = -SpeedMovement;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyMoveLeft)) // left
                {
                    moveInAxis.X = -SpeedMovement;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyMoveRight)) // right
                {
                    moveInAxis.X = SpeedMovement;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyMoveDown)) // down
                {
                    moveInAxis.Y = -SpeedMovement;
                    didAnyChangeOccur = true;
                }
                if (Keyboard.GetState().IsKeyDown(KeyMoveUp)) // up
                {
                    moveInAxis.Y = SpeedMovement;
                    didAnyChangeOccur = true;
                }
            }

            private void MouseLook()
            {
                turnOnAxis = Vector3.Zero;
                Vector2 mousePos = new Vector2(Mouse.GetState().Position.X, Mouse.GetState().Position.Y) - windowcenter;
                Vector2 mouseAngle = Vector2.Normalize(mousePos);
                if (Mouse.GetState().LeftButton == ButtonState.Pressed)
                {
                    Matrix r = Matrix.Identity;
                    mousePos.Normalize();

                    if (mousePos.Y > 5f)
                    {
                        turnOnAxis.Y = SpeedRotational * mouseAngle.Y;
                        didAnyChangeOccur = true;
                    }
                    if (mousePos.Y < 5f)
                    {
                        turnOnAxis.Y = SpeedRotational * mouseAngle.Y;
                        didAnyChangeOccur = true;
                    }
                    if (mousePos.X > 5f)
                    {
                        turnOnAxis.X = SpeedRotational * mouseAngle.X;
                        didAnyChangeOccur = true;
                    }
                    if (mousePos.X < 5f)
                    {
                        turnOnAxis.X = SpeedRotational * mouseAngle.X;
                        didAnyChangeOccur = true;
                    }
                }
            }
        }
    }

It’s not tested a lot but
It seems to work pretty well from as much as i did test it.
I don’t think i ever tested the mouse look input at all though…

using it in update looks something like this.

            // were cam and someobject are or contain a WorldspaceObject
            cam = uiInput.UpdateOrientation(cam);
            if (uiInput.HasChangeOccured)
            {
                transformer.CreateCameraViewSpace(cam);
            }
            // this might end up in draw.
            worldviewprojection = transformer.GetWorldViewProjection(cam);
            // or
            worldviewprojection = transformer.GetWorldViewProjection(someobj_B);

.

Edit:

The following amendments have been since made to the above set of classes.

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

// Replace the below namespace with your own projects namespace
namespace CameraOperations 
{
    /// <summary>
    /// Haven't set up a camera ? 
    /// Don't feel like setting up stuff to move or rotate
    /// Add one of these objects to your class.
    /// </summary>
    public class WorldSpaceObject
    {
        public Matrix world = Matrix.Identity;

        /// <summary>
        /// While the rotations are in fact axis angle rotations. 
        /// About the current objects orientation, we still have a multiplication order.
        /// </summary>
        public bool UseYawPitchRollToRotate 
        { 
            get; 
            set; 
        }
        public Vector3 Position
        {
            get { return world.Translation; }
            set { world.Translation = value; }
        }
        public Vector3 Forward
        {
            get { return world.Forward; }
            set { world = Matrix.CreateWorld(world.Translation, value, world.Up); }
        }
        /// <summary>
        /// Move on a dimensional vector axis of the object itself. Note, we dont use the system vectors for this.
        /// </summary>
        public void Move(Vector3 moveSpeedInEachAxis)
        {
            var motion =
                moveSpeedInEachAxis.X * world.Right +
                moveSpeedInEachAxis.Y * world.Up +
                moveSpeedInEachAxis.Z * world.Forward
                ;
            Position += motion;
        }
        /// <summary>
        /// We designate the dimensional speed of rotation in dimension x y or z upon a perpendicular axis. 
        /// We may change the cw or ccw of rotation by using the reverse inverted axis vector. or just negating
        /// </summary>
        public void Rotate(Vector3 turnSpeedInDimension)
        {
            Vector3 temp = world.Translation;
            if (UseYawPitchRollToRotate)
            {        
                world *=
                    Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y) *
                    Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
                    Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z)
                    ;
                Forward = world.Forward;
            }
            else
            {
                world *=
                    Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z) *
                    Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
                    Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
                    ;
                Forward = world.Forward;     
            }
            world.Translation = temp;
        }
    }


    /// <summary>
    /// This class takes a world space object to create a view camera. Via CreateCameraViewSpace.
    /// You then get a combined world view projection matrix from GetWorldViewProjection.
    /// </summary>
    public class ViewSpaceCameraTransformer
    {
        private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver2, GraphicsDeviceManager.DefaultBackBufferWidth / GraphicsDeviceManager.DefaultBackBufferHeight, .5f, 1000);
        private Matrix viewSpace = Matrix.Identity;
        private Matrix combinedViewProjection;

        /// <summary>
        /// This can be used as a camera offset such as for a chase view.
        /// </summary>
        public Vector3 OffsetPosition 
        { 
            get; 
            set; 
        }
        /// <summary>
        /// Get a default projection matrix or set a new one
        /// </summary>
        public Matrix Projection
        {
            get
            {
                return projection;
            }
            set
            {
                projection = value;
                combinedViewProjection = viewSpace * projection; 
            }
        }
        /// <summary>
        /// creates a camera view space, matrice and stores it.
        /// </summary>
        public void CreateCameraViewSpace(WorldSpaceObject worldObjectToUseAsCamera)
        {
            viewSpace = Matrix.CreateLookAt
                (
                worldObjectToUseAsCamera.Position + OffsetPosition,
                worldObjectToUseAsCamera.Forward + (worldObjectToUseAsCamera.Position + OffsetPosition),
                worldObjectToUseAsCamera.world.Up
                );
            combinedViewProjection = viewSpace * projection;
        }
        /// <summary>
        /// Takes a world space object matrice and transforms it. 
        /// By the view and projection matrixs into screen space.
        /// </summary>
        public Matrix GetWorldViewProjection(WorldSpaceObject worldObject)
        {
            return worldObject.world * combinedViewProjection;
        }
    }

    /// <summary>
    /// Use keys mouse or what not To move WorldSpaceObjects Around.
    /// This could probably be better.
    /// </summary>
    public class UserInputToOrientWorldObject
    {
        Vector3 turnOnAxis = Vector3.Zero;
        Vector3 moveInAxis = Vector3.Zero;
        float SpeedMovement = .01f;
        float SpeedRotational = .01f;
        bool didAnyChangeOccur = false;
        public bool HasChangeOccured { get { return didAnyChangeOccur; } }
        Vector2 windowcenter = new Vector2(GraphicsDeviceManager.DefaultBackBufferWidth * .5f, GraphicsDeviceManager.DefaultBackBufferHeight * .5f);
        KeyboardState keyStates;
        MouseState mouseStates;

        public Keys KeyMoveRight = Keys.D;
        public Keys KeyMoveLeft = Keys.A;
        public Keys KeyMoveUp = Keys.W;
        public Keys KeyMoveDown = Keys.S;
        public Keys KeyMoveForward = Keys.E;
        public Keys KeyMoveBack = Keys.Q;

        public Keys KeyLookRight = Keys.Right;
        public Keys KeyLookLeft = Keys.Left;
        public Keys KeyLookUp = Keys.Up;
        public Keys KeyLookDown = Keys.Down;
        public Keys KeySpinCW = Keys.Z;
        public Keys KeySpinCCW = Keys.C;

        private bool useMouseLook = false;
        // if this is never called will just use the default key assignments
        public bool UseMouseLook
        {
            get { return useMouseLook; }
            set
            {
                if (value)
                {
                    KeyMoveForward = Keys.W;
                    KeyMoveBack = Keys.S;
                    // just move them out of the way
                    KeyMoveUp = Keys.Home;
                    KeyMoveDown = Keys.PageUp;
                }
                else
                {
                    KeyMoveRight = Keys.D;
                    KeyMoveLeft = Keys.A;
                    KeyMoveUp = Keys.W;
                    KeyMoveDown = Keys.S;
                    KeyMoveForward = Keys.E;
                    KeyMoveBack = Keys.Q;
                }
                useMouseLook = value;
            }
        }

        public void SetWindowSizeRequiredForMouseLook(GraphicsDevice g)
        {
            windowcenter = new Vector2(g.Viewport.Width * .5f, g.Viewport.Height * .5f);
        }
        public void SetWindowSizeRequiredForMouseLook(int width, int height)
        {
            windowcenter = new Vector2(width * .5f, height * .5f);
        }

        public WorldSpaceObject UpdateOrientation(WorldSpaceObject worldObj)
        {
            didAnyChangeOccur = false;
            keyStates = Keyboard.GetState();
            mouseStates = Mouse.GetState();
            if (useMouseLook)
            {
                MouseLook();
                Move();
            }
            else
            {
                Rotate();
                Move();
            }
            if (didAnyChangeOccur)
            {
                worldObj.Move(moveInAxis);
                worldObj.Rotate(turnOnAxis);
            }
            return worldObj;
        }

        private void Rotate()
        {
            turnOnAxis = Vector3.Zero;
            if (keyStates.IsKeyDown(KeySpinCCW)) // roll ccw
            {
                turnOnAxis.Z = -SpeedRotational;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeySpinCW)) // roll cw
            {
                turnOnAxis.Z = SpeedRotational;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookLeft)) // r ccw
            {
                turnOnAxis.X = SpeedRotational;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookRight)) // r cw
            {
                turnOnAxis.X = -SpeedRotational;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookUp)) // u cw
            {
                turnOnAxis.Y = SpeedRotational;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookDown)) // d ccw
            {
                turnOnAxis.Y = -SpeedRotational;
                didAnyChangeOccur = true;
            }
        }

        private void Move()
        {
            moveInAxis = Vector3.Zero;
            if (keyStates.IsKeyDown(KeyMoveForward)) // Forward
            {
                moveInAxis.Z = SpeedMovement;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveBack)) // back
            {
                moveInAxis.Z = -SpeedMovement;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveLeft)) // left
            {
                moveInAxis.X = -SpeedMovement;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveRight)) // right
            {
                moveInAxis.X = SpeedMovement;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveDown)) // down
            {
                moveInAxis.Y = -SpeedMovement;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveUp)) // up
            {
                moveInAxis.Y = SpeedMovement;
                didAnyChangeOccur = true;
            }
        }

        private void MouseLook()
        {
            turnOnAxis = Vector3.Zero;
            Vector2 mousePos = new Vector2(mouseStates.Position.X, mouseStates.Position.Y) - windowcenter;
            Vector2 mouseAngle = Vector2.Normalize(mousePos);

            //if (mouseStates.LeftButton == ButtonState.Pressed)
            //{
            Matrix r = Matrix.Identity;
            mousePos.Normalize();

            if (mousePos.Y > 5f)
            {
                turnOnAxis.Y = SpeedRotational * mouseAngle.Y;
                didAnyChangeOccur = true;
            }
            if (mousePos.Y < 5f)
            {
                turnOnAxis.Y = SpeedRotational * mouseAngle.Y;
                didAnyChangeOccur = true;
            }
            if (mousePos.X > 5f)
            {
                turnOnAxis.X = SpeedRotational * mouseAngle.X;
                didAnyChangeOccur = true;
            }
            if (mousePos.X < 5f)
            {
                turnOnAxis.X = SpeedRotational * mouseAngle.X;
                didAnyChangeOccur = true;
            }
            //}
        }
    }
}
1 Like

small optimizations

You use Keyboard.GetState() all over again - for each key actually. Same for Mouse.GetState().
That’s not great, since it doesn’t get cached in the background.

So you should save it to _currentState at the beginning of your update loop and use that value then.

If you want to see for yourself
this will make your program come to a complete halt

for (int i = 0; i<10000;i++)
            keyboardState = Keyboard.GetState();

this will not change a thing

    KeyboardState keyboardState2 = Keyboard.GetState();

    for (int i = 0; i < 10000; i++)
        keyboardState = keyboardState2;

If you have a million objects that need to be transformed each frame there is another thing you want to optimize is this:

public Matrix GetWorldViewProjection(WorldSpaceObject worldObject)
            {
                return worldObject.world * viewSpace * projection;
            }

the viewSpace * projection matrix multiplication is always the same, just calculate that when calculating view and use

return worldObject.world * viewSpaceProjection;

instead

Thank you a good catch, i will make the amendments to the original post.

I made another amendment to this class that i think i should add as it makes a good example of how to time things independent of the frame rate.

So if your running at 60 fps or 1000 things will move or rotate based on a fixed amount of actual time that you set.

That amount is scaled to the portion of a second that has passed since the last update so that things will move and rotate smoothly no matter how many fps your getting. Although i have called it CameraTimer it is simply a Timer class and can be used for a variety of things.

So to the ui input class above i made the following amendments and added a camera timer class.

        public class CameraTimer
        {
            float percentage = 0f;
            float timerLast = 0f;
            float timerNow = 0f;
            float elapsed = 0f;
            float timer = 1f;
            bool triggered = false;

            /// <summary>
            /// Timer will loop from 0 to 1 by the number of seconds specified
            /// </summary>
            public CameraTimer(float TimerInSeconds)
            {
                timer = 1f / TimerInSeconds;
            }
            /// <summary>
            /// Gets the percentage of the given timer that has elapsed
            /// </summary>
            public float Get { get { return percentage; } }
            /// <summary>
            /// Used to gauge things by time such as amounts of movement or speed of movement
            /// </summary>
            public float GetElapsedSMilliSeconds { get { return elapsed * 1000f; } }
            /// <summary>
            /// When the timmer reaches the set time this will evaluate to true
            /// </summary>
            public bool IsTriggered { get { return triggered; } }
            /// <summary>
            /// just like the constructor you set the timer in seconds
            /// </summary>
            public void SetTimingAmount(float TimerInSeconds)
            {
                timer = 1f / TimerInSeconds;
            }
            /// <summary>
            /// Gets a value ranging from 0 to 1 of the elapsed time specified
            /// </summary>
            public float UpdateTimer(GameTime gameTime)
            {
                timerLast = timerNow;
                timerNow = (float)gameTime.TotalGameTime.TotalSeconds;
                elapsed = timerNow - timerLast;
                percentage += elapsed * timer;
                triggered = false;
                if (percentage > 1f) { percentage = percentage - 1f; triggered = true; }
                return percentage;
            }
        }

The amendments to the previous class.

    /// <summary>
    /// Use keys mouse or what not To move WorldSpaceObjects Around.
    /// This could probably be better.
    /// </summary>
    public class UserInputToOrientWorldObject
    {
        Vector3 turnOnAxis = Vector3.Zero;
        Vector3 moveInAxis = Vector3.Zero;
        public float SpeedMovement = 100f;
        public float SpeedRotational = .5f;
        bool didAnyChangeOccur = false;
        public bool HasChangeOccured { get { return didAnyChangeOccur; } }
        Vector2 windowcenter = new Vector2(GraphicsDeviceManager.DefaultBackBufferWidth * .5f, GraphicsDeviceManager.DefaultBackBufferHeight * .5f);
        KeyboardState keyStates;
        MouseState mouseStates;
        public CameraTimer timing = new CameraTimer(1f);

        public Keys KeyMoveRight = Keys.D;
        public Keys KeyMoveLeft = Keys.A;
        public Keys KeyMoveUp = Keys.W;
        public Keys KeyMoveDown = Keys.S;
        public Keys KeyMoveForward = Keys.E;
        public Keys KeyMoveBack = Keys.Q;

        public Keys KeyLookRight = Keys.Right;
        public Keys KeyLookLeft = Keys.Left;
        public Keys KeyLookUp = Keys.Up;
        public Keys KeyLookDown = Keys.Down;
        public Keys KeySpinCW = Keys.Z;
        public Keys KeySpinCCW = Keys.C;

        private bool useMouseLook = false;
        // if this is never called will just use the default key assignments
        public bool UseMouseLook
        {
            get { return useMouseLook; }
            set
            {
                if (value)
                {
                    KeyMoveForward = Keys.W;
                    KeyMoveBack = Keys.S;
                    // just move them out of the way
                    KeyMoveUp = Keys.Home;
                    KeyMoveDown = Keys.PageUp;
                }
                else
                {
                    KeyMoveRight = Keys.D;
                    KeyMoveLeft = Keys.A;
                    KeyMoveUp = Keys.W;
                    KeyMoveDown = Keys.S;
                    KeyMoveForward = Keys.E;
                    KeyMoveBack = Keys.Q;
                }
                useMouseLook = value;
            }
        }

        public void SetWindowSizeRequiredForMouseLook(GraphicsDevice g)
        {
            windowcenter = new Vector2(g.Viewport.Width * .5f, g.Viewport.Height * .5f);
        }
        public void SetWindowSizeRequiredForMouseLook(int width, int height)
        {
            windowcenter = new Vector2(width * .5f, height * .5f);
        }

        public WorldSpaceObject UpdateOrientation(WorldSpaceObject worldObj, GameTime gametime)
        {
            didAnyChangeOccur = false;
            keyStates = Keyboard.GetState();
            mouseStates = Mouse.GetState();
            timing.UpdateTimer(gametime);
            if (useMouseLook)
            {
                MouseLook();
                Move();
            }
            else
            {
                Rotate();
                Move();
            }
            if (didAnyChangeOccur)
            {
                worldObj.Move(moveInAxis);
                worldObj.Rotate(turnOnAxis);
            }
            return worldObj;
        }

        private void Rotate()
        {
            turnOnAxis = Vector3.Zero;
            var rotationspeed = SpeedRotational * timing.GetElapsedSMilliSeconds;
            if (keyStates.IsKeyDown(KeySpinCCW)) // roll ccw
            {
                turnOnAxis.Z = -rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeySpinCW)) // roll cw
            {
                turnOnAxis.Z = rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookLeft)) // r ccw
            {
                turnOnAxis.X = rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookRight)) // r cw
            {
                turnOnAxis.X = -rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookUp)) // u cw
            {
                turnOnAxis.Y = rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookDown)) // d ccw
            {
                turnOnAxis.Y = -rotationspeed;
                didAnyChangeOccur = true;
            }
        }

        private void Move()
        {
            moveInAxis = Vector3.Zero;
            var movespeed = SpeedMovement * timing.GetElapsedSMilliSeconds;
            if (keyStates.IsKeyDown(KeyMoveForward)) // Forward
            {
                moveInAxis.Z = movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveBack)) // back
            {
                moveInAxis.Z = -movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveLeft)) // left
            {
                moveInAxis.X = -movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveRight)) // right
            {
                moveInAxis.X = movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveDown)) // down
            {
                moveInAxis.Y = -movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveUp)) // up
            {
                moveInAxis.Y = movespeed;
                didAnyChangeOccur = true;
            }
        }
        // i still have never used this so its still untested.
        private void MouseLook()
        {
            turnOnAxis = Vector3.Zero;
            Vector2 mousePos = new Vector2(mouseStates.Position.X, mouseStates.Position.Y) - windowcenter;
            Vector2 mouseAngle = Vector2.Normalize(mousePos);

            //if (mouseStates.LeftButton == ButtonState.Pressed)
            //{
            Matrix r = Matrix.Identity;
            mousePos.Normalize();
            var rotationspeed = SpeedRotational * timing.GetElapsedSMilliSeconds;

            if (mousePos.Y > 5f)
            {
                turnOnAxis.Y = rotationspeed * mouseAngle.Y;
                didAnyChangeOccur = true;
            }
            if (mousePos.Y < 5f)
            {
                turnOnAxis.Y = rotationspeed * mouseAngle.Y;
                didAnyChangeOccur = true;
            }
            if (mousePos.X > 5f)
            {
                turnOnAxis.X = rotationspeed * mouseAngle.X;
                didAnyChangeOccur = true;
            }
            if (mousePos.X < 5f)
            {
                turnOnAxis.X = rotationspeed * mouseAngle.X;
                didAnyChangeOccur = true;
            }
            //}
        }
    }

I have updated my camera class once again to do quite a bit more its starting to grow a bit bigger now.

Previously the mouse look didn’t work properly as it was reversed, as well it had no smoothing that’s been added.

The camera only had 1 space sim like behavior i added a basic y Up behavior as well as a horizon behavior. Neither work as well as id like, ill probably revisit that at a later time.

There was no Scaling on objects thru the WorldSpaceObjects so i added 4 scale functions two of them implicitly negate the z axis. Used by the ViewSpaceCameraTransformer when building a final matrix.

    public class WorldSpaceObject
    {
        /// <summary>
        /// this is the primary pre- scaled and transformed world orientations
        /// </summary>
        public Matrix world = Matrix.Identity;
        
        /// <summary>
        /// This returns the orientation matrix without the translations.
        /// I.E this is the local rotations. 
        /// Typically ignored, it is here for convenience for shaders.
        /// </summary>
        public Matrix LocalOrientationMatrix 
        { 
            get 
            { 
                Matrix m = Matrix.Identity; 
                m.Forward = world.Forward;
                m.Right = world.Right;
                m.Up = world.Up;
                return m; 
            } 
        }

        /// <summary>
        /// gets just the scaling matrix for the world
        /// </summary>
        public Matrix ScaleMatrix
        {
            get;
            private set;
        }

        /// <summary>
        /// returns a scaled world matrix
        /// </summary>
        public Matrix ScaledWorldMatrix
        {
            get
            {
                var temp = world.Translation;
                var m = world * ScaleMatrix;
                m.Translation = temp;
                return m;
            }
        }

        /// <summary>
        /// Free type Behavior setting like a space sim.
        /// </summary>
        public const int UP_FREE_Y = 0;
        /// <summary>
        /// A basic fixed camera pointing straight up will spin you.
        /// Though no gimble lock will occur ill probably improve this later on
        /// </summary>
        public const int UP_FIXED_Y = 1;
        /// <summary>
        /// Free behavior for the most part but there is a gravitation to the horizon on the z axis.
        /// This is basically a planned forerunner to a automated panoramic waypoint steped scene camera.
        /// Calling rotate continually even with a vector3.Zero will auto rotate the camera to a horrizontal position.
        /// </summary>
        public const int UP_FREE_HORIZONTAL_Y = 2;
        
        private int upBehavior = 1;
        /// <summary>
        /// This changes the behavior to how a world object moves.
        /// These are primarily used by world objects that act as cameras.
        /// </summary>
        public int SetTheUpBehavior
        {
            set
            {
                upBehavior = value;
                if (value < 0 || value > 2) upBehavior = 0;
            }
        }

        /// <summary>
        /// While the rotations are in fact axis angle rotations. 
        /// About the current objects orientation, we still have a multiplication order.
        /// </summary>
        public bool UseYawPitchRollToRotate 
        { 
            get; 
            set; 
        }
        /// <summary>
        /// gets or sets the position in the world
        /// </summary>
        public Vector3 Position
        {
            get { return world.Translation; }
            set { world.Translation = value; }
        }
        /// <summary>
        /// gets or sets the forward directional orientation
        /// </summary>
        public Vector3 Forward
        {
            get { return world.Forward; }
            set { world = Matrix.CreateWorld(world.Translation, value, world.Up); }
        }
        /// <summary>
        /// Move on a dimensional vector axis of the object itself. Note, we dont use the system vectors for this.
        /// This is typically used by the uiCameraInput class or such as for an ai's movements.
        /// </summary>
        public void Move(Vector3 moveSpeedInEachAxis)
        {
            var motion =
                moveSpeedInEachAxis.X * world.Right +
                moveSpeedInEachAxis.Y * world.Up +
                moveSpeedInEachAxis.Z * world.Forward
                ;
            Position += motion;
        }

        // for reference
        //var crossFL = Vector3.Cross(F, L); // = up
        //var crossFU = Vector3.Cross(F, U); // = right 
        //var crossUR = Vector3.Cross(U, R); // = forward

        /// <summary>
        /// We designate the dimensional speed of rotation in dimension x y or z upon a perpendicular axis. 
        /// We may change the cw or ccw of rotation by using the reverse or negated axis vector or any component thereof.
        /// </summary>
        public void Rotate(Vector3 turnSpeedInDimension)
        {
            Vector3 up = world.Up;
            Vector3 temp = world.Translation;
            switch (upBehavior)
            {
                // free floating look the camera.
                case UP_FREE_Y: 
                    if (UseYawPitchRollToRotate)
                    {
                        world *=
                            Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y) *
                            Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
                            Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z)
                            ;
                        Forward = world.Forward;
                    }
                    else
                    {
                        world *=
                            Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z) *
                            Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
                            Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
                            ;
                        Forward = world.Forward;
                    }
                    world.Translation = temp;
                    break;
                // this is basically a fixed camera we dissallow z rotations
                case UP_FIXED_Y: 
                    if (UseYawPitchRollToRotate)
                    {
                        world = world
                            * Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
                            * Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X)
                            ;
                    }
                    else
                    {
                        world = world
                            * Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X)
                            * Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
                            ;
                    }
                    // partially lerped
                    up = ((new Vector3(0f, .99f, 0f) - world.Up) * .03f) + world.Up;
                    world = Matrix.CreateWorld(world.Translation, world.Forward, up);
                    world.Translation = temp;
                    break;
                // similar to a free camera
                case UP_FREE_HORIZONTAL_Y:
                    if (UseYawPitchRollToRotate)
                    {
                        world *=
                            Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y) *
                            Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
                            Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z)
                            ;
                    }
                    else
                    {
                        world *=
                             Matrix.CreateFromAxisAngle(world.Forward, turnSpeedInDimension.Z) *
                             Matrix.CreateFromAxisAngle(world.Up, turnSpeedInDimension.X) *
                             Matrix.CreateFromAxisAngle(world.Right, turnSpeedInDimension.Y)
                             ;
                    }
                    // set weights, 
                    // these form a ratio to each other and effect blending formulas.
                    float weightup = 20f;
                    float weightmid = 50f;
                    // ranged virtual average, basically a double weighted binomiminal.
                    var dotFu = Vector3.Dot(world.Forward, Vector3.Up);
                    // the Acos and Absolute.
                    // the meaning here of this value is it increases to 1 from 0 when we are look straight up or down.
                    // we are using these directions specifically due to how createworld(...) and createlookat(...) function.
                    dotFu *= dotFu;
                    // in this case well ensure that the inverse of 0 becomes 1.
                    var invFu = 1.001f / (dotFu + .001f);
                    // this value allows the weighted middle to act as a floating scalar against the upweight 
                    // and a counterbalance to the midweight
                    float invwgtmid = 1f / weightmid;
                    var up1 = (world.Up * (dotFu * weightup));
                    var up2 = (invFu * invwgtmid * Vector3.Up) + (invFu * weightmid * world.Up);
                    up = up1 + up2;
                    up.Normalize();
                    world = Matrix.CreateWorld(world.Translation, world.Forward, up);
                    world.Translation = temp;
                    break;
            }
        }
        /// <summary>
        /// This creates a world scale matrix with a corrected z
        /// </summary>
        public void Scale(float scale)
        {
            ScaleMatrix = Matrix.CreateScale(scale, scale, -scale);
        }
        /// <summary>
        /// This creates a world scale matrix with a corrected z
        /// </summary>
        public void Scale(Vector3 scale)
        {
            ScaleMatrix = Matrix.CreateScale(scale.X, scale.Y, -scale.Z);  
        }
        /// <summary>
        /// This creates a world scale matrix no z adjustment is made
        /// </summary>
        public void CreateScale(Vector3 scale)
        {
            ScaleMatrix = Matrix.CreateScale(scale.X, scale.Y, scale.Z);
        }
        /// <summary>
        /// This creates a world scale matrix no z adjustment is made
        /// </summary>
        public void CreateScale(float x, float y, float z)
        {
            ScaleMatrix = Matrix.CreateScale(x, y, z);
        }
    }

The other 2 classes follow well 3 including the timer class.

here is the other two classes.

    /// <summary>
    /// This class takes a world space object to create a view camera. Via CreateCameraViewSpace.
    /// You then get a combined world view projection matrix from GetWorldViewProjection.
    /// </summary>
    public class ViewSpaceCameraTransformer
    {
        private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDeviceManager.DefaultBackBufferWidth / GraphicsDeviceManager.DefaultBackBufferHeight, .5f, 2000);
        private Matrix viewSpace = Matrix.Identity;
        private Matrix combinedViewProjection;

        /// <summary>
        /// This can be used as a camera offset such as for a chase view.
        /// </summary>
        public Vector3 OffsetPosition 
        { 
            get; 
            set; 
        }
        /// <summary>
        /// Creates a camera view space, matrice and stores it.
        /// </summary>
        public void CreateCameraViewSpace(WorldSpaceObject worldObjectToUseAsCamera)
        {
            viewSpace = Matrix.CreateLookAt
                (
                worldObjectToUseAsCamera.Position + OffsetPosition,
                worldObjectToUseAsCamera.Forward + (worldObjectToUseAsCamera.Position + OffsetPosition),
                worldObjectToUseAsCamera.world.Up
                );
            combinedViewProjection = viewSpace * projection;
        }
        /// <summary>
        /// A final matrix
        /// Takes a world space object matrice and transforms it. 
        /// By the view and projection matrixs into screen space.
        /// </summary>
        public Matrix GetWorldViewProjection(WorldSpaceObject worldObject)
        {
            return worldObject.ScaledWorldMatrix * combinedViewProjection;
        }
        /// <summary>
        /// Gets the worldspace object and view without the projection matrix
        /// </summary>
        public Matrix GetWorldView(WorldSpaceObject worldObject)
        {
            return worldObject.ScaledWorldMatrix * viewSpace;
        }
        /// <summary>
        /// Get a view and projection matrix combined
        /// Note you normally use GetWorldViewProjection
        /// </summary>
        public Matrix ViewProjection
        {
            get
            {
                return combinedViewProjection;
            }
        }
        /// <summary>
        /// Get a view matrix alone
        /// Note you normally use GetWorldViewProjection
        /// </summary>
        public Matrix View
        {
            get
            {
                return viewSpace;
            }
        }
        /// <summary>
        /// Get a default projection matrix or set a new one
        /// </summary>
        public Matrix Projection
        {
            get
            {
                return projection;
            }
            set
            {
                projection = value;
                combinedViewProjection = viewSpace * projection;
            }
        }
    }

    /// <summary>
    /// Use keys mouse or what not To move WorldSpaceObjects Around.
    /// This could probably be better.
    /// </summary>
    public class UserInputToOrientWorldObject
    {
        Vector3 turnOnAxis = Vector3.Zero;
        Vector3 moveInAxis = Vector3.Zero;
        public float SpeedMovement = 100f;
        public float SpeedRotational = .5f;
        Vector2 windowcenter = new Vector2(GraphicsDeviceManager.DefaultBackBufferWidth * .5f, GraphicsDeviceManager.DefaultBackBufferHeight * .5f);
        Vector2 maxSquareddist = new Vector2(2000000f, 2000000f);
        KeyboardState keyStates;
        MouseState mouseStates;
        public CameraTimer timing = new CameraTimer(1f);

        bool didAnyChangeOccur = false;
        public bool HasChangeOccured { get { return didAnyChangeOccur; } }

        public Keys KeyMoveRight = Keys.Right;
        public Keys KeyMoveLeft = Keys.Left;
        public Keys KeyMoveUp = Keys.Up;
        public Keys KeyMoveDown = Keys.Down;

        public Keys KeyMoveForward = Keys.E;
        public Keys KeyMoveBack = Keys.Q;

        public Keys KeyLookRight = Keys.D;
        public Keys KeyLookLeft = Keys.A;
        public Keys KeyLookUp = Keys.W;
        public Keys KeyLookDown = Keys.S;
        public Keys KeySpinCW = Keys.Z;
        public Keys KeySpinCCW = Keys.C;

        private bool useMouseLook = true;
        // if this is never called will just use the default key assignments
        /// <summary>
        /// Allows one to use the mouse too look.
        /// This should be called from code if you wish the keys to change.
        /// w s becomes forward back and a d is strafe move side to side
        /// </summary>
        public bool UseMouseLook
        {
            get { return useMouseLook; }
            set
            {
                if (value)
                {
                    KeyMoveForward = Keys.W;
                    KeyMoveBack = Keys.S;
                    KeyMoveRight = Keys.D;
                    KeyMoveLeft = Keys.A;
                    // just move them out of the way
                    KeyMoveUp = Keys.Home;
                    KeyMoveDown = Keys.PageUp;
                }
                else
                {
                    KeyMoveRight = Keys.D;
                    KeyMoveLeft = Keys.A;
                    KeyMoveUp = Keys.W;
                    KeyMoveDown = Keys.S;
                    KeyMoveForward = Keys.E;
                    KeyMoveBack = Keys.Q;
                }
                useMouseLook = value;
            }
        }

        /// <summary>
        /// Requisite for accurate mouse movement.
        /// This should be updated from game1 OnWindowsClientSizedChanged method.
        /// </summary>
        public void SetWindowSizeRequiredForMouseLook(GraphicsDevice g)
        {
            windowcenter = new Vector2(g.Viewport.Width * .5f, g.Viewport.Height * .5f);
            maxSquareddist = windowcenter * windowcenter;
        }
        /// <summary>
        /// Requisite for accurate mouse movement.
        /// This should be updated from game1 OnWindowsClientSizedChanged method.
        /// </summary>
        public void SetWindowSizeRequiredForMouseLook(int width, int height)
        {
            windowcenter = new Vector2(width * .5f, height * .5f);
            maxSquareddist = windowcenter * windowcenter;
        }

        /// <summary>
        /// This should be called in update 
        /// Whichever WorldSpaceObject to be used as the player (or camera) should be passed in.
        /// </summary>
        public WorldSpaceObject UpdateOrientation(WorldSpaceObject worldObj, GameTime gametime)
        {
            didAnyChangeOccur = false;
            keyStates = Keyboard.GetState();
            mouseStates = Mouse.GetState();
            timing.UpdateTimer(gametime);
            if (useMouseLook)
            {
                MouseLook();
                Move();
            }
            else
            {
                Rotate();
                Move();
            }
            if (didAnyChangeOccur)
            {
                worldObj.Move(moveInAxis);
                worldObj.Rotate(turnOnAxis);
            }
            return worldObj;
        }

        private void Rotate()
        {
            turnOnAxis = Vector3.Zero;
            var rotationspeed = SpeedRotational * timing.GetElapsedSMilliSeconds;
            if (keyStates.IsKeyDown(KeySpinCCW)) // roll ccw
            {
                turnOnAxis.Z = -rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeySpinCW)) // roll cw
            {
                turnOnAxis.Z = rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookLeft)) // r ccw
            {
                turnOnAxis.X = rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookRight)) // r cw
            {
                turnOnAxis.X = -rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookUp)) // u cw
            {
                turnOnAxis.Y = rotationspeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyLookDown)) // d ccw
            {
                turnOnAxis.Y = -rotationspeed;
                didAnyChangeOccur = true;
            }
        }

        private void Move()
        {
            moveInAxis = Vector3.Zero;
            var movespeed = SpeedMovement * timing.GetElapsedSMilliSeconds;
            if (keyStates.IsKeyDown(KeyMoveForward)) // Forward
            {
                moveInAxis.Z = movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveBack)) // back
            {
                moveInAxis.Z = -movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveLeft)) // left
            {
                moveInAxis.X = -movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveRight)) // right
            {
                moveInAxis.X = movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveDown)) // down
            {
                moveInAxis.Y = -movespeed;
                didAnyChangeOccur = true;
            }
            if (keyStates.IsKeyDown(KeyMoveUp)) // up
            {
                moveInAxis.Y = movespeed;
                didAnyChangeOccur = true;
            }
        }

        private void MouseLook()
        {
            turnOnAxis = Vector3.Zero;
            Vector2 mousePos = new Vector2(mouseStates.Position.X, mouseStates.Position.Y) - windowcenter;
            Vector2 distratio = new Vector2(mousePos.X * mousePos.X, mousePos.Y * mousePos.Y) / maxSquareddist;
            Vector2 mouseAngle = Vector2.Normalize(mousePos);

            //if (mouseStates.LeftButton == ButtonState.Pressed)
            //{
            Matrix r = Matrix.Identity;
            mousePos.Normalize();
            var rotationspeed =  distratio * SpeedRotational * timing.GetElapsedSMilliSeconds;
            if (distratio.Y > .05f)
            {
                if (mousePos.Y > 5f)
                {
                    turnOnAxis.Y = rotationspeed.Y * -mouseAngle.Y;
                    didAnyChangeOccur = true;
                }
                if (mousePos.Y < 5f)
                {
                    turnOnAxis.Y = rotationspeed.Y * -mouseAngle.Y;
                    didAnyChangeOccur = true;
                }
            }
            if (distratio.X > .05f)
            {
                if (mousePos.X > 5f)
                {
                    turnOnAxis.X = rotationspeed.X * -mouseAngle.X;
                    didAnyChangeOccur = true;
                }
                if (mousePos.X < 5f)
                {
                    turnOnAxis.X = rotationspeed.X * -mouseAngle.X;
                    didAnyChangeOccur = true;
                }
            }
            //}
        }
    }
    public class CameraTimer
    {
        float percentage = 0f;
        float timerLast = 0f;
        float timerNow = 0f;
        float elapsed = 0f;
        float timer = 1f;
        bool triggered = false;

        /// <summary>
        /// Timer will loop from 0 to 1 by the number of seconds specified
        /// </summary>
        public CameraTimer(float TimerInSeconds)
        {
            timer = 1f / TimerInSeconds;
        }
        /// <summary>
        /// Gets the percentage of the given timer that has elapsed
        /// </summary>
        public float Get { get { return percentage; } }
        /// <summary>
        /// Used to gauge things by time such as amounts of movement or speed of movement
        /// </summary>
        public float GetElapsedSMilliSeconds { get { return elapsed * 1000f; } }
        /// <summary>
        /// When the timmer reaches the set time this will evaluate to true
        /// </summary>
        public bool IsTriggered { get { return triggered; } }
        /// <summary>
        /// just like the constructor you set the timer in seconds
        /// </summary>
        public void SetTimingAmount(float TimerInSeconds)
        {
            timer = 1f / TimerInSeconds;
        }
        /// <summary>
        /// Gets a value ranging from 0 to 1 of the elapsed time specified
        /// </summary>
        public float UpdateTimer(GameTime gameTime)
        {
            timerLast = timerNow;
            timerNow = (float)gameTime.TotalGameTime.TotalSeconds;
            elapsed = timerNow - timerLast;
            percentage += elapsed * timer;
            triggered = false;
            if (percentage > 1f) { percentage = percentage - 1f; triggered = true; }
            return percentage;
        }
    }
}

Im probably not finished with this yet i have couple of more things to add in time.