![]() |
Multimedia »
DirectX »
General
Intermediate
Believable physics in C#By Mårten RHow to create believable physics using C#. |
C#.NET 1.1, Win2K, WinXP, Win2003, DirectX, VS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

After reading the great article 'Advanced Character Physics' [1], I realized that, contrary to my earlier belief, creating believable physics on a computer isn't overly complicated. In fact, it's rather simple and isn't especially CPU-hungry neither. As I figured this might be an interesting topic for some developers, I put together these projects and this article for CodeProject.
To be able to compile and use the projects, you'll need the managed extensions for Directx9 [2]. You might need to perform an extra step after installing the DirectX9 SDK. Please refer to the readme.txt that comes with the DirectX9 SDK. The project ParticleSystem depends upon DirectX9 for some basic operations on vectors and matrices. The test application depends on DirectX9 more heavily as it uses DirectX9 to visualize the particle-constraint system.
Once you have the managed extensions for DirectX9, it should be easy to compile the projects.
You should see a parachuting box not unlike the picture above. There are simple commands to move the viewpoint as well as change some parameters of the particle-constraint system.
The code in the test project is close to awful as I only patched the DirectX9 wizard generated code just enough so I could view the particle-constraint system. The interesting code is in the ParticleSystem project.
Let's assume you want to create a very simple system with only one small box in it.
// Begin a transaction
ParticleSystem.Transaction lTransaction = ps.GetTransaction();
// Adds a global constraint to the system (to make sure that the box
// doesn't fall and fall and fall)
lTransaction.AddGlobalConstraint(new AxisAlignedBox(
new Vector3(-10, -15, -10),
new Vector3(10, 15, 10)));
// Set the gravity vector of the system
ps.Gravity = new Vector3(0, -1, 0);
// Creates a stick-constraint factory (since we want our box to be created
// using stiff stick-constraints)
Tools.ITwoParticleConstraintFactory lStickConstraintFactory =
new Tools.StickConstraintFactory();
// Create the box at position (0,0,0), with mass 10.0 and side-length 1.0
Tools.CreateBox(
new Vector3(0.0f, 0.0f, 0.0f),
10.0f,
1.0f,
lStickConstraintFactory,
lTransaction);
// Commit the added particles and constraints to the system
lTransaction.Commit();
If you want to test what the example looks like, just replace the code in the function InitializeParticleSystem with the code above. Also you have to add the row windEffect = null;
Now let's say you wish to attach a chain to the box and the non moving particle. The code would then look as this:
// Begin a transaction
ParticleSystem.Transaction lTransaction = ps.GetTransaction();
// Adds a global constraint to the system (to make sure that the box
// doesn't fall and fall and fall)
lTransaction.AddGlobalConstraint(new AxisAlignedBox(
new Vector3(-10, -15, -10),
new Vector3(10, 15, 10)));
// Set the gravity vector of the system
ps.Gravity = new Vector3(0, -1, 0);
// Creates a stick-constraint factory (since we want our box to be created
// using stiff stick-constraints)
Tools.ITwoParticleConstraintFactory lStickConstraintFactory =
new Tools.StickConstraintFactory();
// Create the box at position (0,0,0), with mass 10.0 and side-length 1.0
Particle[] lBoxParticles = Tools.CreateBox(
new Vector3(0.0f, 0.0f, 0.0f),
10.0f,
1.0f,
lStickConstraintFactory,
lTransaction);
// Create a single particle
Particle lParticle = new Particle(1.0f, new Vector3(0.0f, 5.0f, 0.0f));
// Make the particle non-moving
lParticle.Immoveable = true;
// Add the particle the system
lTransaction.AddParticle(lParticle);
// Create a chain between the single particle and a box-particle
Tools.CreateChain(
lParticle,
lBoxParticles[0],
1.0f,
6,
lStickConstraintFactory,
lTransaction);
// Commit the added particles and constraints to the system
lTransaction.Commit();
For a more complex example, see the parachuting box code in the ParticleSystemTestApplication.
ParticleSystem using the Transaction object. You get an instance of a Transaction object by calling GetTransaction() on an instance of a ParticleSystem. Remember to commit.
TimeStep().
IConstraint which only has one method: Apply().
Apply()? It should check if the constraint is invalid. If its invalid, then it should move the particles that's part of the constraint so that the constraint becomes valid again. As an example, take a look at the StickConstraint; if the particles are too far away, it pulls them together until they are at the correct distance. If they are too close, it pushes them away until they are at the correct distance. It also looks at the mass of the particles and moves differently depending on how much they weigh. Please see 'Advanced Character Physics' [1] for a better insight of how to create constraints.
Tool-class contains a lot of static methods intended to make it easier for a developer. This is of course an ironical nudge towards the impossible 'exercises for the interested reader' that are so often found in student literature.
IEffect instead of an intrinsic part of the ParticleSystem-class. This to allow systems where you have a centre of gravity or many gravity sources.
Thomas Jakobsen - for without his great article [1], I doubt that I ever would have started playing around with imaginary particles and constraints (and thus leading a lesser life). Also, I have shamelessly robbed code from his article when building ParticleSystem.
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 29 Dec 2003 Editor: Nishant Sivakumar |
Copyright 2003 by Mårten R Everything else Copyright © CodeProject, 1999-2009 Web22 | Advertise on the Code Project |