Search code examples
c++openglrotationglutparticles

Rotate a particle system


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.

Although most irrelevant, here is an image (incase) http://i.imgur.com/YhV4w.png


Solution

  • You need to know the orientation of the camera to work out how to change the orientation of the flame particles. You need to basically inverse the camera's rotation matrix. If I was doing this, I would keep a copy of the transformations locally so that I could quickly access the cameras rotation. The alternative is to read the transformation matrix and to calculate the inverse rotation from the matrix.

    static void inverseRotMatrix(const GLfloat in[4][4], GLfloat out[4][4])
    {
        out[0][0] = in[0][0];
        out[0][1] = in[1][0];
        out[0][2] = in[2][0];
        out[0][3] = 0.0f;
        out[1][0] = in[0][1];
        out[1][1] = in[1][1];
        out[1][2] = in[2][1];
        out[1][3] = 0.0f;
        out[2][0] = in[0][2];
        out[2][1] = in[1][2];
        out[2][2] = in[2][2];
        out[2][3] = 0.0f;
        out[3][0] = 0.0f;
        out[3][1] = 0.0f;
        out[3][2] = 0.0f;
        out[3][3] = 1.0f;
    }
    
    void RenderFlame() 
    {
        GLfloat matrix[4][4];
        GLfloat invMatrix[4][4];
        glGetFloatv(GL_MODELVIEW_MATRIX, matrix[0]);
    
        inverseRotMatrix(matrix, invMatrix);
    
        glPushMatrix();
    
        // glMultMatrixf(invMatrix[0]); If you want to rotate the entire body of particles
    
        for ... each particle
            ...
            glTranslatef(particleX, particleY, particleZ);
            glMultMatrixf(invMatrix[0]);
    
            DrawParticle();
    
            ...
    
         glPopMatrix();
    }
    

    This may or may not work for you though depending on what you are doing. If the particles spread out in all directions it should be fine, but if the flame is essentially flat you will have other issues. All this does is rotate each particle so that it is facing the the screen. If you are just rotating the camera it will work fine. If you move the camera you have to rotate all of the points as well about the center point of the flame. But this does give you the rotation you need by inversing the rotation matrix, it's merely a question of how many times you apply the transformation. (I added a comment where you would apply another rotation to rotate the whole body of particles)