📄 particlesystem.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns:o>
<head>
<title></title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="VisualStudio.HTML" name="ProgId">
<meta content="Microsoft Visual Studio .NET 7.1" name="Originator">
</head>
<body>
<H1><FONT face="Verdana">Believable physics in C#</FONT></H1>
<P><FONT face="Verdana"></FONT> </P>
<P><FONT face="Verdana"><IMG src="parachute.JPG"></FONT></P>
<H2><FONT face="Verdana"></FONT> </H2>
<H2><FONT face="Verdana">Abstract</FONT></H2>
<P><FONT face="Verdana">This article demonstrates what an implementation of believable
physics using Verlet Integration could look like. Provided with the article are
two projects; ParticleSystem and ParticleSystemTestApplication.</FONT></P>
<H2><FONT face="Verdana">Introduction</FONT></H2>
<P><FONT face="Verdana">After reading the great article 'Advanced Character Physics' <A href="#REF_1">
[1]</A> I realized that, contrary to my earlier belief, creating believable
physics on a computer isn't overly complicated. In fact, its 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.</FONT></FONT></P>
<H2><FONT face="Verdana">Setting up</FONT></H2>
<H3><FONT face="Verdana">Requirements</FONT></H3>
<P><FONT face="Verdana">To be able to compile and use the projects you'll
need the managed extensions for Directx9 <A href="#REF_2">[2]</A>.
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.</FONT></P>
<H3><FONT face="Verdana">Compiling</FONT></H3>
<P><FONT face="Verdana">Once you have managed extension for DirectX9 it should be easy
to compile the projects.</FONT></P>
<P><FONT face="Verdana">Running the test application</FONT></P>
<P><FONT face="Verdana">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.</FONT></P>
<UL>
<LI>
<FONT face="Verdana">Arrow-keys: Moves the viewpoint</FONT>
<LI>
<FONT face="Verdana">A: Makes gravity vector pointing downward</FONT>
<LI>
<FONT face="Verdana">B: Makes gravity vector pointing upward</FONT>
<LI>
<FONT face="Verdana">S: Shakes the particles</FONT>
<LI>
<FONT face="Verdana">K: Increase the strength of the wind (that affects the
parachute).</FONT></FONT>
<LI>
<FONT face="Verdana">L: Decrease the strength of the wind (that affects the
parachute).</FONT></LI></UL>
<P><FONT face="Verdana">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.</FONT></P>
<H2><FONT face="Verdana">How to create a simple particle-constraint system</FONT></H2>
<P><FONT face="Verdana">Let's assume you want to create a very simple system with only
one small box in it.</FONT></P>
<FONT face="Courier New">
<P><BR>
<FONT size="2">ParticleSystem.Transaction lTransaction = ps.GetTransaction();
<BR>
// Adds a global constraint to the system (to make sure that the box doesn't
fall and fall and fall)<BR>
lTransaction.AddGlobalConstraint(new AxisAlignedBox( new Vector3(-10, -15,
-10), new Vector3(10, 15, 10)));
<BR>
// Set the gravity vector of the system<BR>
ps.Gravity = new Vector3(0, -1, 0);
<BR>
// Creates a stick-constraint factory (since we want our box to be created
using stiff stick-constraints)<BR>
Tools.ITwoParticleConstraintFactory lStickConstraintFactory = new
Tools.StickConstraintFactory();
<BR>
// Create the box at position (0,0,0), with mass 10.0 and side-length 1.0<BR>
Tools.CreateBox(new Vector3(0.0f, 0.0f, 0.0f), 10.0f, 1.0f,
lStickConstraintFactory, lTransaction);
<BR>
// Commit the added particles and constraints to the system<BR>
lTransaction.Commit(); </FONT>
</FONT></P>
<P><FONT face="Verdana"><EM>If you want to test what example looks like just replace the
code in the function InitializeParticleSystem with the code above. Also
you have to add the row windEffect = null;</EM></FONT></P>
<P><FONT face="Verdana">Now let's say you wish to attach a chain to the box and non
moving particle.</FONT></P>
<P><FONT face="Verdana">The code would then look as this:</FONT></P>
<P><FONT face="Courier New" size="2">ParticleSystem.Transaction lTransaction =
ps.GetTransaction();
<BR>
// Adds a global constraint to the system (to make sure that the box doesn't
fall and fall and fall)
<BR>
lTransaction.AddGlobalConstraint(new AxisAlignedBox( new Vector3(-10, -15,
-10), new Vector3(10, 15, 10)));
<BR>
// Set the gravity vector of the system
<BR>
ps.Gravity = new Vector3(0, -1, 0);
<BR>
// Creates a stick-constraint factory (since we want our box to be created
using stiff stick-constraints)
<BR>
Tools.ITwoParticleConstraintFactory lStickConstraintFactory = new
Tools.StickConstraintFactory();
<BR>
// Create the box at position (0,0,0), with mass 10.0 and side-length 1.0
<BR>
Particle[] lBoxParticles = Tools.CreateBox(new Vector3(0.0f, 0.0f, 0.0f),
10.0f, 1.0f, lStickConstraintFactory, lTransaction);
<BR>
// Create a single particle
<BR>
Particle lParticle = new Particle(1.0f, new Vector3(0.0f, 5.0f, 0.0f));
<BR>
// Make the particle non-moving
<BR>
lParticle.Immoveable = true;
<BR>
// Add the particle the system
<BR>
lTransaction.AddParticle(lParticle);
<BR>
// Create a chain between the single particle and a box-particle
<BR>
Tools.CreateChain(lParticle, lBoxParticles[0], 1.0f, 6,
lStickConstraintFactory, lTransaction);
<BR>
// Commit the added particles and constraints to the system
<BR>
lTransaction.Commit(); </FONT>
</P>
<P><FONT face="Verdana">For a more complex example see the parachuting box code in the
ParticleSystemTestApplication.</FONT></P>
<H2><FONT face="Verdana">A tiny introduction to the ParticleSystem project</FONT></H2>
<OL>
<LI>
<FONT face="Verdana">The project is named ParticleSystem. A better name would be
ParticleConstraintSystem because that's essentially what it is.</FONT>
<LI>
<FONT face="Verdana">The design goal of ParticleSystem was primarily to make it
easy for a developer to add new constraints, effects and global constraints
classes. Also, I wanted to make it reasonably easy to create "experiments".
Performance hasn't been a primary concern.</FONT>
<LI>
<FONT face="Verdana">You add instances of particles, constraints, effects and
global constraints to a 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.</FONT>
<LI>
<FONT face="Verdana">To generate the next frame you call TimeStep().</FONT>
<LI>
<FONT face="Verdana">You can create own constraints, effects and global
constraints by implementing the required interface. For instance to
create a constraint the object has to implement IConstraint which only has
one method: Apply().</FONT>
<LI>
<FONT face="Verdana">A reasonable question is what should a constraint do when it
gets a call to Apply()? It should check if the constraint is invalid. If its
invalid than 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 move differently depending on how much they weigh. Please see
'Advanced Character Physics' for a better insight how to create constraints.</FONT>
<LI>
<FONT face="Verdana">The Tool-class contains a lot of static methods intended to
make it easier for a developer.</FONT></LI></OL>
<H2><FONT face="Verdana">Exercises for the interested reader:</FONT></H2>
<P><FONT face="Verdana">This is of course an ironical nudge towards the impossible
'exercises for the interested reader' that are so often found in student
literature. </FONT>
</P>
<OL>
<LI>
<FONT face="Verdana">Implement a 'real' parachute. Instead of having a fixed wind
blowing upwards the particles in the parachute could be affected by a wind
that's dependent on average velocity of the particles in the parachute. That
is, the faster they are going down the stronger the wind is blowing upwards.</FONT>
<LI>
<FONT face="Verdana">Implement a sailboat game. </FONT>
</LI>
</OL>
<FONT face="Verdana">
<P><BR>
</P>
</FONT>
<H2><FONT face="Verdana">TODO:</FONT></H2>
<UL>
<LI>
<FONT face="Verdana">Add NUnit tests </FONT>
<LI>
<FONT face="Verdana">Improve the documentation and provide a NDoc project </FONT>
<LI>
<FONT face="Verdana">Reengineer the gravity to be a 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.</FONT>
<LI>
<FONT face="Verdana">Implement collision detection between particles and
triangles. This would enable some very cool things such as; solid bodies
bouncing against each other, trampolines and friction.</FONT></LI></UL>
<H2><FONT face="Verdana">Acknowledgments</FONT></H2>
<P class="MsoSubtitle"><SPAN lang="EN-US" style="mso-ansi-language: EN-US"><FONT face="Verdana">Thomas
Jakobsen - for without his great article <A href="#REF_1">[1]</A> 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.</FONT></SPAN></P>
<H2><FONT face="Verdana">About the author</FONT></H2>
<P><FONT face="Verdana">M錼ten R錸ge is at the time of writing 29 years old and have
been working as a professional developer for five years. Lately he has, much to
his own surprise, realized that he actually enjoys writing code for money.</FONT></P>
<H2><FONT face="Verdana">References:</FONT></H2>
<P><FONT face="Verdana"><A id="REF_1">[1] <A href="http://www.ioi.dk/Homepages/thomasj/publications/gdc2001.htm">
Advanced Character Physics</A></A></FONT>
</P>
<P><FONT face="Verdana"><A id="REF_2">[2] <A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9216652f-51e0-402e-b7b5-feb68d00f298&displaylang=en">
DirectX 9.0 SDK Update - (Summer 2003)</A></A></FONT></P>
<P><FONT face="Verdana"></FONT> </P>
<P><FONT face="Verdana"></FONT> </P>
<P><EM><FONT face="Verdana"></FONT></EM> </P>
<P></FONT></P>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -