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 }