# Another billboarding problem

I have following problem with billboarding:
I have a bunch of objects placed on their local origins.
For facing objects to camera view i’m using following function

``````void doBillboarding(float *cam, float *worldPos) {

float lookAt[3]={0,0,1},objToCamProj[3],upAux[3],angleCosine;

// objToCamProj is the vector in world coordinates from the local origin to the camera
// projected in the XZ plane
objToCamProj[0] = cam[0] - worldPos[0] ;
objToCamProj[1] = 0;
objToCamProj[2] = cam[2] - worldPos[2] ;

// normalize both vectors to get the cosine directly afterwards
mathsNormalize(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.

mathsCrossProduct(upAux,lookAt,objToCamProj);

// compute the angle
angleCosine = mathsInnerProduct(lookAt,objToCamProj);

// perform the rotation. The if statement is used for stability reasons
// if the lookAt and v vectors are too close together then |aux| could
// be bigger than 1 due to lack of precision
if ((angleCosine < 0.99990) && (angleCosine > -0.9999))
glRotatef(acos(angleCosine)*180/3.14,upAux[0], upAux[1], upAux[2]);
}
``````

This is straight from Lighthouse3D billboarding tutorial.
When i’m drawing my billboards:

doBillboarding(Camera.Position, Object.origin);
object.draw()
glPopMatrix();

The problem is that damn billboards flying around the scene not just rotating the Y axis of their local origins.
I have tried all (modelview matrix modification etc.). What’s wrong ??? (stupid thing i suppose )
Thanks for ANY help.
Best Regards.

If I understand you correctly, you want to create a single matrix to transform all your sprites.
If that’s the case, then good luck my friend. You could create a single rotation matrix, but translation is another matter, since I assume that each sprite in your scene has a unique position, hence the orbiting sprite frenzy you mentioned. You simply can’t use a single matrix to both rotate and translate all the sprites.

I strongly recommend getting rid of the glRotatef(…) and acos() calls. There are much better (faster) ways to generate a sprite basis. Here’s an alternative method:

``````void makeSprite( Vector eyeLeft, Vector eyeUp, Vector spritePos, float spriteRadius, Vector result[4] )
{
Vector left = eyeLeft * spriteRadius;
Vector up   = eyeUp   * spriteRadius;

result[0] = spritePos + left + up;
result[1] = spritePos - left + u;
result[2] = spritePos - left - up;
result[3] = spritePos + left - up;
}
``````

edit:
corrected some mistakes.

I’ve adopted your method and it works fine. Thanks for help and sorry for my english
Best Regards.

Hmm…I’ve just noticed that billboard rotating around ALL axes. How to do an axis(Y) aligned rotation ?
Thx for help.

Holrin, just set eyeUp = Vector(0,1,0), then cross this vector with your forward vector.

newEyeLeft = cross( eyeUp, eyeForward );

then proceed normally using newEyeLeft instead of eyeLeft.

But take care that eyeForward doesn’t coincide with the y axis, or you will have a nasty case where the cross will give you a zero vector. To solve that problem, you can pick another suitable vector to replace it.

In fact, you can generalize this whole thing into what’s known as a rope sprite:

``````void makeRopeSprite( Vector eyePos, Vector ropeStart, Vector ropeEnd, float radius, Vector result[4] ) {

Vector up = cross(eyePos-ropeStart, ropeEnd-ropeStart );
up = normalize( up );