Billboard problem (Solved)

Started by
2 comments, last by deffer 18 years, 9 months ago
My game has a relatively minor but frustrating problem. It might be easier to illustrate with a screenshot. In the left screenshot, my sprite is standing just in front of the bridge. In the right screenshot, I've moved my camera upwards without moving the sprite, and now it is sitting a few steps on the bridge. Technically, that is correct: my billboarded sprite's center is at the same spot (ie, the X and Z coordinates of the center of the sprite are the same). But since the perspective changes, the sprite is rotated to face the camera (which is just fine.) However, this places its feet either too far ahead or too far behind where they should be. Drawing the sprite is pretty simple.
	glTranslatef(0.0f, -0.53f, 0.0f);
	glBegin(GL_QUADS);
		glTexCoord2f(fXPos + 0.25f, gID + 0.1875f); glVertex3f( 0.240f, 0.00f, 0);
		glTexCoord2f(fXPos + 0.25f, gID + 0.0025f); glVertex3f( 0.240f, 0.75f, 0);
		glTexCoord2f(fXPos		  , gID + 0.0025f); glVertex3f(-0.240f, 0.75f, 0);
		glTexCoord2f(fXPos		  , gID + 0.1875f); glVertex3f(-0.240f, 0.00f, 0);
	glEnd();




This is how I handle billboarding.
ES_Graphics::SetBillboard(bool Activation)
{
	int   i, j;
	float Matrix[16];

	/* If we're turning it on, alter the model view matrix.								*/ 
	if(Activation)
	{
		glPushMatrix();
		glTranslatef(xPos, yPos, zPos);
		glGetFloatv(GL_MODELVIEW_MATRIX, Matrix);
		for(i = 0; i < 3; i++)
			for(j = 0; j < 3; j++)
				Matrix[(i<<2) + j] = (i == j) ? 1.0f : 0.0f;
		glLoadMatrixf(Matrix);
	}

	/* Otherwise, restore the model view matrix.									*/ 
	else
	{
		glPopMatrix();
	}
}




Any idea what could be wrong, or how I could fix this? [Edited by - RuneLancer on July 10, 2005 3:00:50 PM]
Advertisement
That's very strange since you draw your sprites feet at 0.0. Got me.
Author Freeworld3Dhttp://www.freeworld3d.org
Quote:Original post by oconnellseanm
That's very strange since you draw your sprites feet at 0.0. Got me.


Oddly enough, that sentence caused me to find the solution. My feet weren't drawn at 0.0, I was just translating down to 0.0. Apparently that's not enough. Instead, I removed the translation and drew the map 0.53 units higher, and it works fine now.

What I'm still miffed about is why my map was 0.53 units too low. :/ This seems like a patchy solution to me...
This is not a bug. But it should be avoided somehow.

How about shrinking the height of the billboard when looking from above? The easiest way would be to lock the Y (vertical) axis of the sprite.
Only that that way the billboard will be completely flat when seen from above, which you probably do not want.

There's a technique I implemented lately, which I called flat particles.
Basically it goes like this.
A billboard has diferent size seen from different angles. For example, when we look at a quad at angle x (to it's normal), it has height = cos(x)*heightBase. When we look at standard sprite, it has always height = heightBase.
The second one behaves like a circle, first one like a line - a flat circle. Both are elipses of some kind. Any elipsis between those two special cases is a base for "flat particle". With it we can compute height for a billboard at a certain angle x.

If the elipsis has radii 1.0f and R, then:
height = sqrt( R*R + (1-R*R)*(cos(x))^2 ) * heightBase;
width = widthBase

So you set R as 0.4f, for example, and get:
cos(x)^2 == 1.0f - y*y
y - from camera normal.

Hope that helps.
/def

This topic is closed to new replies.

Advertisement