Professional Documents
Culture Documents
B
J as Usenet, particle systems are a pretty hot issue. This may be partially a result
of the phenomenal success of QUAKE, with its use of particles for smoke,
blood trails, and spark falls.
or subtracted from base emitNumber. By spin. Those two angles are the rotation
adjusting these two values, you can about the y axis (yaw or azimuth
change the effect from a constant, defined by θ) and the rotation about the
steady stream to a more random flow. x axis (pitch or inclination defined by
The formula for calculating how many ψ). These angles are varied by a random
particles to emit each frame is value and then converted to a direction
particleCount = emitNumber + (emitVariance * vector for each particle.
RandomNum()); The conversion process for generating
Where RandomNum() is a function that this direction vector is pretty easy. It
returns a number between -1.0 and 1.0. requires some general 3D rotation tech-
These techniques are also used to vary niques and some basic matrix math.
the color, direction, speed, and life span A rotation about y is defined as
of a particle. The color is a special case x’ = x*cos(θ) + z*sin(θ);
because I want the color to change over y’ = y;
the life span of the particle. I calculate z’ = -x*sin(θ) + z*cos(θ)
two randomly varied colors as above or, in matrix form,
and then divide the difference between cos(θ) 0 -sin(θ)
them by the life. This creates the color
Roty(θ) = 0 1 0
delta that is added to each particle each sin(θ) 0 cos(θ)
14 frame of its life.
I now need to describe the direction A rotation of about x is
particles as colored points, so I also in which the particles should be emit- x’ = x;
need to know the current color of this ted. We really only need to describe two y’ = y*cos(ψ) - z*sin(ψ);
particle and the previous color for angles of rotation about the origin z’ = y*sin(ψ) + z*cos(ψ)
antialiasing. In order to change the because the particles are single points in or
color over time, I’m going to store the space, and I’m not concerned with the
amount of change in color per frame
also. The last piece of information that L I S T I N G 2 . The emitter structure.
I need is the life count for this particle.
This is the number of frames that this struct tEmitter
particle will exist before dying. {
You can see a data structure for my long id; // EMITTER ID
particles in Listing 1. If you wished to char name[80]; // EMITTER NAME
make your particle system more com- long flags; // EMITTER FLAGS
// TRANSFORMATION INFO
plex, it would be very easy to add prop-
tVector pos; // XYZ POSITION
erties here. You could animate the size float yaw, yawVar; // YAW AND VARIATION
of the particles by adding a size, the float pitch, pitchVar; // PITCH AND VARIATION
transparency by adding an alpha com- float speed,speedVar;
ponent to the color. You could further- // Particle
more add mass, other physical proper- tParticle *particle; // NULL TERMINATED LINKED LIST
int totalParticles; // TOTAL EMITTED AT ANY TIME
ties, or any number of other variables.
int particleCount; // TOTAL EMITTED RIGHT NOW
int emitsPerFrame, emitVar; // EMITS PER FRAME AND VARIATION
int life, lifeVar; // LIFE COUNT AND VARIATION
The Emitter tColor startColor, startColorVar; // CURRENT COLOR OF PARTICLE
tColor endColor, endColorVar; // CURRENT COLOR OF PARTICLE
he particle emitter is the entity // Physics
T responsible for creating the parti-
cles in the system. This is the object
};
tVector force; // GLOBAL GRAVITY, WIND, ETC.
ent ways (see “References”). Along with on antialiasing, the system draws a
a point source, he describes methods gouraud-shaded line from the previous
for creating particles on the surface of a position and color to the new position
sphere, within the volume of a sphere, and color. This tends to smooth out the
on the surface of a 2D disc, and on the look at the cost of some rendering
surface of a rectangle. These different speed. You can see the difference in
methods will create various effects, so Figures 1a and 1b. The first image is a
you should experiment to find what simple point rendering, and the second
works best for your application. is composed of line segments.
points. You can also calculate a polygon // APPLY GLOBAL FORCE TO DIRECTION
around the point so that it always faces particle->dir.x += emitter->force.x;
the camera like a billboard. Then apply particle->dir.y += emitter->force.y;
any texture you like to the polygon. By particle->dir.z += emitter->force.z;
scaling the polygon with the distance
// SAVE THE OLD COLOR
from the camera, you can create per- particle->prevColor.r = particle->color.r;
spective. Another option is to draw a 3D particle->prevColor.g = particle->color.g;
object of any type at the position of the particle->prevColor.b = particle->color.b;
particle.
I took the simple route. I just drew // GET THE NEW COLOR
particle->color.r += particle->deltaColor.r;
each particle as a 3D point. If you turn
particle->color.g += particle->deltaColor.g;
particle->color.b += particle->deltaColor.b;
particle->life—; / / I T I S A C Y C L E O L D E R
return TRUE;
}
else if (particle != NULL && particle->life == 0)
{
// FREE THIS SUCKER UP BACK TO THE MAIN POOL
if (particle->prev != NULL)
particle->prev->next = particle->next;
else
emitter->particle = particle->next;
// FIX UP THE NEXT’S PREV POINTER IF THERE IS A NEXT
if (particle->next != NULL)
particle->next->prev = particle->prev;
particle->next = m_ParticlePool;
m_ParticlePool = particle; // NEW POOL POINTER
emitter->particleCount—; // ADD ONE TO POOL
}
F I G U R E S 1 a A N D 1 b . 1a shows return FALSE;
}
point rendering and 1b shows a com-
/// updateParticle ///////////////////////////////////////////////////////////////
position of line segments.