So this section of my tutorials we are going to cover Cameras, we will be creating two classes our main Camera class and our First Person Camera, later we will be adding a Third Person Camera(Chase Camera).
So let’s look at the code for our main Class that our First Person will inherit from.
using System;
using Microsoft.Xna.Framework;
using GameEngine;
using GameEngine.Utilities;
using GameEngine.Components;
namespace GameEngine.Cameras
{
public class Camera : Component, I3DComponent
{
Vector3 position = Vector3.Zero;
Matrix rotationMatrix = Matrix.Identity;
Vector3 target = new Vector3(0, 0, -1);
Vector3 up = Vector3.Up;
Matrix view;
Matrix projection;
/// <summary>
/// Gets or sets the target.
/// </summary>
/// <value>
/// The target.
/// </value>
public virtual Vector3 Target
{ get { return target; } set { target = value; } }
/// <summary>
/// Gets or sets the view.
/// </summary>
/// <value>
/// The view.
/// </value>
public virtual Matrix View
{ get { return view; } set { view = value; } }
/// <summary>
/// Gets or sets the projection.
/// </summary>
/// <value>
/// The projection.
/// </value>
public virtual Matrix Projection
{ get { return projection; } set { projection = value; } }
/// <summary>
/// Gets or sets up.
/// </summary>
/// <value>
/// Up.
/// </value>
public virtual Vector3 Up
{ get { return up; } set { up = value; } }
/// <summary>
/// Gets or sets the position.
/// </summary>
/// <value>
/// The position.
/// </value>
public virtual Vector3 Position { get { return position; } set { position = value; } }
/// <summary>
/// Gets or sets the scale.
/// </summary>
/// <value>
/// The scale.
/// </value>
public virtual Vector3 Scale { get { return Vector3.One; } set { } }
/// <summary>
/// Gets or sets the rotation.
/// </summary>
/// <value>
/// The rotation.
/// </value>
public virtual Matrix Rotation
{
get { return rotationMatrix;}
set{rotationMatrix = value;}
}
/// <summary>
/// Gets or sets the euler rotation.
/// </summary>
/// <value>
/// The euler rotation.
/// </value>
public Vector3 EulerRotation
{
get{return MathUtil.MatrixToVector3(Rotation);}
set { rotationMatrix = MathUtil.Vector3ToMatrix(value);}
}
/// <summary>
/// Gets the bounding box.
/// </summary>
public virtual BoundingBox BoundingBox
{get {return new BoundingBox(Position - Vector3.One, Position + Vector3.One);}}
/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="Parent">The parent.</param>
public Camera(GameScreen Parent) : base(Parent) { }
/// <summary>
/// Initializes a new instance of the class.
/// </summary>
public Camera() : base() { }
/// <summary>
/// Updates this instance.
/// </summary>
public override void Update()
{
Vector3 newForward = Target - Position;
newForward.Normalize();
Matrix rotationMatrixCopy = this.Rotation;
rotationMatrixCopy.Forward = newForward;
Vector3 referenceVector = Vector3.Up;
if (rotationMatrixCopy.Forward.Y == referenceVector.Y || rotationMatrixCopy.Forward.Y == -referenceVector.Y)
referenceVector = Vector3.Backward;
rotationMatrixCopy.Right = Vector3.Cross(this.Rotation.Forward, referenceVector);
rotationMatrixCopy.Up = Vector3.Cross(this.Rotation.Right, this.Rotation.Forward);
this.Rotation = rotationMatrixCopy;
Up = Rotation.Up;
View = Matrix.CreateLookAt(Position, Target, Up);
Projection = MathUtil.CreateProjectionMatrix();
}
}
}
So next lets look at our First Person Camera this class is very simple really as most of the work is done in the Camera Class.
using Microsoft.Xna.Framework;
using System;
using GameEngine.Components;
using GameEngine.Utilities;
namespace GameEngine.Cameras{
// A simple first person camera. Accepts rotation and translation
public class FPSCamera : Camera
{
// Keeps track of the rotation and translation that have been
// added via RotateTranslate()
Vector3 rotation;
Vector3 translation;
public FPSCamera(GameScreen Parent) : base(Parent) { }
public FPSCamera() : base() { }
// This adds to rotation and translation to change the camera view
public void RotateTranslate(Vector3 Rotation, Vector3 Translation)
{
translation += Translation;
rotation += Rotation;
}
public override void Update()
{
// Update the rotation matrix using the rotation vector
Rotation = MathUtil.Vector3ToMatrix(rotation);
// Update the position in the direction of rotation
translation = Vector3.Transform(translation, Rotation);
Position += translation;
// Reset translation
translation = Vector3.Zero;
// Calculate the new target
Target = Vector3.Add(Position, Rotation.Forward);
// Have the base Camera update all the matrices, etc.
base.Update();
}
}
}
So that our Main camera class and our First Person Camera created
Will try and get the next post up a bit sooner that this one.