Geosearchef

05-17-2015, 09:21 AM

I've implemented a particle system. I'm drawing their textures on billboards that should be rotated towards the camera.

This works fine except for the case when the angle between particle->camera and the normal comes near to 180 degrees. Then the particle starts rotating around itself many times.

The angle is calculated using cos(angle) = dot(a, b) / (length(a) * length(b), the length are both 1 cause the Vectors are normalized. The axis is calculated using the cross product of those two vectors.

glDisable(GL_CULL_FACE);

//calculate rotation

Vector3f normal =newVector3f(0,0,1);

Vector3f dir =Vector3f.sub(newVector3f(GraphicsData.camera.x,Gr aphicsData.camera.y,GraphicsData.camera.z),newVect or3f(x, y, z),null);

if(dir.length()==0)

{

glEnable(GL_CULL_FACE);

return;

}

dir =(Vector3f) dir.normalise();

float angle =(float)Math.toDegrees(Math.acos(Vector3f.dot(norm al, dir)));

Vector3f rotationAxis =Vector3f.cross(normal, dir,null);

rotationAxis =(Vector3f) rotationAxis.normalise();

System.out.println("Angle: + "+ angle +" Axis: "+ rotationAxis);

glBindTexture(GL_TEXTURE_2D,ParticleEngine.particl eTextures.get(typeId).texture.getTextureID());

glColor4f(1f,1f,1f, time >= lifeTime - decayTime ?((float)lifeTime -(float)time)/((float)lifeTime -(float)decayTime):1f);

shaderEngine.createModelMatrix(newVector3f(x, y, z),newVector3f(angle * rotationAxis.x, angle * rotationAxis.y, angle * rotationAxis.z),newVector3f(sx, sy, sz));

shaderEngine.loadModelMatrix(shaderEngine.particle );

glCallList(ParticleEngine.particleTextures.get(typ eId).displayListId + textureIndex);

glEnable(GL_CULL_FACE);

What am i doing wrong calculating the rotation?

publicstaticvoid createModelMatrix(Vector3f pos,Vector3f rot,Vector3f scale)

{

GraphicsData.camera.modelMatrix =newMatrix4f();

GraphicsData.camera.modelMatrix.setIdentity();

GraphicsData.camera.modelMatrix.translate(pos);

GraphicsData.camera.modelMatrix.rotate((float)Math .toRadians(rot.x),newVector3f(1,0,0));

GraphicsData.camera.modelMatrix.rotate((float)Math .toRadians(rot.y),newVector3f(0,1,0));

GraphicsData.camera.modelMatrix.rotate((float)Math .toRadians(rot.z),newVector3f(0,0,1));

GraphicsData.camera.modelMatrix.scale(scale);

}

This works fine except for the case when the angle between particle->camera and the normal comes near to 180 degrees. Then the particle starts rotating around itself many times.

The angle is calculated using cos(angle) = dot(a, b) / (length(a) * length(b), the length are both 1 cause the Vectors are normalized. The axis is calculated using the cross product of those two vectors.

glDisable(GL_CULL_FACE);

//calculate rotation

Vector3f normal =newVector3f(0,0,1);

Vector3f dir =Vector3f.sub(newVector3f(GraphicsData.camera.x,Gr aphicsData.camera.y,GraphicsData.camera.z),newVect or3f(x, y, z),null);

if(dir.length()==0)

{

glEnable(GL_CULL_FACE);

return;

}

dir =(Vector3f) dir.normalise();

float angle =(float)Math.toDegrees(Math.acos(Vector3f.dot(norm al, dir)));

Vector3f rotationAxis =Vector3f.cross(normal, dir,null);

rotationAxis =(Vector3f) rotationAxis.normalise();

System.out.println("Angle: + "+ angle +" Axis: "+ rotationAxis);

glBindTexture(GL_TEXTURE_2D,ParticleEngine.particl eTextures.get(typeId).texture.getTextureID());

glColor4f(1f,1f,1f, time >= lifeTime - decayTime ?((float)lifeTime -(float)time)/((float)lifeTime -(float)decayTime):1f);

shaderEngine.createModelMatrix(newVector3f(x, y, z),newVector3f(angle * rotationAxis.x, angle * rotationAxis.y, angle * rotationAxis.z),newVector3f(sx, sy, sz));

shaderEngine.loadModelMatrix(shaderEngine.particle );

glCallList(ParticleEngine.particleTextures.get(typ eId).displayListId + textureIndex);

glEnable(GL_CULL_FACE);

What am i doing wrong calculating the rotation?

publicstaticvoid createModelMatrix(Vector3f pos,Vector3f rot,Vector3f scale)

{

GraphicsData.camera.modelMatrix =newMatrix4f();

GraphicsData.camera.modelMatrix.setIdentity();

GraphicsData.camera.modelMatrix.translate(pos);

GraphicsData.camera.modelMatrix.rotate((float)Math .toRadians(rot.x),newVector3f(1,0,0));

GraphicsData.camera.modelMatrix.rotate((float)Math .toRadians(rot.y),newVector3f(0,1,0));

GraphicsData.camera.modelMatrix.rotate((float)Math .toRadians(rot.z),newVector3f(0,0,1));

GraphicsData.camera.modelMatrix.scale(scale);

}