Yet Another Camera Class. [YACC]

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.