5
\$\begingroup\$

Languages / Libraries in use: C++, OpenGL, GLUT

Okay, here's the deal.

I've got a particle system which shoots out alpha blended textures to produce a flame. The system only keeps track of very basic things such as, time alive, life, xyz and spread.

The direction in which the flames are currently moving in is purely based on other things which are going on in my code ( I assume ).

My goal however, is to attach the flame to the camera (DONE) and have the flame pointing in the direction my camera is facing (NOT WORKING).

I've tried glRotate for both x,y,z and I can't get it to work properly.

I'm currently using gluLookAt to move the camera, and get the flame to follow the XYZ of the camera by calling glTranslatef(camX, camY - offset, camZ);

Any suggestions on how I can rotate the direction of the flame with the camera would be greatly appreciated.

Heres an image of what I've got: https://i.stack.imgur.com/ha3gh.png

enter image description here

Notes: Crosshair depicts where camera is facing

if I turn the camera, flame doesn't follow the crosshair

Also asked here: https://stackoverflow.com/questions/9560396/rotate-a-particle-system but was referred here

\$\endgroup\$
3
  • \$\begingroup\$ Are you using a vector as your basis for the direction the particles will generally move in? \$\endgroup\$ Mar 5, 2012 at 4:18
  • 1
    \$\begingroup\$ OT: is "Sugar Coating Biscuit Tins" a password generated by xkcd? \$\endgroup\$
    – o0'.
    Apr 5, 2012 at 9:54
  • \$\begingroup\$ make some google search on billboard technique, this old stuff earlier was used for grass and trees but can be found nowadays too. \$\endgroup\$
    – Yevhen
    Aug 23, 2012 at 17:05

3 Answers 3

2
\$\begingroup\$

Just at a quick glance I would check in your code where you are drawing the particle system in comparison to when you actually do the world rotations and translations. Drawing the particle system before you do the any changes could cause it to remain in the same position. Just trying to help in any way. Good Luck!

\$\endgroup\$
0
\$\begingroup\$

Personally, my preference would be to not use gluLookAt. Instead, I'd recommend using gluPerspective to set your perspective transform. Then, push a translation and rotation to define the global co-ordinate space relative to the camera co-ordinates. (That is, don't move the camera, move the world). Draw things whose positions are fixed relative to the camera either at the begining, before you push the global co-ordinate transform, or at the end, after popping the transform.

In this manner, to get a camera at (10,10,0) which is rotated down 30deg about the x axis, you could write:

glLoadIdentity();
gluPerspective(60, 1.5, 0.1, 1000.0);
/* Draw things relative to camera */
glPushMatrkx();
glTranslatef(-10,-10,0);
glRotatef(-30, 1, 0, 0);
/* Draw the world */
glPopMatrix();
/* Relative to camera again*/

If you want to continue to move the camera in the way you are now, here's what I would recommend doing.

Be careful to ensure that the flame co-ordinate system is rotated before it is translated. Remember, matrix multiplication is not communtative, so rotating and then translating is not at all the same as translating and then rotating.

First, compute the rotation axis and angle. Given a unit vector pointing in the camera view direction, V, and another unit vector pointing in the direction of the flame, F, you can compute the required axis of rotation as A = (F cross V). The rotation angle is given by theta = acos(F dot V).

Recalling that GL right-multiplies matrices, call glTranslatef before glRotatef. So you'll get something along the lines of:

glPushMatrix();
glTranslatef(camX, camY - offset, camZ); 
glRotatef(theta * 180 / pi, A.x, A.y, A.z);  // acos usually gives radians
/* Draw fire */
glPopMatrix()
\$\endgroup\$
0
\$\begingroup\$

OpenGL uses a left-handed coordinate system, so the camera's Z axis is always pointing "into" the scene.

What you need to do is rotate the camera's Z axis into object space, which is actually quite simple:

Say the upper 3x3 of your model-view matrix is orthogonal (a scaled rotation). Use the normalization of the 3rd row of it as the direction vector.

For a general model space matrix, you need to do this:

objZ = (inverse(MV)*vec4(0,0,1,0)).xyz;

Then normalize.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .