#region Copyright
/*
--------------------------------------------------------------------------------
This source file is part of Xenocide
by Project Xenocide Team
For the latest info on Xenocide, see http://www.projectxenocide.com/
This work is licensed under the Creative Commons
Attribution-NonCommercial-ShareAlike 2.5 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/2.5/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.
--------------------------------------------------------------------------------
*/
/*
* @file Camera.cs
* @date Created: 2008/01/01
* @author File creator: David Teviotdale
* @author Credits: none
*/
#endregion
#region Using Statements
using System;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
#endregion
namespace ProjectXenocide.UI.Scenes.Battlescape
{
///
/// Camera used to view the Battlescape
///
public class Camera
{
///
/// Update camera's position, in response to user input
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods",
Justification = "will throw if gameTime is null")]
public void Update(GameTime gameTime)
{
// scroll at 20 units/second
float displacement = (float)gameTime.ElapsedRealTime.TotalMilliseconds * 0.02f;
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.Left))
{
position += displacement * Left;
}
if (keyState.IsKeyDown(Keys.Right))
{
position -= displacement * Left;
}
if (keyState.IsKeyDown(Keys.PageUp))
{
position.Y += displacement;
}
if (keyState.IsKeyDown(Keys.PageDown) && (0.5f < position.Y))
{
position.Y -= displacement;
}
if (keyState.IsKeyDown(Keys.Up))
{
position += displacement * Forward;
}
if (keyState.IsKeyDown(Keys.Down))
{
position -= displacement * Forward;
}
// take 2 seconds to do a 360 degree rotation
float rotation = (float)gameTime.ElapsedRealTime.TotalMilliseconds * MathHelper.Pi * 0.001f;
float yaw = 0.0f;
float pitch = 0.0f;
if (keyState.IsKeyDown(Keys.A))
{
yaw = +rotation;
}
if (keyState.IsKeyDown(Keys.D))
{
yaw = -rotation;
}
if (keyState.IsKeyDown(Keys.W) && (lookVector.Y < -0.45f))
{
pitch = rotation;
}
if (keyState.IsKeyDown(Keys.X) && (-0.9f < lookVector.Y))
{
pitch = -rotation;
}
// allow for rotation in horizonal plane
Vector3 xz = Vector3.Transform(lookVector, Matrix.CreateRotationY(yaw));
float x = (float)Math.Sqrt(xz.X * xz.X + xz.Z * xz.Z);
// rotation in vertical plane
Vector3 xy = Vector3.Transform(new Vector3(x, lookVector.Y, 0), Matrix.CreateRotationZ(pitch));
float scale = xy.X / x;
lookVector = Vector3.Normalize(new Vector3(xz.X / scale, xy.Y, xz.Z / scale));
CalcViewMatrix();
}
private void CalcViewMatrix()
{
view = Matrix.CreateLookAt(position, position + lookVector, Vector3.Up);
}
/// Return a unit vector in the X-Z plane in the same direction as the camera
private Vector3 Forward { get { return Vector3.Normalize(new Vector3(lookVector.X, 0, lookVector.Z)); } }
/// Return a unit vector in the X-Z plane, 90% counterclockwise to the camera's direction
private Vector3 Left
{
get { return Vector3.Cross(Forward, Vector3.Down); }
}
#region Fields
/// View matrix, to use with Effect
public Matrix View { get { return view; } }
/// Position of the camera in the scene
public Vector3 Position { get { return position; } set { position = value; CalcViewMatrix(); } }
/// Position of the camera in the scene
private Vector3 position = new Vector3(1.5f, 6.7f, 9.2f);
/// direction camera is looking in
private Vector3 lookVector = new Vector3(0, -0.67f, -0.74f);
/// view matrix that encapsulates all camera data
private Matrix view;
#endregion Fields
}
}