PDA

View Full Version : Billboarding my particle system

roguespear
01-02-2005, 07:02 AM
Hiya guys and a Happy New Year to all of you.

I am trying to do a particle system to represent snow and rain. At the moment i am concentrating on the snow and using a snow flake texture mapped to a quad. The problem is I am trying to use billboarding so the quad is constantly facing the viewer. At certain points the quad faces the viewer and at others it doesnt.

I am trying to draw the quad with two points remaining the same and the outer points rotating as the view does.

glPushMatrix();

float rotX, rotY;

rotX = cos(yaw*PI/180);
rotY = sin(yaw*PI/180);

glTexCoord2f(0,0);
glVertex3f(tempX+rotX,tempY-1,tempZ+rotY);
glTexCoord2f(1,0);
glVertex3f(tempX-rotX,tempY-1,tempZ-rotY);
glTexCoord2f(1,1);
glVertex3f(tempX-rotX,tempY+1,tempZ-rotY);
glTexCoord2f(0,1);
glVertex3f(tempX+rotX,tempY+1,tempZ+rotY);
glEnd();

glPopMatrix();
particles[i]->setX(tempX-wind.x);
particles[i]->setY(tempY-gravity-wind.y);
particles[i]->setZ(tempZ-wind.z);
if(particles[i]->getY() < 0)
particles[i]->kill();where yaw is the angle i rotate the eye around the y-axis.

When rotating my eye i use a combination of rotation and translations.

glRotatef( -pitch, 1.0, 0.0, 0.0 );
glRotatef( -yaw, 0.0, 1.0, 0.0 );
glTranslatef( -eyeX, -eyeY, -eyeZ );
If ne1 could help me i would really appreciate it. If ne more info is needed please just say and ill provide what i can.

Thanx

Tom

plasmonster
01-05-2005, 08:55 PM
Hi Tom,

I think your problem stems from a little confusion about rotations. In your code, you add to "temp"--which I assume is the billboard origin--the signed components of the rotated vector, "rot". In doing so, you have a situation sort of like this:

z
\ |
\ |
\ | rotation direction
o B, C \ | o A, D
\ | *
\| *
origin *------------ x
\
\
\
\
\
vertical plane where "origin" is the center of the billboard; A, B, C, and D are your final vertex positions; and the camera is looking in the rotation direction determined by the yaw angle around the y-axis (into the page).

What you would probably like to have is something like this:

z
\ |
o A,D|
\ | rotation direction
\ | *
\ | *
\| * rot
origin *------------ x
\
\
\
o B,C
\
vertical plane So what you need is the vertical plane that's orthogonal (perpendicular) to the rotation direction; in this plane you can wind your quad. You know that the quad will be vertical; so if you cross the rotation direction vector with the up vector (0,1,0) you will have a "right" vector (right = rotation direction x up). All these vectors summed together--the right and up vectors, scaled by the quad's width/2 and height/2 respectively, along with the billboard origin--will generate the desired vertex positions. That is,

A = origin - right*width/2 + up*height/2
B = origin + right*width/2 + up*height/2
C = origin + right*width/2 - up*height/2
D = origin - right*width/2 - up*height/2

This is sometimes called cylindrical billboarding, since the quad is constrained to rotate in a cylinder whose base is parallel to the camera's ground plane. I, and some others of questionable repute, call them rope-sprites.

The rotation vector is constant, unless the camera changes direction. Consequently, the right and up vectors are constant as well. You could therefore consider the right vector calculation a per-frame affair, leaving only the scales and adds on a per-quad basis.

I noticed that you had a redundant Push and PopMatrix in your code snippet. Just in case that's an indication, I would advise you to resist the temptation to use a technique that I've seen floating around online, involving manipulation of the modelview matrix. While this practice is informative, and it certainly works, it is not an efficient use of the GL's matrix mechanism, especially for large systems of particles. Toward that end, there are some clever methods for dealing with billboards in OpenGL's programmable pipeline.

I hope this helps.