|
I was
all set to start talking about how to handle collision response. I thought
I could just have these objects that you could move around, m
ake collide,
and then watch their responses. Yeah, collision response, that will
be great! Then I thought, "How am I going to get these objects
flying around in the first place?" Well, I could give each object
an initial velocity and they would collide. But, I would need world
boundaries for those objects to bounce off of so they would stay in
play. To direct the objects, I need to be able to apply force. Suddenly,
instead of a nice collision demo, I had designed Asteroids. All
I wanted was a little demonstration of a fairly simple concept and instead
I ended up applying forces and acceleration to particles. I had stumbled
on the big "D" word: Dynamics.
That’s
alright. I will not be afraid. I always say, "Turn a problem into
an opportunity." However, physics is a huge field full of fertile
topics that can be distilled into nice column-sized pieces. So once
more good friends, into the breach.
What’s
So Dynamic About It?
When I
was writing about inverse kinematics back in September, I was only really
interested in kinematics: that is, the study of motion without regard
to the forces that cause it. Dynamics, I said, concerns how forces are
used to create motion, and I didn’t want to open up that can of worms.
Well, the can is now open and the worms are climbing all over.
I’m going
to have to recap a bit, but I suggest you go back and reread Chris Hecker’s
column from the October/November 1996 Game Developer, "Physics,
the Next Frontier." If you don’t have the magazine handy, that
article as well as other physics related articles written by Chris Hecker
are available on the Definition Six web site at http://www.d6.com/users/checker.
This month,
I’m going to focus on particle dynamics. What is particularly important
about particle dynamics is the relationship between force, f, the mass
of a particle, m, and the acceleration of that particle, a. This can
be stated in the familiar Newtonian notation as f = ma. You may recall
that the acceleration of a particle is the derivative with respect to
time of the velocity of that particle, v. Likewise, the velocity of
the particle is the derivative with respect to time of the position
of the particle, x. You can see how this relationship works in the following
equation:
So, let
me state the problem I’m trying to solve. Given a set of forces acting
on a particle at time t, where will that particle be after a small amount
of time has passed? It’s clear that with the value of the force and
the mass of the particle, I can obtain the acceleration of the particle.
If I integrate that acceleration with respect to t, I’ll end up with
the new velocity of the particle. If I integrate again, I get the new
position. Easy, right?
The structure
for a particle is in Listing 1. It’s easier
to store 1/m for the particle because this is what I need in the equations.
The forces that act on the particle accumulate in the f term. With this
information, I can integrate the dynamic system forward in time to establish
a new position for the particle. This process involves solving ordinary
differential equations. Fortunately, Chris’s column described a numerical
method of solving these problems. Listing 2
contains code that uses the simplest numerical integrator, known as
Euler’s method, to compute the new state of the system. The great thing
about this integrator is that it’s simple to implement and understand.
However, because it’s a simple approximation, it’s subject to numerical
instability, as we will see later.
Listing
1. The particle type.
// TYPE FOR A PHYSICAL
PARTICLE IN THE SYSTEM
struct tParticle
{
tVector
pos; // Position of Particle
tVector
v; // Velocity of Particle
tVector
f; // Total Force Acting on Particle
float oneOverM; //
1 / Mass of Particle
};
Listing
2. My simple Euler intergrator.
///////////////////////////////////////////////////////////////////////////////
// Function: Integrate
// Purpose: Calculate new Positions and Velocities given a deltatime
// Arguments: DeltaTime that has passed since last iteration
// Notes: This integrator uses Euler's method
///////////////////////////////////////////////////////////////////////////////
void CPhysEnv::Integrate( float DeltaTime)
{
/// Local Variables //////////////////////////////////////////////////////////
int loop;
tParticle *source,*target;
///////////////////////////////////////////////////////////////////////////////
source = m_CurrentSys; // CURRENT STATE OF PARTICLE
target = m_TargetSys; // WHERE I AM GOING TO STORE
THE NEW STATE
for (loop = 0; loop < m_ParticleCnt; loop++)
{
// DETERMINE THE NEW VELOCITY FOR THE PARTICLE
target->v.x = source->v.x + (DeltaTime *
source->f.x * source->oneOverM);
target->v.y = source->v.y + (DeltaTime *
source->f.y * source->oneOverM);
target->v.z = source->v.z + (DeltaTime *
source->f.z * source->oneOverM);
//
SET THE NEW POSITION
target->pos.x = source->pos.x + (DeltaTime
* source->v.x);
target->pos.y = source->pos.y + (DeltaTime
* source->v.y);
target->pos.z = source->pos.z + (DeltaTime
* source->v.z);
source++;
target++;
}
}
You
Can’t Force Me to Move, Can You?
I now
have a method for dynamically moving particles around in a realistic
fashion. However, to get anything interesting to happen, I need to get
things moving. This requires the application of some brute force, or
several forces. But what kinds of forces do I want to apply to my little
particles?
Well,
the obvious force that has been applied to objects in games since the
beginning of computer simulations is gravity. Gravity is a constant
force that is being applied to all particles. In order to realistically
simulate gravity, force must be added into the particle’s force accumulator
every system update. In general, this force is a vector pointing down
along the y axis. However, there’s nothing to stop a simulator from
having a gravity vector that points in a different direction. In fact,
one of the very cool things about having a good physical simulation
is that gravity can change and things will still "look" correct.
This realistic look may not occur if you are trying to hand animate
an object.
|