Hiya, i took the code from the http://www.lighthouse3d.com/opengl/tutorials.shtml tutorial on billboarding and implemented it in my engine... only problem is that the particle stands still until i pass by it, then it swivels quickly to face the other direction... i can't figure why its acting this way...
static void billboardSphericalBegin(
float camX, float camY, float camZ,
float objPosX, float objPosY, float objPosZ) {
float[] lookAt = new float[3];
float[] objToCamProj = new float[3];
float[] upAux = new float[3];
float[] modelview = new float[16];
float angleCosine;
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
// objToCamProj is the vector in world coordinates from the
// local origin to the camera projected in the XZ plane
objToCamProj[0] = camX - objPosX ;
objToCamProj[1] = 0;
objToCamProj[2] = camZ - objPosZ ;
// This is the original lookAt vector for the object
// in world coordinates
lookAt[0] = 0;
lookAt[1] = 0;
lookAt[2] = 1;
// normalize both vectors to get the cosine directly afterwards
Math3d.normalize(objToCamProj);
// easy fix to determine wether the angle is negative or positive
// for positive angles upAux will be a vector pointing in the
// positive y direction, otherwise upAux will point downwards
// effectively reversing the rotation.
Math3d.CrossProduct(upAux,lookAt,objToCamProj);
// compute the angle
angleCosine = Math3d.InnerProduct(lookAt,objToCamProj);
// perform the rotation. The if statement is used for stability reasons
// if the lookAt and objToCamProj vectors are too close together then
// |angleCosine| could be bigger than 1 due to lack of precision
if ((angleCosine < 0.99990) && (angleCosine > -0.9999))
GL11.glRotatef((float)(Math.acos(angleCosine)*180/3.14),upAux[0], upAux[1], upAux[2]);
// so far it is just like the cylindrical billboard. The code for the
// second rotation comes now
// The second part tilts the object so that it faces the camera
// objToCam is the vector in world coordinates from
// the local origin to the camera
float[] objToCam = new float[3];
objToCam[0] = camX - objPosX;
objToCam[1] = camY - objPosY;
objToCam[2] = camZ - objPosZ;
// Normalize to get the cosine afterwards
Math3d.normalize(objToCam);
// Compute the angle between objToCamProj and objToCam,
//i.e. compute the required angle for the lookup vector
angleCosine = Math3d.InnerProduct(objToCamProj,objToCam);
// Tilt the object. The test is done to prevent instability
// when objToCam and objToCamProj have a very small
// angle between them
if ((angleCosine < 0.99990) && (angleCosine > -0.9999))
if (objToCam[1] < 0)
GL11.glRotatef((float)(Math.acos(angleCosine)*180/3.14),1f,0f,0f);
else
GL11.glRotatef((float)(Math.acos(angleCosine)*180/3.14),-1f,0f,0f);
}
oh, and the define macros that were in this tutorial had to be converted (im using lwjgl in java) and here is that class:
public class Math3d {
static void normalize(float[] vector){
float dist=(float)Math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]+vector[2]*vector[2]);
float[] vec= new float[]{vector[0] / dist, vector[1] / dist, vector[2] / dist};
}
static void CrossProduct(float[] a,float[] b,float[] c){
(a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2];
(a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0];
(a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1];
}
static float InnerProduct(float[] v,float[] q){
return ((v)[0] * (q)[0] +
(v)[1] * (q)[1] +
(v)[2] * (q)[2]);
}
}
any help would be greatly appreciated
cheers
Bow before me... for i am l33t!