PageRenderTime 176ms CodeModel.GetById 117ms app.highlight 47ms RepoModel.GetById 1ms app.codeStats 1ms

/PhysicsEngines/Tests3D/Program.cs

#
C# | 1054 lines | 651 code | 149 blank | 254 comment | 44 complexity | 12feeb8eb07cb5074e25b2a0e16fae4d MD5 | raw file
   1using System;
   2using System.Collections.Generic;
   3using Delta.ContentSystem.Rendering;
   4using Delta.ContentSystem.Rendering.Helpers;
   5using Delta.Engine;
   6using Delta.InputSystem;
   7using Delta.PhysicsEngines.Advanced;
   8using Delta.PhysicsEngines.Effects;
   9using Delta.PhysicsEngines.VisualShapes;
  10using Delta.Rendering;
  11using Delta.Rendering.Basics.Drawing;
  12using Delta.Rendering.Basics.Fonts;
  13using Delta.Rendering.Cameras;
  14using Delta.Rendering.Effects;
  15using Delta.Rendering.Effects.Modifiers;
  16using Delta.Rendering.Enums;
  17using Delta.Rendering.Models;
  18using Delta.Utilities;
  19using Delta.Utilities.Datatypes;
  20using Delta.Utilities.Datatypes.Advanced;
  21using Delta.Utilities.Math;
  22using NUnit.Framework;
  23
  24namespace Delta.PhysicsEngines.Tests3D
  25{
  26	/// <summary>
  27	/// Physics tests
  28	/// </summary>
  29	internal class Program
  30	{
  31		#region Main
  32		/// <summary>
  33		/// Main entry point, will just call one of the tests, uncomment the rest
  34		/// </summary>
  35		private static void Main()
  36		{
  37			// Note: In the settings for this project Jitter is used. You can switch
  38			// to other physics engines here (required files are copied automatically,
  39			// but for your release you should set this to the content project).
  40			// Warning: Farseer has no 3D Physics support (just good for 2D)
  41			//Settings.Modules.PhysicsModule = "Bullet";
  42			//Settings.Modules.PhysicsModule = "JigLib";
  43			//Settings.Modules.PhysicsModule = "Jitter";
  44			//coming soon: Settings.Modules.PhysicsModule = "Havok";
  45			//coming soon: Settings.Modules.PhysicsModule = "PhysX";
  46
  47			#region Tests
  48			//TestSimpleSimulation3D();
  49			//TestRayCast();
  50			//Test3DObjectPicking();
  51			//TestMultiple3DObjectPicking();
  52			//TestControlledSpherePlane();
  53			//does not work: TestBallMovement();
  54			//TestSimpleRagdoll();
  55			//TestRestitution();
  56			//TestRopeSimulation();
  57			//TestPrismaticJoint();
  58			//TestCollisionEvents();
  59			//FountainEffectPhysics3D();
  60			//FountainPhysicsEffectWithTornado3D();
  61			//TestJigLibXCreateScene1(9);
  62			//TestJigLibXCreateScene3();
  63			//Jitter.JitterPhysics.JitterPhysicsTests.TestCreate3DBodyWithShape();
  64			#endregion
  65
  66			#region Tutorials
  67			//Tutorials.Simple3DSimulation();
  68			//Tutorials.RopeSimulation();
  69			//Tutorials.CollisionEvents();
  70			//Tutorials.ControlledSphere();
  71			//Tutorials.RayCasting3D();
  72			Tutorials.PyramidSimulation();
  73			//Tutorials.BodyRestitution();
  74			#endregion
  75		}
  76		#endregion
  77		
  78		#region TestSimpleSimulation3D (Static)
  79		/// <summary>
  80		/// Test a simple simulation with 3D physics
  81		/// </summary>
  82		[Test, Category("Visual")]
  83		public static void TestSimpleSimulation3D()
  84		{
  85			// create 4 vertices that will define the "ground" static plane
  86			const int planeSize = 200;
  87			const int height = -5;
  88
  89			// Enable plane to physics world.
  90			Physics.Instance.SetGroundPlane(true, height);
  91
  92			Physics.DebugEnabled = true;
  93
  94			// set the params of the spheres
  95			float radius = 2.0f;
  96			Vector spherePosition1 = new Vector(2.0f, 0.0f, 5.0f);
  97			Vector spherePosition2 = new Vector(12.0f, 0.0f, 5.0f);
  98
  99			// create two sphere and add them to the physics world
 100			VisualPhysicsSphere visualSphere1 = new VisualPhysicsSphere(
 101				spherePosition1, radius, Color.Red);
 102
 103			VisualPhysicsSphere visualSphere2 = new VisualPhysicsSphere(
 104				spherePosition2, radius, Color.Green);
 105
 106			// create two boxes
 107			VisualPhysicsBox visualBox1 = new VisualPhysicsBox(
 108				spherePosition1 + 15.0f * Vector.UnitZ, radius * 2);
 109
 110			VisualPhysicsBox visualBox2 = new VisualPhysicsBox(
 111				visualBox1.Body.Position + new Vector(3.0f, 1.0f, 7.0f) +
 112				5.0f * Vector.UnitZ + 1.0f * Vector.UnitX, radius * 2);
 113
 114			// this line of code also sets the camera, i.e. ViewProjection matrix
 115			LookAtCamera camera = new LookAtCamera(new Vector(0, -10, 10));
 116
 117			Font fpsFont = new Font(Font.Default,
 118				HorizontalAlignment.Left, VerticalAlignment.Top);
 119			Mesh plane = Mesh.CreatePlane("GroundPlane", planeSize, planeSize,
 120				new MaterialData());
 121
 122			Application.Start(delegate
 123			{
 124				fpsFont.Draw("Fps: " + Time.Fps, ScreenSpace.DrawArea);
 125
 126				// Draw the spheres
 127				visualSphere1.Draw();
 128				visualSphere2.Draw();
 129
 130				// Draw the boxes
 131				visualBox1.Draw();
 132				visualBox2.Draw();
 133
 134				// Draw the ground plane
 135				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 136				plane.Draw(ref planeHeight);
 137			});
 138		}
 139		#endregion
 140
 141		#region TestSimpleRagdoll (Static)
 142		/// <summary>
 143		/// Test a simple simulation with ragdoll
 144		/// </summary>
 145		[Test, Category("Visual")]
 146		public static void TestSimpleRagdoll()
 147		{
 148			// create 4 vertices that will define the "ground" static plane
 149			const int size = 50;
 150			const int height = -5;
 151
 152			// add a plane to the physics world 
 153			Physics.Instance.SetGroundPlane(true, height);
 154
 155			List<Ragdoll> ragdolls = new List<Ragdoll>();
 156
 157			for (int i = 3; i < 8; i++)
 158			{
 159				for (int e = 3; e < 8; e++)
 160				{
 161					Vector position = new Vector(i * 6 - 25, e * 6 - 25, 5);
 162					ragdolls.Add(new Ragdoll(position));
 163				}
 164			}
 165
 166			// this line of code also sets the camera, i.e. ViewProjection matrix
 167			LookAtCamera camera = new LookAtCamera(new Vector(0, -10, 10));
 168			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size,
 169				new MaterialData());
 170
 171			Application.Start(delegate
 172			{
 173				// Draw the ground plane
 174				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 175				plane.Draw(ref planeHeight);
 176
 177				if (Input.Mouse.LeftButtonIsPressed)
 178				{
 179					Point mousePosition = Input.Mouse.Position;
 180					Ray ray = ScreenSpace.GetRayFromScreenPoint(mousePosition);
 181
 182					PhysicsBody grabBody;
 183					Vector hitNormal;
 184					float fraction;
 185					bool result = Physics.FindRayCast(ray, false, out grabBody,
 186						out hitNormal, out fraction);
 187
 188					if (result)
 189					{
 190						grabBody.IsActive = true;
 191					}
 192				}
 193				foreach (Ragdoll ragdoll in ragdolls)
 194				{
 195					ragdoll.Draw();
 196				}
 197			});
 198		}
 199		#endregion
 200
 201		#region TestControlledSpherePlane (Static)
 202		/// <summary>
 203		/// Test a Sphere controlled by the user in a plane
 204		/// </summary>
 205		[Test, Category("Visual")]
 206		public static void TestControlledSpherePlane()
 207		{
 208			/*TODO
 209			// create 4 vertices that will define the "ground" static plane
 210			Vector v0 = new Vector(16, 16, -5);
 211			Vector v1 = new Vector(16, -16, -5);
 212			Vector v2 = new Vector(-16, -16, -5);
 213			Vector v3 = new Vector(-16, 16, -5);
 214
 215			// add a plane to the physics world 
 216			VisualPhysicsPlane groundPlane = new VisualPhysicsPlane(80, 80, new Vector(0, 0, -5), new MaterialData());//"NormalMap", "RocksHighDiffuse", "None", "None", "None", "None"));
 217
 218			//Mesh sphereMesh = Mesh.CreateSphere("SomeName", 5, new MaterialData());
 219
 220			// create the sphere and add it to the physics world
 221			VisualPhysicsSphere sphere = new VisualPhysicsSphere(new Vector(0, 0, 10), 3.0f, new MaterialData());//"NormalMap", "RocksHighDiffuse", "None", "None", "None", "None"));
 222
 223			// set a controller for the sphere
 224			IController3D ctrler =
 225					PhysicsManager.CreateController(sphere.PhysicsSphere, 1.0f, 2.0f, 0.0f);
 226
 227			// Manipulate the sphere with the help of the controller.
 228			Vector direction = new Vector(RandomHelper.RandomFloat(-1000, +1000),
 229					RandomHelper.RandomFloat(-1000, +1000),
 230					RandomHelper.RandomFloat(-1000, +1000));
 231			direction.Normalize();
 232			ctrler.MovingDirection = direction;
 233			ctrler.MoveSpeed = RandomHelper.RandomFloat(5, 30);
 234
 235			// set the gravity
 236			PhysicsManager.Gravity = new Vector(0, 0, -9.8f);
 237
 238			LookAtCamera camera = new LookAtCamera(new Vector(0, 25, 10));
 239
 240			Application.Start(delegate
 241			{
 242				//Draw our sphere and groundPlane
 243				sphere.Draw();
 244				groundPlane.Draw();
 245
 246				//Font.Default.WriteTopLeft(sphere.PhysicsSphere.Position.ToString());
 247			});*/
 248		}
 249		#endregion
 250
 251		#region FountainEffectPhysics3D (Static)
 252		/// <summary>
 253		/// Tests that simulates usage of physics particles
 254		/// </summary>
 255		[Test, Category("Visual")]
 256		public static void FountainEffectPhysics3D()
 257		{
 258			// Set up camera
 259			LookAtCamera cam = new LookAtCamera(new Vector(1, -5, 3));
 260
 261			float maxLifeTime = 30.0f;
 262
 263			// Create a new template.
 264			EffectData data = EffectData.Get("<SmokeEffect3D>");
 265			// Add an emitter and modifiers.
 266			EmitterData emitter = new EmitterData();
 267			emitter.Modifiers.AddRange(
 268				new IEffectModifier[]
 269				{
 270					new AlwaysSpawnModifier(),
 271					new SpawnIntervalModifier
 272					{
 273						SpawnInterval = 0.4f,
 274					},
 275					new PhysicsModifier
 276					{
 277						DebugDisplay = true,
 278						PhysicsShapeType = ParticlePhysicsShape.Sphere,
 279						Mass = 10.0f,
 280					},
 281					new SizeModifier
 282					{
 283						WidthRange = 20f,
 284						HeightRange = 20f,
 285					},
 286					new ParticleLifetimeModifier
 287					{
 288						ParticleLifetime = maxLifeTime,
 289					},
 290					new RotationModifier
 291					{
 292						Rotation = new Range(0f, 360f),
 293					},
 294					new MaterialModifier
 295					{
 296						Material = new MaterialColored("SmokeSmallAdditive")
 297						{
 298							BlendColor = new Color(0.3f, 0.4f, 0.8f),
 299						},
 300						BillboardMode = BillboardMode.CameraFacingPrecise,
 301					},
 302				});
 303			data.Emitters.Add(emitter);
 304			int effectId = Effect.Spawn(data, new Vector(0.0f, 0.0f, 8.5f));
 305
 306			// Setup Physics
 307			Physics.Gravity = new Vector(0f, 0f, -9.81f);
 308
 309			// Create invisile Plane
 310			Physics.Instance.SetGroundPlane(true, 0.0f);
 311
 312			// Start the application.
 313			Application.Start(delegate
 314			{
 315				// Draw a grid for orientation.
 316				Grid.Draw();
 317
 318				if (Input.Keyboard.GetState(InputButton.M) == InputState.Released)
 319				{
 320					Physics.Multithreading = !Physics.Multithreading;
 321				}
 322
 323				Font.DrawTopLeftInformation(
 324					"Fps: " + Time.Fps + "\n" +
 325					Effect.NumberOfActiveParticles(effectId) +
 326					" currently active particles\n" +
 327					(Physics.Multithreading
 328					 	? "Multithreaded "
 329					 	: "Single Threaded"));
 330			});
 331		}
 332		#endregion
 333
 334		#region FountainPhysicsEffectWithTornado3D (Static)
 335		/// <summary>
 336		/// Tests that simulates usage of physics particles with apply
 337		/// of tornado, press N to activated, U to remove it.
 338		/// </summary>
 339		[Test, Category("Visual")]
 340		public static void FountainPhysicsEffectWithTornado3D()
 341		{
 342			// Set up camera
 343			LookAtCamera cam = new LookAtCamera(new Vector(1, -5, 3));
 344
 345			float maxLifeTime = 10.0f;
 346
 347			// Create a new template.
 348			EffectData data = EffectData.Get("<SmokeEffect3D>");
 349			// Add an emitter and modifiers.
 350			EmitterData emitter = new EmitterData();
 351			emitter.Modifiers.AddRange(
 352				new IEffectModifier[]
 353				{
 354					new AlwaysSpawnModifier(),
 355					new SpawnIntervalModifier
 356					{
 357						SpawnInterval = 1.0f,
 358					},
 359					new PhysicsModifier
 360					{
 361						DebugDisplay = true,
 362						PhysicsShapeType = ParticlePhysicsShape.Sphere,
 363						Mass = 10.0f,
 364					},
 365					new SizeModifier
 366					{
 367						WidthRange = 20f,
 368						HeightRange = 20f,
 369					},
 370					new ParticleLifetimeModifier
 371					{
 372						ParticleLifetime = maxLifeTime,
 373					},
 374					new RotationModifier
 375					{
 376						Rotation = new Range(0f, 360f),
 377					},
 378					new MaterialModifier
 379					{
 380						Material = new MaterialColored("SmokeSmallAdditive")
 381						{
 382							BlendColor = new Color(0.3f, 0.4f, 0.8f),
 383						},
 384						BillboardMode = BillboardMode.CameraFacingPrecise,
 385					},
 386				});
 387			data.Emitters.Add(emitter);
 388			int effectId = Effect.Spawn(data, new Vector(0.0f, 0.0f, 8.5f));
 389
 390			// Setup Physics
 391			Physics.Gravity = new Vector(0f, 0f, -9.81f);
 392
 393			// Create invisile Plane
 394			Physics.Instance.SetGroundPlane(true, 0.0f);
 395
 396			Tornado tornado = Physics.CreateTornado(Vector.Zero);
 397			tornado.IsEnabled = false;
 398
 399			// Start the application.
 400			Application.Start(delegate
 401			{
 402				// Draw a grid for orientation.
 403				Grid.Draw();
 404
 405				if (Input.Keyboard.GetState(InputButton.N) == InputState.Released)
 406				{
 407					tornado.IsEnabled = !tornado.IsEnabled;
 408					tornado.Position = new Vector(0, 0, -5.0f);
 409
 410					if (tornado.IsEnabled &&
 411					    tornado.IsRemoved)
 412					{
 413						// Trigger to add to simulation if removed with U button.
 414						tornado.AddToSimulation();
 415					}
 416				}
 417
 418				if (Input.Keyboard.GetState(InputButton.U) == InputState.Released)
 419				{
 420					Physics.RemoveForceField(tornado);
 421				}
 422
 423				if (Input.Keyboard.GetState(InputButton.M) == InputState.Released)
 424				{
 425					Physics.Multithreading = !Physics.Multithreading;
 426				}
 427
 428				Font.DrawTopLeftInformation(
 429					"Fps: " + Time.Fps + "\n" +
 430					"Currently active particles: " +
 431					Effect.NumberOfActiveParticles(effectId) + "\n" +
 432					(Physics.Multithreading
 433					 	? "Multithreaded "
 434					 	: "Single Threaded"));
 435			});
 436		}
 437		#endregion
 438
 439		#region Methods (Private)
 440
 441		#region TestRayCast
 442		/// <summary>
 443		/// Test ray cast
 444		/// </summary>
 445		private static void TestRayCast()
 446		{
 447			// create a plane so that every ray that doesn't hit an object will hit
 448			// the plane
 449			const int size = 50;
 450			const int height = -5;
 451
 452			// add a plane to the physics world 
 453			Physics.Instance.SetGroundPlane(true, height);
 454
 455			// create a box and a sphere
 456			VisualPhysicsBox visualBox = new VisualPhysicsBox(new Vector(-2, 0, 0), 4);
 457			VisualPhysicsSphere visualSphere =
 458				new VisualPhysicsSphere(new Vector(5, 0, 0), 2);
 459
 460			// this line of code also sets the camera, i.e. ViewProjection matrix
 461			LookAtCamera cam = new LookAtCamera(new Vector(0, 25, 10));
 462
 463			// create a moving ray
 464			Vector rayStart = new Vector(0, 0, 10);
 465			Vector lookTarget = new Vector();
 466			Ray testRay = new Ray(rayStart, lookTarget - rayStart);
 467
 468			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size, new MaterialData());
 469
 470			Application.Start(delegate
 471			{
 472				// Draw the ground plane
 473				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 474				plane.Draw(ref planeHeight);
 475
 476				PhysicsBody catchedBody;
 477				Vector normal;
 478				float fraction;
 479
 480				//Draw the sphere and box
 481				visualBox.Draw();
 482				visualSphere.Draw();
 483
 484				// perform ray cast
 485				bool rayCasted = Physics.FindRayCast(testRay, false,
 486					out catchedBody, out normal, out fraction);
 487
 488				// update the objects color according to the result of the ray cast
 489				if (catchedBody == visualBox.Body)
 490				{
 491					visualBox.DebugDrawColor = Color.Red;
 492				}
 493				else
 494				{
 495					visualBox.DebugDrawColor = Color.Green;
 496				}
 497
 498				if (catchedBody == visualSphere.Body)
 499				{
 500					visualSphere.DebugDrawColor = Color.Red;
 501				}
 502				else
 503				{
 504					visualSphere.DebugDrawColor = Color.Green;
 505				}
 506
 507				// render the line according to the deleted intersection
 508				if (rayCasted)
 509				{
 510					// render up to the intersection point
 511					//DrawManager.Line3D(testRay.Position, testRay.Direction, Color.Yellow);
 512
 513					// render the surface normal at this point
 514					//DrawManager.Line3D(testRay.Position, testRay.Direction + normal, Color.White);
 515				}
 516				else
 517				{
 518					//DrawManager.Line3D(testRay.Position,
 519					//		testRay.Position + 15.0f * testRay.Direction, Color.Yellow);
 520				}
 521
 522				// update the direction of the ray
 523				lookTarget.X = 8 * (float)Math.Cos(0.3f * Time.CurrentExactTime);
 524				lookTarget.Y = 2.0f * (float)Math.Sin(5.0f * Time.CurrentExactTime);
 525				testRay.Direction = Vector.Normalize(lookTarget - testRay.Position);
 526			});
 527		}
 528		#endregion
 529
 530		#region Test3DObjectPicking
 531		/// <summary>
 532		/// Test 3D object picking
 533		/// </summary>
 534		private static void Test3DObjectPicking()
 535		{
 536			// create a box
 537			VisualPhysicsBox visualBox = new VisualPhysicsBox(Vector.Zero, 4);
 538
 539			// this line of code also sets the camera, i.e. ViewProjection matrix
 540			LookAtCamera cam = new LookAtCamera(new Vector(0, 25, 10));
 541
 542			Ray mouseRay = new Ray();
 543
 544			Application.Start(delegate
 545			{
 546				bool rayCasted = false;
 547				if (Input.Mouse.RightButtonIsPressed)
 548				{
 549					// create ray from mouse position
 550					Point mousePosition = Input.Mouse.Position;
 551					mouseRay = ScreenSpace.GetRayFromScreenPoint(mousePosition);
 552
 553					PhysicsBody catchedBody;
 554					Vector normal;
 555					float fraction;
 556
 557					// perform ray cast
 558					rayCasted = Physics.FindRayCast(mouseRay, false,
 559						out catchedBody, out normal, out fraction);
 560				}
 561
 562				if (rayCasted)
 563				{
 564					Font.Default.Draw("Hit", ScreenSpace.DrawArea);
 565					visualBox.DebugDrawColor = Color.Red;
 566				}
 567				else
 568				{
 569					visualBox.DebugDrawColor = Color.Green;
 570				}
 571
 572				visualBox.Draw();
 573			});
 574		}
 575		#endregion
 576
 577		#region TestMultiple3DObjectPicking
 578		/// <summary>
 579		/// Test 3D object picking
 580		/// </summary>
 581		private static void TestMultiple3DObjectPicking()
 582		{
 583			/*
 584			// create a box and a sphere
 585			VisualPhysicsBox visualBox = new VisualPhysicsBox(new Vector(-2, 0, 0), 4);
 586			VisualPhysicsSphere visualSphere = new VisualPhysicsSphere(new Vector(7, 0, 0), 3);
 587
 588			// this line of code also sets the camera, i.e. ViewProjection matrix
 589			LookAtCamera cam = new LookAtCamera(new Vector(0, 25, 10));
 590
 591			//Create the ray
 592			Ray mouseRay = new Ray();
 593
 594			Application.Start(delegate
 595			{
 596				//Write some info on the screen
 597				//Font.Default.Write(new Point(0.5f, 0.2f), "Use the right mouse button to pick an object");
 598
 599				IPhysicsShape3D catchedObject = null;
 600				if (Input.Mouse.RightButtonIsPressed)
 601				{
 602					// create ray from mouse position
 603					Point mousePosition = Input.Mouse.Position;
 604					mouseRay = ScreenSpace.GetRayFormScreenPoint(mousePosition);
 605
 606					Vector intersection;
 607					Vector normal;
 608
 609					// perform ray cast
 610					PhysicsManager.RayCast(mouseRay,
 611							out catchedObject, out intersection, out normal);
 612				}
 613
 614
 615				// Draw the box and sphere
 616				visualBox.Draw();
 617				visualSphere.Draw();
 618
 619				//Reset the color of the box and the sphere
 620				visualBox.DebugDrawColor = Color.Green;
 621				visualSphere.DebugDrawColor = Color.Green;
 622
 623
 624				if (catchedObject != null)
 625				{
 626					var visualPhysicsShape = catchedObject.Owner as IVisualPhysicsShape;
 627					if (visualPhysicsShape != null)
 628					{
 629						visualPhysicsShape.DebugDrawColor = Color.Red;
 630					}
 631				}
 632			});*/
 633		}
 634		#endregion
 635
 636		#region TestRestitution
 637		private static void TestRestitution()
 638		{
 639			// create 4 vertices that will define the "ground" static plane
 640			const int size = 250;
 641			const int height = -5;
 642
 643			// add a plane to the physics world 
 644			Physics.Instance.SetGroundPlane(true, height);
 645
 646			// this line of code also sets the camera, i.e. ViewProjection matrix
 647			LookAtCamera camera = new LookAtCamera(new Vector(0, -10, 10));
 648
 649			List<BaseVisualPhysicsShape> drawable =
 650				new List<BaseVisualPhysicsShape>();
 651
 652			for (int i = 0; i < 11; i++)
 653			{
 654				Vector position = new Vector(-15 + i * 3 + 10, 0, 5);
 655				VisualPhysicsSphere sphere =
 656					new VisualPhysicsSphere(position + Vector.UnitZ * 30, 1.0f);
 657
 658				// Set restitution.
 659				sphere.Body.Restitution = i / 3.0f;
 660
 661				drawable.Add(sphere);
 662			}
 663
 664			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size,
 665				new MaterialData());
 666
 667			Application.Start(delegate
 668			{
 669				// Draw the ground plane
 670				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 671				plane.Draw(ref planeHeight);
 672
 673				foreach (BaseVisualPhysicsShape shape in drawable)
 674				{
 675					shape.Draw();
 676				}
 677				Font.DrawTopLeftInformation("Fps: " + Time.Fps);
 678			});
 679		}
 680		#endregion
 681
 682		#region TestRopeSimulation
 683		private static void TestRopeSimulation()
 684		{
 685			// Enable debug rendering.
 686			Physics.DebugEnabled = true;
 687
 688			// create 4 vertices that will define the "ground" static plane
 689			const int size = 50;
 690			const int height = -5;
 691
 692			// add a plane to the physics world 
 693			Physics.Instance.SetGroundPlane(true, height);
 694
 695			// this line of code also sets the camera, i.e. ViewProjection matrix
 696			LookAtCamera camera = new LookAtCamera(new Vector(30, -30, 10));
 697
 698			List<BaseVisualPhysicsShape> drawable = new List<BaseVisualPhysicsShape>();
 699
 700			BaseVisualPhysicsShape last = null;
 701
 702			for (int i = 0; i < 40; i++)
 703			{
 704				BaseVisualPhysicsShape shape = new VisualPhysicsSphere(
 705					new Vector(i * 1.5f - 20, 0, 3.5f), 0.5f);
 706
 707				drawable.Add(shape);
 708
 709				Vector pos2 = shape.Body.Position;
 710
 711				if (last != null)
 712				{
 713					Vector pos3 = last.Body.Position;
 714
 715					Vector dif = pos2 - pos3;
 716					dif = dif * 0.5f;
 717					dif = pos2 - dif;
 718
 719					PhysicsJoint joint = Physics.CreatePointOnPoint(
 720						last.Body,
 721						shape.Body,
 722						dif);
 723				}
 724
 725				last = shape;
 726			}
 727
 728			int index = 0;
 729			BaseVisualPhysicsShape controllingShape = drawable[index];
 730			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size,
 731				new MaterialData());
 732
 733			Application.Start(delegate
 734			{
 735				// Draw the ground plane
 736				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 737				plane.Draw(ref planeHeight);
 738
 739				if (Input.Keyboard.SpaceReleased)
 740				{
 741					if (index + 1 > drawable.Count)
 742					{
 743						index = 0;
 744					}
 745
 746					controllingShape = drawable[index++];
 747				}
 748
 749				// Up movement
 750				if (Input.Keyboard.IsPressed(InputButton.W))
 751				{
 752					controllingShape.Body.ApplyLinearImpulse(
 753						new Vector(0, 0, 2), controllingShape.Body.Position);
 754				}
 755
 756				// Down movement
 757				if (Input.Keyboard.IsPressed(InputButton.S))
 758				{
 759					controllingShape.Body.ApplyLinearImpulse(
 760						new Vector(0, 0, -2), controllingShape.Body.Position);
 761				}
 762
 763				// Left movement
 764				if (Input.Keyboard.IsPressed(InputButton.A))
 765				{
 766					controllingShape.Body.ApplyLinearImpulse(
 767						new Vector(-2, 0, 0), controllingShape.Body.Position);
 768				}
 769
 770				// Right movement
 771				if (Input.Keyboard.IsPressed(InputButton.D))
 772				{
 773					controllingShape.Body.ApplyLinearImpulse(
 774						new Vector(2, 0, 0), controllingShape.Body.Position);
 775				}
 776
 777				foreach (BaseVisualPhysicsShape shape in drawable)
 778				{
 779					shape.Draw();
 780				}
 781
 782				// Draw info
 783				Font.DrawTopLeftInformation(
 784					"Fps: " + Time.Fps + "\n" +
 785					"Use W,A,S,D to translate joint\n" +
 786					"Use Space to select next joint");
 787			});
 788		}
 789		#endregion
 790
 791		#region TestPrismaticJoint
 792		private static void TestPrismaticJoint()
 793		{
 794			// create 4 vertices that will define the "ground" static plane
 795			const int size = 50;
 796			const int height = -17;
 797
 798			// add a plane to the physics world 
 799			Physics.Instance.SetGroundPlane(true, height);
 800
 801			// this line of code also sets the camera, i.e. ViewProjection matrix
 802			LookAtCamera camera = new LookAtCamera(new Vector(30, -30, 0));
 803
 804			List<BaseVisualPhysicsShape> drawable = new List<BaseVisualPhysicsShape>();
 805
 806			BaseVisualPhysicsShape body1 = new VisualPhysicsBox(new Vector(0, 0, 7), 1.0f);
 807			BaseVisualPhysicsShape body2 = new VisualPhysicsBox(new Vector(0, 0, 4), 1.0f);
 808			drawable.Add(body1);
 809			drawable.Add(body2);
 810
 811			// Add a prismatic joint. The minimum allowed distance is 3. The maximum
 812			// allowed distance is also 3, the body should be fixed on the slider.
 813			Physics.CreatePrismatic(body1.Body, body2.Body, 3, 3, 1.0f, 0.0f);
 814			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size,
 815				new MaterialData());
 816
 817			Application.Start(delegate
 818			{
 819				// Draw the ground plane
 820				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 821				plane.Draw(ref planeHeight);
 822
 823				// Up movement
 824				if (Input.Keyboard.IsPressed(InputButton.W))
 825				{
 826					body1.Body.ApplyAngularImpulse(new Vector(0, 0, 0.2f));
 827				}
 828
 829				// Down movement
 830				if (Input.Keyboard.IsPressed(InputButton.S))
 831				{
 832					body1.Body.ApplyAngularImpulse(new Vector(0, 0, -0.2f));
 833				}
 834
 835				// Left movement
 836				if (Input.Keyboard.IsPressed(InputButton.A))
 837				{
 838					body1.Body.ApplyAngularImpulse(new Vector(-0.2f, 0, 0));
 839				}
 840
 841				// Right movement
 842				if (Input.Keyboard.IsPressed(InputButton.D))
 843				{
 844					body1.Body.ApplyAngularImpulse(new Vector(0.2f, 0, 0));
 845				}
 846
 847				foreach (BaseVisualPhysicsShape shape in drawable)
 848				{
 849					shape.Draw();
 850				}
 851
 852				// Draw info
 853				//Font.DrawTopLeftInformation(
 854				//  "Fps: "+Time.Fps+"\n"+,
 855				//  "Use W,A,S,D to move upper joint");
 856			});
 857		}
 858		#endregion
 859
 860		#region TestCollisionEvents
 861		/// <summary>
 862		/// Performs collision check between two bodies with events.
 863		/// </summary>
 864		private static void TestCollisionEvents()
 865		{
 866			// create 4 vertices that will define the "ground" static plane
 867			const int size = 50;
 868			const int height = -5;
 869
 870			// add a plane to the physics world 
 871			Physics.Instance.SetGroundPlane(true, height);
 872			Physics.GroundBody.Name = "PlaneBody";
 873			Physics.GroundBody.CollisionBegin += BodyCollisionBegin;
 874			Physics.GroundBody.CollisionEnd += GroundBodyCollisionEnd;
 875
 876			// this line of code also sets the camera, i.e. ViewProjection matrix
 877			LookAtCamera camera = new LookAtCamera(new Vector(30, -30, 10));
 878
 879			List<BaseVisualPhysicsShape> drawable = new List<BaseVisualPhysicsShape>();
 880
 881			BaseVisualPhysicsShape body1 =
 882				new VisualPhysicsBox(new Vector(0, 0, 27), 1.0f);
 883			BaseVisualPhysicsShape body2 =
 884				new VisualPhysicsBox(new Vector(0, 0, 24), 1.0f);
 885			drawable.Add(body1);
 886			drawable.Add(body2);
 887			body1.Body.Name = "Body1";
 888			body2.Body.Name = "Body2";
 889
 890			int index = 3;
 891			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size,
 892				new MaterialData());
 893
 894			Application.Start(delegate
 895			{
 896				// Draw the ground plane
 897				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 898				plane.Draw(ref planeHeight);
 899
 900				foreach (BaseVisualPhysicsShape shape in drawable)
 901				{
 902					shape.Draw();
 903				}
 904
 905				if (Input.Mouse.RightButtonIsPressed)
 906				{
 907					BaseVisualPhysicsShape body = new VisualPhysicsBox(new Vector(0, 0, 27),
 908						1.0f);
 909					body.Body.Name = "Body" + (index++);
 910					drawable.Add(body);
 911				}
 912			});
 913		}
 914		#endregion
 915
 916		#region GroundBodyCollisionEnd
 917		private static void GroundBodyCollisionEnd(PhysicsBody other)
 918		{
 919			Log.Info(
 920				"Given body '" + other.Name + "' ends collision with the ground " +
 921				"plane body.");
 922		}
 923		#endregion
 924
 925		#region BodyCollisionBegin
 926		private static void BodyCollisionBegin(PhysicsBody other)
 927		{
 928			Log.Info(
 929				"Given body '" + other.Name + "' collide with this plane body.");
 930		}
 931		#endregion
 932
 933		#region TestJigLibXCreateScene1
 934		/// <summary>
 935		/// JigLibX game CreateScene1 test unit.
 936		/// </summary>
 937		/// <param name="dim">Dimension of the cube grid created.</param>
 938		private static void TestJigLibXCreateScene1(int dim)
 939		{
 940			// create 4 vertices that will define the "ground" static plane
 941			const int size = 50;
 942			const int height = -5;
 943
 944			// add a plane to the physics world 
 945			Physics.Instance.SetGroundPlane(true, height);
 946
 947			// this line of code also sets the camera, i.e. ViewProjection matrix
 948			LookAtCamera camera = new LookAtCamera(new Vector(30, -30, 10));
 949
 950			List<BaseVisualPhysicsShape> drawable = new List<BaseVisualPhysicsShape>();
 951
 952			for (int x = 0; x < dim; x++)
 953			{
 954				for (int y = 0; y < dim; y++)
 955				{
 956					VisualPhysicsBox box = null;
 957					if (y % 2 == 0)
 958					{
 959						box = new VisualPhysicsBox(
 960							new Vector(x * 1.01f - 10.0f, y * 1.01f - 14.5f, 25), 1.0f);
 961					}
 962					else
 963					{
 964						box = new VisualPhysicsBox(
 965							new Vector(x * 1.01f - 10.5f, y * 1.01f - 14.5f, 25), 1.0f);
 966					}
 967
 968					drawable.Add(box);
 969				}
 970			}
 971
 972			int index = 3;
 973			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size,
 974				new MaterialData());
 975
 976			Application.Start(delegate
 977			{
 978				// Draw the ground plane
 979				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
 980				plane.Draw(ref planeHeight);
 981
 982				foreach (BaseVisualPhysicsShape shape in drawable)
 983				{
 984					shape.Draw();
 985				}
 986
 987				if (Input.Mouse.RightButtonIsPressed)
 988				{
 989					BaseVisualPhysicsShape body = new VisualPhysicsBox(new Vector(0, 0, 27),
 990						1.0f);
 991					body.Body.Name = "Body" + (index++);
 992					drawable.Add(body);
 993				}
 994			});
 995		}
 996		#endregion
 997
 998		#region TestJigLibXCreateScene3
 999		/// <summary>
