Quantcast
Channel: Community | MonoGame - Latest topics
Viewing all articles
Browse latest Browse all 6821

Yet another camera class.

$
0
0

@willmotil wrote:

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 input controller class the values are set pretty low, its not that hot but its there just to move around the camera objects.

So here's my World object camera class.

    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);
            }
            worldviewprojection = transformer.GetWorldViewProjection(cam);
            // or
            worldviewprojection = transformer.GetWorldViewProjection(someobj_B);

Posts: 1

Participants: 1

Read full topic


Viewing all articles
Browse latest Browse all 6821

Trending Articles