particle system question

There is still one peice of particle systems that confuses me.
If I let the user rotate the camera to some arbitrary location, how do I determine the angles for making the particle surfaces parallel to the camera view?

Is this something I do the math for by hand (calculate particle’s angle to camera and build polygon from there), or is there a quick gl function I can use to make polygons face the camera?


it depends how you’re doing your scene rotations. if you’re following the advice of the redbook, and rotating the model matrix rather than the view matrix, then you could do this:


/* Setup the projection and view. */
gluPerspective( 30.0, 1.33333333, 5.0, 100.0);

gluLookAt(0.0, 0.0, 40.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.);

	/* Perform scene rotations */
	glRotatef(angle2, 1.0, 0.0, 0.0);
	glRotatef(angle, 0.0, 1.0, 0.0);
	/* Draw your scene */

/* Draw your particles */


at least, this is my theory. i have yet to test it, so take it with a grain of salt. you might take a look at this open source particle system for ideas:

[This message has been edited by phlake (edited 07-10-2000).]

Since I store the camera angles in my engine, I just wrote a angle to vector function that returns a forward, right, and up vector. Such a function can be derived form a Euler Angle matrix.

Then if have the particles origin, use your up and right vectors to build the particle. Since these vectors are perpendicular to the forward vector, you’ll end up with a surface that is always parallel to the view screen.

As always, many ways to accomplish a task.

After you’ve set up the camera. You could just extract the vectors from the matrix.

[This message has been edited by Blaze (edited 07-10-2000).]

Phlake: It sounds like that would keep all the particles in the same relative positions no matter the camera rotation.

El Jefe: humm… I store my camera angles too. sounds like that’s what I’m looking for.

Blaze: that sounds like the best plan, but I don’t know how to do that.

thanks guys,

hmmm… good point. i’m glad i added the “grain of salt” clause… (doh!)

Sorry to barge in. But this is the information I was looking for.

I figured I could retrieve the forward vector by multiplying 0,0,-1 by the current camera-rotation-matrix right? That should work.
The right vector would be 1,0,0 and the up vector would be 0,1,0 multiplied by the same matrix. No?

But how do I figure out the vertices for a particle when I have those vectors?
Say my particles origin is at x,y,z and the size is in p_size, what’s the formula, when you have the vectors (v_up,v_right)?

How do I do it?

i decided i’d go find some information on this, so here’s the math:

and this page contains a nice (ie, short) code sample (fifth example down):

The other solution is to do all your own transformations (no glRotate or glTranslate) and just convert the particle’s origin into eye coordinates and then determine the vertices directly (you have center of particle and size right?) Then you don’t have to worry with turning the particles so that remain facing forward.

[This message has been edited by DFrey (edited 07-11-2000).]

yeah, that would give the desired effect, but it seems like it would be difficult to size the particles correctly (due to perspective).
personally, i prefer the “rotate the particle” method over the “translate the particle” method.

however, i’ve found a demo that uses this technique, for those interested.

Well, if you have the x,y,z ( origin ) of the particle…the size of the particle…and a up and right vector…try something like this:

float scale = particle_size * 0.5f;
vector vert[4];

VectorMA( origin, -scale, up, vert[0] );
VectorMA( vert[0], -scale, right, vert[0] );

VectorMA( origin, -scale, up, vert[1] );
VectorMA( vert[1], scale, right, vert[1] );

VectorMA( origin, scale, up, vert[2] );
VectorMA( vert[2], scale, right, vert[2] );

VectorMA( origin, scale, up, vert[3] );
VectorMA( vert[3], -scale, right, vert[3] );

// Now you have your oriented quad
…add quad into engine, heh heh

BTW, VectorMA is vector multiply and add, defined something like this:

void VectorMA( vector origin, float scale, vector dir, vector result)
result[0] = origin[0] + dir[0] * scale;
result[1] = origin[1] + dir[1] * scale;
result[2] = origin[2] + dir[2] * scale;