1000		/// JigLibX game CreateScene3 test unit.
1001		/// </summary>
1002		private static void TestJigLibXCreateScene3()
1003		{
1004			// create 4 vertices that will define the "ground" static plane
1005			const int size = 50;
1006			const int height = -5;
1007
1008			// add a plane to the physics world 
1009			Physics.Instance.SetGroundPlane(true, height);
1010
1011			// this line of code also sets the camera, i.e. ViewProjection matrix
1012			LookAtCamera camera = new LookAtCamera(new Vector(30, -30, 10));
1013
1014			List<BaseVisualPhysicsShape> chainBoxes = new List<BaseVisualPhysicsShape>();
1015
1016			for (int i = 0; i < 25; i++)
1017			{
1018				VisualPhysicsBox boxObject =
1019					new VisualPhysicsBox(new Vector(i, 25 - i, 0), 1.0f);
1020				if (i == 0)
1021				{
1022					boxObject.IsStatic = true;
1023				}
1024				chainBoxes.Add(boxObject);
1025			}
1026
1027			for (int i = 1; i < 25; i++)
1028			{
1029				// Create HingeJoint
1030				PhysicsJoint joint = Physics.CreateHinge(
1031					chainBoxes[i - 1].Body, chainBoxes[i].Body, Vector.UnitZ,
1032					new Vector(0.5f, -0.5f, 0.0f));
1033			}
1034
1035			Mesh plane = Mesh.CreatePlane("GroundPlane", size, size,
1036				new MaterialData());
1037
1038			Application.Start(delegate
1039			{
1040				// Draw the ground plane
1041				Matrix planeHeight = Matrix.CreateTranslation(0, 0, height);
1042				plane.Draw(ref planeHeight);
1043
1044				foreach (BaseVisualPhysicsShape shape in chainBoxes)
1045				{
1046					shape.Draw();
1047				}
1048			});
1049		}
1050		#endregion
1051
1052		#endregion
1053	}
1054}