PageRenderTime 97ms CodeModel.GetById 30ms app.highlight 44ms RepoModel.GetById 16ms app.codeStats 1ms

/PhysicsEngines/Tests2D/Program.cs

#
C# | 756 lines | 418 code | 115 blank | 223 comment | 17 complexity | 6512b8c081070d00d4f4603c2fcce748 MD5 | raw file
  1using System.Collections.Generic;
  2using Delta.Engine;
  3using Delta.InputSystem;
  4using Delta.Rendering.Basics.Fonts;
  5using Delta.Rendering.Basics.Materials;
  6using Delta.Utilities;
  7using Delta.Utilities.Datatypes;
  8using Delta.Utilities.Datatypes.Advanced;
  9using Delta.Utilities.Helpers;
 10using NUnit.Framework;
 11
 12namespace Delta.PhysicsEngines.Tests2D
 13{
 14	/// <summary>
 15	/// Physics tests
 16	/// </summary>
 17	[Category("Visual")]
 18	internal class Program
 19	{
 20		#region Main (Static)
 21		/// <summary>
 22		/// Main entry point, will just call one of the tests, uncomment the rest
 23		/// </summary>
 24		public static void Main()
 25		{
 26			// Note: In the default settings Physics modules are not used, thus none
 27			// of the physics tests will work. For this project (which has the same
 28			// content project name: Delta.PhysicsEngines.Tests2D) Farseer is already
 29			// set in the content Settings.xml and will be used. Do the same for your
 30			// own projects or use a line like this to force a specific physics
 31			// module. All required files will be copied automatically.
 32			//Settings.Modules.PhysicsModule = "Farseer";
 33
 34			#region Tests
 35			//TestSimpleSimulation2D();
 36			//TestJoints();
 37			//TestForceAndTorque();
 38			//TestSingleBodyTwoShapes();
 39			//TestFlummySimulation2D();
 40			//TestRayCast();
 41			//TestControlledSpherePlane();
 42			//TestRotatingBall();
 43			//TestBallMovement();
 44			//TestResize();
 45			//TestCollisionEvents();
 46			//BugTest();
 47			#endregion
 48
 49			#region Tutorials
 50			//Tutorials.Simple2DSimulation();
 51			//Tutorials.JointsSimulation();
 52			//Tutorials.BouncyBallSimulation();
 53			//Tutorials.FlummySimulation();
 54			//Tutorials.RayCasting2D();
 55			//Tutorials.CollisionEvents();
 56			Tutorials.PyramidSimulation();
 57			#endregion
 58		}
 59		#endregion
 60		
 61		#region TestSimpleSimulation2D (Static)
 62		/// <summary>
 63		/// Test a simple simulation with 2D physics
 64		/// </summary>
 65		[Test]
 66		public static void TestSimpleSimulation2D()
 67		{
 68			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
 69			// Enable debug drawing
 70			Physics.DebugEnabled = true;
 71
 72			// Create some (2 balls and 1 box) and the ground and let them 
 73			// collide due to gravity
 74			List<PhysicsBody> balls = new List<PhysicsBody>();
 75
 76			PhysicsBody box = null;
 77			PhysicsBody ground = null;
 78			float radius = 0.05f;
 79			float mass = 1.0f;
 80
 81			Rectangle rectangle = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
 82			Rectangle boxRect = new Rectangle(0.0f, 0.0f, 0.05f, 0.05f);
 83
 84			for (int index = 0; index < 10; index++)
 85			{
 86				PhysicsBody ball = Physics.CreateCircle(radius, mass);
 87				ball.Position = new Vector(RandomHelper.RandomFloat(-0.5f, 0.5f),
 88					RandomHelper.RandomFloat(-0.5f, 0.5f), 0.0f);
 89				ball.Friction = 1.0f;
 90				ball.IsStatic = false;
 91
 92				// Set debug color to red.
 93				ball.DebugColor = Color.Red;
 94
 95				balls.Add(ball);
 96			}
 97
 98			box = Physics.CreateRectangle(
 99				boxRect.Width, boxRect.Height, 1.0f);
100			box.Position = new Vector(.5f, .4f, 0.0f);
101			box.IsStatic = false;
102			box.Friction = 1.0f;
103			box.DebugColor = Color.Green;
104
105			// set our ground
106			ground = Physics.CreateRectangle(
107				rectangle.Width, rectangle.Height, 1f);
108			ground.Position = new Vector(rectangle.Center, 0.0f);
109			ground.IsStatic = true;
110			ground.Friction = 1.0f;
111			ground.DebugColor = Color.Yellow;
112
113			Application.Start(delegate
114			{
115				//Font.DrawTopLeftInformation("Fps: "+Time.Fps);
116			});
117		}
118		#endregion
119
120		#region TestJoints (Static)
121		/// <summary>
122		/// Test a simple simulation with 2D physics and joints
123		/// </summary>
124		[Test]
125		public static void TestJoints()
126		{
127			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
128			// Enable debug drawing
129			Physics.DebugEnabled = true;
130
131			// Create some (2 balls and 1 box) and the ground and let them 
132			// collide due to gravity
133			List<PhysicsBody> balls = new List<PhysicsBody>();
134
135			PhysicsBody box = null;
136			PhysicsBody ground = null;
137			float radius = 0.05f;
138			float mass = 1.0f;
139
140			Rectangle rectangle = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
141			Rectangle boxRect = new Rectangle(0.0f, 0.0f, 0.05f, 0.05f);
142
143			for (int index = 0; index < 10; index++)
144			{
145				PhysicsBody ball = Physics.CreateCircle(radius, mass);
146				ball.Position = new Vector(RandomHelper.RandomFloat(-0.5f, 0.5f),
147					RandomHelper.RandomFloat(-0.5f, 0.5f), 0.0f);
148				ball.Friction = 1.0f;
149				ball.IsStatic = false;
150
151				// Set debug color to red.
152				ball.DebugColor = Color.Red;
153
154				balls.Add(ball);
155			} // for
156
157			box = Physics.CreateRectangle(
158				boxRect.Width, boxRect.Height, 1.0f);
159			box.Position = new Vector(.5f, .4f, 0.0f);
160			box.IsStatic = false;
161			box.Friction = 1.0f;
162			box.DebugColor = Color.Green;
163
164			PhysicsBody box2 = Physics.CreateRectangle(
165				boxRect.Width, boxRect.Height, 1.0f);
166			box2.Position = new Vector(.6f, .4f, 0.0f);
167			box2.IsStatic = false;
168			box2.Friction = 1.0f;
169			box2.DebugColor = Color.Green;
170
171			// Create angle joint
172			PhysicsJoint joint = Physics.CreateAngleJoint(box, box2, 0.0f);
173
174			// set our ground
175			ground = Physics.CreateRectangle(
176				rectangle.Width, rectangle.Height, 1f);
177			ground.Position = new Vector(rectangle.Center, 0.0f);
178			ground.IsStatic = true;
179			ground.Friction = 1.0f;
180			ground.DebugColor = Color.Yellow;
181
182			Application.Start(delegate
183			{
184				Font.DrawTopLeftInformation("Fps: " + Time.Fps);
185			});
186		}
187		#endregion
188
189		#region TestForceAndTorque (Static)
190		/// <summary>
191		/// Test a simple simulation with 2D physics with no gravity and
192		/// how to apply force and torque
193		/// </summary>
194		[Test]
195		public static void TestForceAndTorque()
196		{
197			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
198			// Enable debug drawing
199			Physics.DebugEnabled = true;
200
201			PhysicsBody box = null;
202			PhysicsBody ground = null;
203
204			Rectangle rectangle = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
205			Rectangle boxRect = new Rectangle(0.0f, 0.0f, 0.05f, 0.05f);
206
207			box = Physics.CreateRectangle(
208				boxRect.Width, boxRect.Height, 1.0f);
209			box.Position = new Vector(.5f, .4f, 0.0f);
210			box.IsStatic = false;
211			box.Friction = 1.0f;
212			box.DebugColor = Color.Green;
213
214			// Set our ground
215			ground = Physics.CreateRectangle(
216				rectangle.Width, rectangle.Height, 1f);
217			ground.Position = new Vector(rectangle.Center, 0.0f);
218			ground.IsStatic = true;
219			ground.Friction = 1.0f;
220			ground.DebugColor = Color.Yellow;
221
222			// Farseer
223			PhysicsBody rectBody = Physics.CreateRectangle(.05f, .05f, 1);
224			rectBody.Position = new Vector(0.3f, 0.3f, 0.0f);
225			rectBody.IsStatic = false;
226			rectBody.DebugColor = Color.Gold;
227
228			Application.Start(delegate
229			{
230				const float forceAmount = 60;
231				const float torqueAmount = 40;
232				Vector force = Vector.Zero;
233
234				// Apply left force
235				if (Input.Keyboard.IsPressed(InputButton.A))
236				{
237					force += new Vector(-forceAmount, 0, 0);
238				}
239
240				// Apply down force
241				if (Input.Keyboard.IsPressed(InputButton.S))
242				{
243					force += new Vector(0, forceAmount, 0);
244				}
245
246				// Apply right force
247				if (Input.Keyboard.IsPressed(InputButton.D))
248				{
249					force += new Vector(forceAmount, 0, 0);
250				}
251
252				// Apply up force
253				if (Input.Keyboard.IsPressed(InputButton.W))
254				{
255					force += new Vector(0, -forceAmount, 0);
256				}
257
258				rectBody.ApplyForce(force);
259
260				float torque = 0;
261
262				if (Input.Keyboard.IsPressed(InputButton.Q))
263				{
264					torque += torqueAmount;
265				}
266				if (Input.Keyboard.IsPressed(InputButton.E))
267				{
268					torque -= torqueAmount;
269				}
270
271				rectBody.ApplyTorque(torque);
272
273				Font.DrawTopLeftInformation("Fps: " + Time.Fps);
274			});
275		}
276		#endregion
277
278		#region TestSingleBodyTwoShapes (Static)
279		/// <summary>
280		/// Test a simple simulation with 2D physics with no gravity and
281		/// single body with two shapes.
282		/// </summary>
283		[Test]
284		public static void TestSingleBodyTwoShapes()
285		{
286			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
287			// Enable debug drawing
288			Physics.DebugEnabled = true;
289
290			//PhysicsBody box = null;
291			//PhysicsBody ground = null;
292
293			//Rectangle rectangle = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
294
295			//// set our ground
296			//ground = Physics.CreateRectangle(
297			//    rectangle.Width, rectangle.Height, 1f);
298			//ground.Position = new Vector(rectangle.Center, 0.0f);
299			//ground.IsStatic = true;
300			//ground.Friction = 1.0f;
301			//ground.DebugColor = Color.Yellow;
302
303			//// Farseer
304			//PhysicsBody rectBody = Physics.Create2DBody(
305			//  new Point(0.3f, 0.3f));
306			//rectBody.IsStatic = false;
307
308			//Application.Start(delegate
309			//{
310			//  const float forceAmount = 60;
311			//  const float torqueAmount = 40;
312			//  Vector force = Vector.Zero;
313
314			//  // Apply left force
315			//  if (Input.Keyboard.IsPressed(InputButton.A))
316			//  {
317			//    force += new Vector(-forceAmount, 0, 0);
318			//  }
319
320			//  // Apply down force
321			//  if (Input.Keyboard.IsPressed(InputButton.S))
322			//  {
323			//    force += new Vector(0, forceAmount, 0);
324			//  }
325
326			//  // Apply right force
327			//  if (Input.Keyboard.IsPressed(InputButton.D))
328			//  {
329			//    force += new Vector(forceAmount, 0, 0);
330			//  }
331
332			//  // Apply up force
333			//  if (Input.Keyboard.IsPressed(InputButton.W))
334			//  {
335			//    force += new Vector(0, -forceAmount, 0);
336			//  }
337
338			//  rectBody.ApplyForce(force);
339
340			//  float torque = 0;
341
342			//  if (Input.Keyboard.IsPressed(InputButton.Q))
343			//  {
344			//    torque += torqueAmount;
345			//  }
346			//  if (Input.Keyboard.IsPressed(InputButton.E))
347			//  {
348			//    torque -= torqueAmount;
349			//  }
350
351			//  rectBody.ApplyTorque(torque);
352
353			//  //Font.DrawTopLeftInformation(Time.Fps.ToString());
354			//});
355		}
356		#endregion
357
358		#region TestFlummySimulation2D (Static)
359		/// <summary>
360		/// Test flummy simulation 2D
361		/// </summary>
362		[Test]
363		public static void TestFlummySimulation2D()
364		{
365			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
366			Physics.DebugEnabled = true;
367
368			// Border properties
369			float density = 5.0f;
370			float friction = 1.0f;
371			float restitution = 1.0f;
372
373			// Border rectangle
374			Rectangle leftRect = new Rectangle(0.0f, 0.0f, 0.1f, 1.0f);
375			Rectangle topRect = new Rectangle(0.1f, 0.1f, 0.8f, 0.1f);
376			Rectangle rightRect = new Rectangle(0.9f, 0.0f, 0.1f, 1.0f);
377			Rectangle bottomRect = new Rectangle(0.1f, 0.8f, 0.8f, 0.1f);
378
379			PhysicsBody leftBorder =
380				Physics.CreateRectangle(leftRect.Width, leftRect.Height, density);
381			leftBorder.Friction = friction;
382			leftBorder.Restitution = restitution;
383			leftBorder.Position2D = leftRect.Center;
384			leftBorder.IsStatic = true;
385			leftBorder.DebugColor = Color.White;
386
387			PhysicsBody topBorder =
388				Physics.CreateRectangle(topRect.Width, topRect.Height, density);
389			topBorder.Friction = friction;
390			topBorder.Restitution = restitution;
391			topBorder.Position2D = topRect.Center;
392			topBorder.IsStatic = true;
393			topBorder.DebugColor = Color.White;
394
395			PhysicsBody rightBorder =
396				Physics.CreateRectangle(rightRect.Width, rightRect.Height, density);
397			rightBorder.Friction = friction;
398			rightBorder.Restitution = restitution;
399			rightBorder.Position2D = rightRect.Center;
400			rightBorder.IsStatic = true;
401			rightBorder.DebugColor = Color.White;
402
403			PhysicsBody bottomBorder =
404				Physics.CreateRectangle(bottomRect.Width, bottomRect.Height, density);
405			bottomBorder.Friction = friction;
406			bottomBorder.Restitution = restitution;
407			bottomBorder.Position2D = bottomRect.Center;
408			bottomBorder.IsStatic = true;
409
410			// Create a ball;
411			PhysicsBody ball = Physics.CreateCircle(0.035f, 1.0f);
412			ball.Friction = 0.3f;
413			ball.Restitution = 1.0f;
414			ball.IsStatic = false;
415			ball.Position2D = Point.Half;
416			ball.DebugColor = Color.CornflowerBlue;
417
418			// The Physics engine performs debug shape draw for us.
419			Application.Start();
420		}
421		#endregion
422
423		#region TestRotatingBall (Static)
424		[Test]
425		public static void TestRotatingBall()
426		{
427			const float BallRadius = 0.02f;
428			const float BallMass = 1.0f;
429			Point startPosition = new Point(0.1f, 0.5f);
430			float setRotationVelocity = 180.0f;
431			// Disable gravity
432			Physics.Gravity = Vector.Zero;
433
434			// Create ball
435			var ball = Physics.CreateCircle(BallRadius, BallMass);
436			ball.Position2D = startPosition;
437			// No friction or restitution, fly ball, fly ;)
438			ball.Friction = 0.0f;
439			//not longer used: ball.Restitution = 0.0f;
440			// Set the body type (the ball should fly, default is static)
441			ball.IsStatic = false;
442
443			Material2DColored ballMaterial = new Material2DColored(
444				//"SmokeBrightTransparency");
445				//"SmokeAdditive");
446				"DeltaEngineLogo");
447
448			Application.Start(delegate
449			{
450				// When we press the mouse or touch the screen, rotate!
451				if (Input.Mouse.LeftButtonReleased ||
452				    Input.Touch.TouchReleased)
453				{
454					ball.AngularVelocity2D = setRotationVelocity;
455				}
456				// Draw the physics shape as a line circle
457				//Circle.DrawOutline(ball.Position, ball.Radius, Color.Red);
458				ballMaterial.Draw(Rectangle.FromCenter(ball.Position2D,
459					ballMaterial.Size), ball.Rotation);
460
461				Font.DrawTopLeftInformation(
462					"AngularVelocity=" + ball.AngularVelocity2D +
463					", Rotation=" + ball.Rotation);
464			});
465		}
466		#endregion
467
468		#region TestBallMovement (Static)
469		/// <summary>
470		/// Test ball movement
471		/// </summary>
472		[Test]
473		public static void TestBallMovement()
474		{
475			const float BallRadius = 0.02f;
476			const float BallMass = 1.0f;
477			Point startPosition = new Point(0.1f, 0.5f);
478			Point setVelocity = new Point(50.0f, 0.0f);
479			// Disable gravity
480			Physics.Gravity = Vector.Zero;
481
482			// Create ball
483			var ball = Physics.CreateCircle(BallRadius, BallMass);
484			ball.Position2D = startPosition;
485			// No friction or restitution, fly ball, fly ;)
486			ball.Friction = 0.0f;
487			//not longer used: ball.Restitution = 0.0f;
488			// Set the body type (the ball should fly, default is static)
489			ball.IsStatic = false;
490
491			Material2D ballMaterial = new Material2D(
492				//"SmokeBrightTransparency");
493				//"SmokeAdditive");
494				"DeltaEngineLogo");
495			//Second ball without physics
496			Point ballPosition = startPosition + new Point(0, 0.2f);
497			Point ballVelocity = Point.Zero;
498
499			Application.Start(delegate
500			{
501				// When we press, give a velocity to the ball
502				if (Input.Mouse.LeftButtonReleased ||
503				    Input.Touch.TouchReleased)
504				{
505					ball.LinearVelocity = new Vector(setVelocity, 0.0f);
506					ballVelocity = setVelocity / 1000.0f;
507				}
508				else if (Input.Mouse.RightButtonReleased)
509				{
510					ball.Position2D = startPosition;
511					ballPosition = startPosition + new Point(0, 0.2f);
512				}
513				else if (Input.Mouse.MiddleButtonReleased)
514				{
515					ball.Stop();
516				}
517
518				// Draw the physics shape as a line circle
519				//Circle.DrawOutline(ball.Position, ball.Radius, Color.Red);
520				ballMaterial.Draw(Rectangle.FromCenter(ball.Position2D,
521					ballMaterial.Size));
522
523				// And a second ball without physics
524				ballMaterial.Draw(Rectangle.FromCenter(ballPosition,
525					ballMaterial.Size));
526
527				ballPosition += ballVelocity * Time.Delta;
528
529				if (Input.Keyboard.ShiftIsPressed)
530				{
531					Font.DrawTopLeftInformation("ballPosition=" + ballPosition);
532				}
533			});
534		}
535		#endregion
536
537		#region BugTest (Static)
538		/// <summary>
539		/// Test method for bug #3496 to check if 2 balls and a box collide properly
540		/// </summary>
541		[Test]
542		public static void BugTest()
543		{
544			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
545			// Enable debug drawing
546			Physics.DebugEnabled = true;
547
548			// Create some (2 balls and 1 box) and the ground and let them 
549			// collide due to gravity
550			List<PhysicsBody> balls = new List<PhysicsBody>();
551
552			PhysicsBody box = null;
553			PhysicsBody ground = null;
554			float radius = 0.05f;
555			float mass = 1.0f;
556
557			Rectangle rectangle = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
558			Rectangle boxRect = new Rectangle(0.0f, 0.0f, 0.05f, 0.05f);
559
560			for (int index = 0; index < 10; index++)
561			{
562				PhysicsBody ball = Physics.CreateCircle(radius, mass);
563				ball.Position = new Vector(RandomHelper.RandomFloat(-0.5f, 0.5f),
564					RandomHelper.RandomFloat(-0.5f, 0.5f), 0.0f);
565				ball.Friction = 1.0f;
566				ball.IsStatic = false;
567
568				// Set debug color to red.
569				ball.DebugColor = Color.Red;
570
571				balls.Add(ball);
572			}
573
574			box = Physics.CreateRectangle(
575				boxRect.Width, boxRect.Height, 1.0f);
576			box.Position = new Vector(.5f, .4f, 0.0f);
577			box.IsStatic = false;
578			box.Friction = 1.0f;
579			box.DebugColor = Color.Green;
580
581			// set our ground
582			ground = Physics.CreateRectangle(
583				rectangle.Width, rectangle.Height, 1f);
584			ground.Position = new Vector(rectangle.Center, 0.0f);
585			ground.IsStatic = true;
586			ground.Friction = 1.0f;
587			ground.DebugColor = Color.Yellow;
588
589			Application.Start();
590		}
591		#endregion
592
593		#region TestRayCast (Static)
594		/// <summary>
595		/// Test ray cast
596		/// </summary>
597		[Test]
598		public static void TestRayCast()
599		{
600			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
601			// create a plane so that every ray that doesnt hit an object will hit
602			// the plane
603			//const int size = 24;
604			//const int height = -5;
605
606			//// add a plane to the physics world 
607			//VisualPhysicsPlane visualPhysicsPlane = new VisualPhysicsPlane(size, size, new Vector(0, 0, height));
608
609			//// create a box and a sphere
610			//VisualPhysicsBox visualBox = new VisualPhysicsBox(new Vector(-2, 0, 0), 4);
611			//VisualPhysicsSphere visualSphere = new VisualPhysicsSphere(new Vector(5, 0, 0), 2);
612
613			//// this line of code also sets the camera, i.e. ViewProjection matrix
614			//LookAtCamera cam = new LookAtCamera(new Vector(0, 25, 10));
615
616			//// create a moving ray
617			//Vector rayStart = new Vector(0, 0, 10);
618			//Vector lookTarget = new Vector();
619			//Ray testRay = new Ray(rayStart, lookTarget - rayStart);
620
621			//Application.Start(delegate
622			//{
623			//  IPhysicsShape3D catchedObject;
624			//  Vector intersection;
625			//  Vector normal;
626
627			//  //Draw the sphere and box
628			//  visualBox.Draw();
629			//  visualSphere.Draw();
630
631			//  // perform ray cast
632			//  bool rayCasted = PhysicsManager.RayCast(testRay,
633			//      out catchedObject, out intersection, out normal);
634
635			//  // update the objects color according to the result of the ray cast
636			//  if (catchedObject == visualBox.PhysicsBox)
637			//    visualBox.DebugDrawColor = Color.Red;
638			//  else
639			//    visualBox.DebugDrawColor = Color.Green;
640
641			//  if (catchedObject == visualSphere.PhysicsSphere)
642			//    visualSphere.DebugDrawColor = Color.Red;
643			//  else
644			//    visualSphere.DebugDrawColor = Color.Green;
645
646			//  //Draw the physics plane
647			//  visualPhysicsPlane.Draw();
648
649			//  // render the line according to the deleted intersection
650			//  if (rayCasted)
651			//  {
652			//    // render up to the intersection point
653			//    Line.Draw(testRay.Position, intersection, Color.Yellow);
654
655			//    // render the surface normal at this point
656			//    Line.Draw(intersection, intersection + normal, Color.White);
657			//  }
658			//  else
659			//  {
660			//    Line.Draw(testRay.Position,
661			//        testRay.Position + 15.0f * testRay.Direction, Color.Yellow);
662			//  }
663
664			//  // update the direction of the ray
665			//  lookTarget.X = 8 * (float)Math.Cos(0.3f * Time.CurrentExactTime); ;
666			//  lookTarget.Y = 2.0f * (float)Math.Sin(5.0f * Time.CurrentExactTime);
667			//  testRay.Direction = Vector.Normalize(lookTarget - testRay.Position);
668			//});
669		}
670		#endregion
671
672		#region TestCollisionEvents (Static)
673		/// <summary>
674		/// Performs collision check between two bodies with events.
675		/// </summary>
676		[Test]
677		public static void TestCollisionEvents()
678		{
679			Physics.Gravity = new Vector(0.0f, 0.0981f, 0.0f);
680			// Enable debug drawing
681			Physics.DebugEnabled = true;
682
683			// Create some (2 balls and 1 box) and the ground and let them 
684			// collide due to gravity
685			List<PhysicsBody> balls = new List<PhysicsBody>();
686
687			PhysicsBody box = null;
688			PhysicsBody ground = null;
689			float radius = 0.05f;
690			float mass = 1.0f;
691
692			Rectangle rectangle = new Rectangle(0.1f, 0.65f, 0.8f, 0.1f);
693			Rectangle boxRect = new Rectangle(0.0f, 0.0f, 0.05f, 0.05f);
694
695			for (int index = 0; index < 10; index++)
696			{
697				PhysicsBody ball = Physics.CreateCircle(radius, mass);
698				ball.Position = new Vector(RandomHelper.RandomFloat(-0.5f, 0.5f),
699					RandomHelper.RandomFloat(-0.5f, 0.5f), 0.0f);
700				ball.Friction = 1.0f;
701				ball.IsStatic = false;
702
703				// Set debug color to red.
704				ball.DebugColor = Color.Red;
705				ball.Name = "Ball_" + index;
706				balls.Add(ball);
707			} // for
708
709			box = Physics.CreateRectangle(
710				boxRect.Width, boxRect.Height, 1.0f);
711			box.Position = new Vector(.5f, .4f, 0.0f);
712			box.IsStatic = false;
713			box.Friction = 1.0f;
714			box.DebugColor = Color.Green;
715			box.Name = "Box";
716
717			// set our ground
718			ground = Physics.CreateRectangle(
719				rectangle.Width, rectangle.Height, 1f);
720			ground.Position = new Vector(rectangle.Center, 0.0f);
721			ground.IsStatic = true;
722			ground.Friction = 1.0f;
723			ground.DebugColor = Color.Yellow;
724			ground.Name = "PlaneBody";
725			ground.CollisionBegin += ground_CollisionBegin;
726			ground.CollisionEnd += ground_CollisionEnd;
727
728			Application.Start();
729		}
730		#endregion
731
732		#region Methods (Private)
733
734		#region ground_CollisionBegin
735		private static void ground_CollisionBegin(PhysicsBody other)
736		{
737			Log.Info(
738				string.Format("Given body '{0}' ends collision with this plane body.",
739					other.Name)
740				);
741		}
742		#endregion
743
744		#region ground_CollisionEnd
745		private static void ground_CollisionEnd(PhysicsBody other)
746		{
747			Log.Info(
748				string.Format("Given body '{0}' collide with this plane body.",
749					other.Name)
750				);
751		}
752		#endregion
753
754		#endregion
755	}
756}