00001
00002
00003
00004 namespace NewGamePhysics.GraphicalElements
00005 {
00006 using System;
00007 using System.Collections.Generic;
00008 using System.Linq;
00009 using System.Text;
00010 using Microsoft.Xna.Framework;
00011 using Microsoft.Xna.Framework.Content;
00012 using Microsoft.Xna.Framework.Graphics;
00013 using Microsoft.Xna.Framework.Input;
00014
00015 using NewGamePhysics.StateManager;
00016 using NewGamePhysics.Utilities;
00017 using NewGamePhysics.PhysicalElements;
00018 using NewGamePhysics.Mathematics;
00019 using NewGamePhysics.Physics;
00020
00024 public class GravitySelector
00025 {
00029 private ScreenManager screenManager;
00030
00034 private static Vector3 cameraReferenceVector = new Vector3(0.0f, 0.0f, -1.0f);
00035
00039 private static Vector3 cameraUpVector = new Vector3(0.0f, 1.0f, 0.0f);
00040
00044 private TexturedSphere planetSphere;
00045
00049 private Matrix projectionMatrix;
00050
00054 private Matrix viewMatrix;
00055
00059 private ValueIndicator gravityIndicator;
00060
00064 private ValueIndicator latitudeIndicator;
00065
00069 private ValueIndicator longitudeIndicator;
00070
00074 private ScrollingText scrollingInfoText;
00075
00079 private double latitude;
00080
00084 private double longitude;
00085
00090 private float displaySize;
00091
00095 private Vector2 screenCenter;
00096
00100 private Color drawColor;
00101
00105 private CelestialBody celestialBody;
00106
00110 private GravityCalculator gravityCalculator;
00111
00115 private Texture2D surfaceTexture;
00116
00120 private double gravity;
00121
00125 public double Gravity
00126 {
00127 get { return this.gravity; }
00128 }
00129
00134 public float DisplaySize
00135 {
00136 get { return this.displaySize; }
00137 set
00138 {
00139 this.displaySize = value;
00140
00141
00142 if (this.displaySize < 0.0f)
00143 {
00144 this.displaySize = 0.0f;
00145 }
00146 else if (this.displaySize > 2.0f)
00147 {
00148 this.displaySize = 2.0f;
00149 }
00150
00151
00152 UpdateViewMatrix();
00153 }
00154 }
00155
00162 public GravitySelector(
00163 ScreenManager manager,
00164 CelestialObject celestialObject,
00165 GravityCalculator gravityCalculator)
00166 {
00167
00168 this.screenManager = manager;
00169
00170
00171 this.celestialBody = new CelestialBody(celestialObject);
00172
00173
00174 this.surfaceTexture = screenManager.Game.Content.Load<Texture2D>(
00175 this.celestialBody.GetTextureName(0));
00176
00177
00178 this.gravityCalculator = gravityCalculator;
00179 this.gravity = this.gravityCalculator.Value;
00180
00181
00182 this.planetSphere = new TexturedSphere(
00183 screenManager.GraphicsDevice,
00184 36,
00185 36,
00186 1.0f,
00187 this.surfaceTexture);
00188
00189
00190 this.screenCenter = new Vector2(
00191 (float)(screenManager.GraphicsDevice.Viewport.Width / 2),
00192 (float)(screenManager.GraphicsDevice.Viewport.Height / 2));
00193
00194
00195 float aspectRatio =
00196 (float)screenManager.GraphicsDevice.Viewport.Width /
00197 (float)screenManager.GraphicsDevice.Viewport.Height;
00198
00199
00200 this.projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
00201 0.1f * MathHelper.PiOver4,
00202 aspectRatio,
00203 5.0f,
00204 10000.0f);
00205
00206
00207 this.displaySize = 1.0f;
00208 UpdateViewMatrix();
00209
00210
00211 this.latitude = 0.0;
00212 this.longitude = 0.0;
00213
00214
00215 this.latitudeIndicator = new ValueIndicator(
00216 this.screenManager, "Latitude", "{0,20:####.##} deg", -90.0, 90.0);
00217 this.latitudeIndicator.SetPosition(new Vector2(20.0f, 20.0f));
00218 this.latitudeIndicator.SetValueInRange(this.latitude);
00219
00220 this.longitudeIndicator = new ValueIndicator(
00221 this.screenManager, "Longitude", "{0,20:####.##} deg", 0.0, 360.0);
00222 this.longitudeIndicator.SetPosition(new Vector2(20.0f, 80.0f));
00223 this.longitudeIndicator.LowHighColoring = false;
00224 this.longitudeIndicator.SetValueInRange(this.longitude);
00225
00226 this.gravityIndicator = new ValueIndicator(
00227 this.screenManager, "Gravity", "{0,20:###.######} N");
00228 this.gravityIndicator.SetPosition(new Vector2((float)screenManager.GraphicsDevice.Viewport.Width - 20.0f - ValueIndicator.Width, 20.0f));
00229 this.latitudeIndicator.LowHighColoring = false;
00230 this.gravityIndicator.SetValue(this.gravity);
00231
00232
00233 this.screenManager.AddFont("retro", "Fonts/retroMedium");
00234
00235
00236 SpriteFont font = this.screenManager.Fonts["game"];
00237 int width = this.screenManager.GraphicsDevice.Viewport.Width;
00238 int yPos = this.screenManager.GraphicsDevice.Viewport.Height - 32;
00239 string infoText =
00240 "Model Info: " +
00241 gravityCalculator.GetModelInfo() +
00242 " --- Texture Info: " +
00243 celestialBody.GetTextureInfo() +
00244 " ";
00245 infoText = infoText.Replace("\n", " * ");
00246 scrollingInfoText = new ScrollingText(infoText, font, width, yPos);
00247 scrollingInfoText.TextScale = 0.5f;
00248
00249
00250 this.drawColor = new Color(1.0f, 0.25f, 0.25f);
00251 }
00252
00257 public double Latitude
00258 {
00259 get
00260 {
00261 return this.latitude;
00262 }
00263
00264 set
00265 {
00266 this.latitude = value;
00267
00268
00269 while (this.latitude < -90.0)
00270 {
00271 this.latitude = -90.0;
00272 }
00273
00274 while (this.latitude > 90.0)
00275 {
00276 this.latitude = 90.0;
00277 }
00278
00279
00280 this.gravityCalculator.Latitude = this.latitude;
00281 this.gravity = this.gravityCalculator.Value;
00282
00283
00284 this.latitudeIndicator.SetValueInRange(this.latitude);
00285 this.gravityIndicator.SetValue(this.gravity);
00286 }
00287 }
00288
00293 public double Longitude
00294 {
00295 get
00296 {
00297 return this.longitude;
00298 }
00299
00300 set
00301 {
00302 this.longitude = value;
00303
00304
00305 while (this.longitude < 0.0)
00306 {
00307 this.longitude += 360.0;
00308 }
00309
00310 while (this.longitude > 360.0)
00311 {
00312 this.longitude -= 360.0;
00313 }
00314
00315
00316 this.gravityCalculator.Longitude = this.longitude;
00317 this.gravity = this.gravityCalculator.Value;
00318
00319
00320 this.longitudeIndicator.SetValueInRange(this.longitude);
00321 this.gravityIndicator.SetValue(this.gravity);
00322 }
00323 }
00324
00328 public void Update(GameTime gameTime)
00329 {
00330 scrollingInfoText.Update(gameTime);
00331 }
00332
00337 public void Draw(GameTime gameTime)
00338 {
00339
00340 Matrix sphereRollingMatrix = Matrix.CreateRotationY((float)(this.longitude * Math.PI / 180.0))
00341 * Matrix.CreateRotationX((float)(this.latitude * Math.PI / 180.0));
00342 planetSphere.Render(
00343 this.screenManager.GraphicsDevice,
00344 this.viewMatrix,
00345 this.projectionMatrix,
00346 sphereRollingMatrix,
00347 this.DisplaySize);
00348
00349
00350 PrimitiveBatch primitiveBatch = screenManager.PrimitiveBatch;
00351 float offset = (float)Math.Abs(Math.Sin(Math.PI * gameTime.TotalRealTime.TotalSeconds));
00352 offset = 4.0f * MathHelper.SmoothStep(0.0f, 1.0f, offset);
00353 float max_size = 12.0f + offset;
00354 float min_size = 1.0f + offset;
00355
00356
00357 primitiveBatch.Begin(PrimitiveType.LineList);
00358
00359 primitiveBatch.AddVertex(screenCenter + new Vector2( max_size, 0.0f), this.drawColor);
00360 primitiveBatch.AddVertex(screenCenter + new Vector2( min_size, 0.0f), this.drawColor);
00361
00362 primitiveBatch.AddVertex(screenCenter + new Vector2(-max_size, 0.0f), this.drawColor);
00363 primitiveBatch.AddVertex(screenCenter + new Vector2(-min_size, 0.0f), this.drawColor);
00364
00365 primitiveBatch.AddVertex(screenCenter + new Vector2(0.0f, max_size), this.drawColor);
00366 primitiveBatch.AddVertex(screenCenter + new Vector2(0.0f, min_size), this.drawColor);
00367
00368 primitiveBatch.AddVertex(screenCenter + new Vector2(0.0f, -max_size), this.drawColor);
00369 primitiveBatch.AddVertex(screenCenter + new Vector2(0.0f, -min_size), this.drawColor);
00370
00371 primitiveBatch.End();
00372
00373
00374 if (this.displaySize > 0.99f)
00375 {
00376 longitudeIndicator.Draw(gameTime);
00377 latitudeIndicator.Draw(gameTime);
00378 gravityIndicator.Draw(gameTime);
00379
00380 SpriteBatch spriteBatch = this.screenManager.SpriteBatch;
00381 scrollingInfoText.Draw(gameTime, spriteBatch);
00382 }
00383 }
00384
00388 private void UpdateViewMatrix()
00389 {
00390
00391 double cameraDistance = 30.0f;
00392 if (this.displaySize <= 1.0f)
00393 {
00394 cameraDistance = cameraDistance + MathHelper.SmoothStep(0.0f, 1.0f, (1.0f - this.displaySize)) * 100.0f * cameraDistance;
00395 }
00396 else
00397 {
00398 cameraDistance = cameraDistance - MathHelper.SmoothStep(0.0f, 1.0f, this.displaySize - 1.0f) * cameraDistance;
00399 }
00400
00401
00402
00403 Vector3 cameraPosition = new Vector3(0, 0, (float)cameraDistance);
00404
00405
00406 Vector3 cameraLookAtVector = cameraReferenceVector;
00407
00408
00409 cameraLookAtVector += cameraPosition;
00410
00411
00412
00413
00414 this.viewMatrix = Matrix.CreateLookAt(
00415 cameraPosition,
00416 cameraLookAtVector,
00417 cameraUpVector);
00418 }
00419 }
00420 }