using System; using Microsoft.Xna.Framework; namespace KinPortal { public class Camera : GameComponent { public Matrix LookAtMatrix { get {return Matrix.CreateLookAt(Pos, Eye + Pos, Up);} } public Matrix ProjectionMatrix { get {return Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(Fov), Game.GraphicsDevice.Viewport.AspectRatio, NearDist, FarDist ); } } public float Fov {get; set;} public float NearDist {get; set;} public float FarDist {get; set;} public Vector3 Pos {get; set;} public Vector3 Eye {get; set;} public Vector3 Up {get; set;} private float m_tangage; public float Tangage { get {return m_tangage;} set { m_tangage = value; Eye = GetEyeFromAngle(Lacet, Tangage); } } private float m_lacet; public float Lacet { get {return m_lacet;} set { m_lacet = value; Eye = GetEyeFromAngle(Lacet, Tangage); } } private float m_roulis; public float Roulis { get {return m_roulis;} set { m_roulis = value; // TODO : compute up vector Up = new Vector3(0, 0, 1); } } public Camera(Game game, Vector3 pos, Vector3 eye, Vector3 up, float fov, float near, float far) : base(game) { Pos = pos; Eye = eye; Up = up; Fov = fov; NearDist = near; FarDist = far; UpdateOrder = 1; } public Camera(Game game, Vector3 pos, float lacet, float tangage, float roulis, float fov, float near, float far) : base(game) { Pos = pos; Lacet = lacet; Tangage = tangage; Roulis = roulis; Fov = fov; NearDist = near; FarDist = far; } public void MoveForward(float step) { Pos = Eye * step + Pos; } public void MoveBackward(float step) { Pos = Eye * step * -1.0f + Pos; } public void MoveLeft(float step) { Pos = GetEyeFromAngle(Lacet + 90.0f, 0) * step + Pos; } public void MoveRight(float step) { Pos = GetEyeFromAngle(Lacet + 90.0f, 0) * step * -1.0f + Pos; } public void MoveUp(float step) { Pos = Up * step + Pos; } public void MoveDown(float step) { Pos = Up * step * -1.0f + Pos; } public void Rotate(float lacet, float tangage, float roulis) { Lacet = (Lacet + lacet) % 360.0f; Tangage = (Tangage + tangage) % 360.0f; Roulis = (Roulis + roulis) % 360.0f; } private Vector3 GetEyeFromAngle(float lacet, float tangage) { float lacet_rad = MathHelper.ToRadians(lacet); float tangage_rad = MathHelper.ToRadians(tangage); Vector3 eye = new Vector3( (float) (Math.Cos(tangage_rad) * Math.Cos(lacet_rad)), (float) (Math.Cos(tangage_rad) * Math.Sin(lacet_rad)), (float) (Math.Sin(tangage_rad)) ); return Vector3.Normalize(eye); } public Vector3 Unproject(int x, int y) { Vector3 nearSource = new Vector3(x, y, 0); Vector3 farSource = new Vector3(x, y, 1); Matrix world = Matrix.Identity; Matrix proj = ProjectionMatrix; Matrix view = LookAtMatrix; Vector3 nearPoint = Game.GraphicsDevice.Viewport.Unproject(nearSource, proj, view, world); Vector3 farPoint = Game.GraphicsDevice.Viewport.Unproject(farSource, proj, view, world); return farPoint - nearPoint; } } }