00001 using System;
00002 using Microsoft.Xna.Framework;
00003 using Microsoft.Xna.Framework.Graphics;
00004
00005 namespace Mindshifter
00006 {
00011 public sealed class LookAtCamera : ICamera
00012 {
00013 private Matrix mViewMatrix;
00014 private Projection mProjection;
00015
00016 private Vector3 mEyePosition;
00017 private Vector3 mLookAtPosition;
00018
00019 private bool mRequiresUpdate;
00020
00024 public Matrix ViewMatrix
00025 {
00026 get
00027 {
00028 if (mRequiresUpdate)
00029 BuildMatrix();
00030
00031 return mViewMatrix;
00032 }
00033 }
00034
00038 public Matrix ProjectionMatrix
00039 {
00040 get { return mProjection.Matrix; }
00041 }
00042
00046 public Projection Projection
00047 {
00048 get { return mProjection; }
00049 }
00050
00054 public BoundingFrustum Frustum
00055 {
00056 get { return new BoundingFrustum(ViewMatrix * ProjectionMatrix); }
00057 }
00058
00062 public Vector3 Position
00063 {
00064 get { return mEyePosition; }
00065 set
00066 {
00067 mEyePosition = value;
00068 mRequiresUpdate = true;
00069 }
00070 }
00071
00075 public Vector3 LookAtPosition
00076 {
00077 get { return mLookAtPosition; }
00078 set
00079 {
00080 mLookAtPosition = value;
00081 mRequiresUpdate = true;
00082 }
00083 }
00084
00090 public LookAtCamera()
00091 : this(Vector3.Zero, -Vector3.UnitZ)
00092 {
00093
00094 }
00095
00103 public LookAtCamera(Vector3 eye, Vector3 lookAt)
00104 : this(eye, lookAt, (float)Math.PI / 4f, 4f / 3f, 1f, 1000f)
00105 {
00106 mEyePosition = eye;
00107 mLookAtPosition = lookAt;
00108 }
00109
00120 public LookAtCamera(Vector3 eye, Vector3 lookAt, float fov, float aspect, float near, float far)
00121 {
00122 mEyePosition = eye;
00123 mLookAtPosition = lookAt;
00124
00125 mProjection = new Projection(fov, aspect, near, far);
00126
00127 mRequiresUpdate = true;
00128 }
00129
00139 public LookAtCamera(Vector3 eye, Vector3 lookAt, Rectangle rect, float near, float far)
00140 {
00141 mEyePosition = eye;
00142 mLookAtPosition = lookAt;
00143
00144 mProjection = new Projection(rect.X, rect.Y, rect.Width, rect.Height, near, far);
00145
00146 mRequiresUpdate = true;
00147 }
00148
00153 private void BuildMatrix()
00154 {
00155 mViewMatrix = Matrix.CreateLookAt(mEyePosition, mLookAtPosition, Vector3.Up);
00156 mRequiresUpdate = false;
00157 }
00158
00163 public void Update(float elapsedSeconds)
00164 {
00165 if (mRequiresUpdate)
00166 BuildMatrix();
00167 }
00168
00174 public Ray GetPickRay(Vector2 position, Viewport viewport)
00175 {
00176 Vector3 near = viewport.Unproject(new Vector3(position, 0f), ProjectionMatrix,
00177 ViewMatrix, Matrix.Identity);
00178
00179 Vector3 far = viewport.Unproject(new Vector3(position, 1f), ProjectionMatrix,
00180 ViewMatrix, Matrix.Identity);
00181
00182 return new Ray(near, Vector3.Normalize(far - near));
00183 }
00184 }
00185 }