• Advertisement
Sign in to follow this  

Manual Billboarding.. - a question of orientation

This topic is 4170 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone, I'm currently working on a game whereby I have several holes in a 3D board and I want to display a numbered value above each hole in 3D space which corresponds to the number of items in each hole.. I have two questions on this topic.. firstly I want to display the numbers as textured quads since I will be using my own bitmap fonts for the job.. My question is how can I orientate each textured quads transform matrix so that they always face the view/camera? Lastly I need each hole to have two textured quads above it to represent each digit so cfor example a hole containing 24 items would have two quads rendered above it, one displaying the number "2" and the other displaying the number "4".. Now how would I be able to read the value of an int which would tell me how many items are in the hole and map each digit from the int to each number texture described above? hope the question makes sense..

Share this post


Link to post
Share on other sites
Advertisement
Reading an int:

firstdigit = value / 10 (integer math truncates the fraction, so: 24 / 10 = 2
seconddigit = value % 10 (24 % 10 = 4)


Billboarding: depends on what type of billboarding you are doing.
I have three types of billboarding, which I named

AXIS (billboarding around a major axis)
POINT (facing the camera position)
PLANE (facing the camera plane, constructed from camera->up and camera->right)

here's the billboarding code:

void Billboard::createMatrixAxis(Vec3& axis, Vec3& dir, Vec3& pos, Matrix4& result)
{
Vec3 r = axis.cross(dir);
r.normalize();
Vec3 d = axis.cross(r);

result.m11 = r.x;
result.m12 = r.y;
result.m13 = r.z;
result.m21 = axis.x;
result.m22 = axis.y;
result.m23 = axis.z;
result.m31 = d.x;
result.m32 = d.y;
result.m33 = d.z;
result.m41 = pos.x;
result.m42 = pos.y;
result.m43 = pos.z;
}

void Billboard::createMatrixPoint(Vec3& up, Vec3& dir, Vec3& pos, Matrix4& result)
{
dir.normalize();
Vec3 r = up.cross(dir);
Vec3 u = dir.cross(r);

result.m11 = r.x;
result.m12 = r.y;
result.m13 = r.z;
result.m21 = u.x;
result.m22 = u.y;
result.m23 = u.z;
result.m31 = dir.x;
result.m32 = dir.y;
result.m33 = dir.z;
result.m41 = pos.x;
result.m42 = pos.y;
result.m43 = pos.z;
}

void Billboard::createMatrixPlane( Vec3& camup, Vec3 camlook, Vec3& pos, Matrix4& result)
{
Vec3 l = -camlook;
Vec3 r = camup.cross(l);

result.m11 = r.x;
result.m12 = r.y;
result.m13 = r.z;
result.m21 = camup.x;
result.m22 = camup.y;
result.m23 = camup.z;
result.m31 = l.x;
result.m32 = l.y;
result.m33 = l.z;
result.m41 = pos.x;
result.m42 = pos.y;
result.m43 = pos.z;
}




And here's how to use it:

glPushMatrix();

switch(m_billboardtype)
{
case Billboard::AXIS:
{
Camera& cam = Engine::getActiveCamera();
Vec3 look = cam.getPosition() - m_position;

Matrix4 m;
Billboard::createMatrixAxis(m_direction, look, m_position, m);

glMultMatrixf(m.n);
break;
}
case Billboard::POINT:
{
Camera& cam = Engine::getActiveCamera();
Vec3 look = cam.getPosition() - m_position;

Matrix4 m;
Billboard::createMatrixPoint(cam.getUp(), look, m_position, m);

glMultMatrixf(m.n);
break;
}
case Billboard::PLANE:
{
Camera& cam = Engine::getActiveCamera();
Vec3 look = cam.getLookAt() - cam.getPosition();
Matrix4 m;
Billboard::createMatrixPlane(cam.getUp(), look, m_position, m);

glMultMatrixf(m.n);
break;
}
default: //Billboard::NONE
{
glMultMatrixf(m_mLocal);
}
}

m_texture->bind();
glCallList(m_displaylist);

glPopMatrix();
}




m_position is the position of the sprite, m_direction is its up vector (the direction of the axis to rotate around)

OK, the render code is OpenGL but it should be fairly easy to convert to D3D.

[Edited by - Lord_Evil on September 21, 2006 6:56:20 AM]

Share this post


Link to post
Share on other sites
If you want to orient a quad in such a way that it is always parallel to the image plane, all you have to do is set the upper left 3x3 matrix of your world*view matrix to identity. That is all. Your matrix should look something like:


1 0 0 A
0 1 0 B
0 0 1 C
D E F G

If you are using the directx FFP, you just use point primitives. They are rendered as billboards. If you are writing your own shaders, then you can still use point primitives but they won't scale properly with the view (i.e. you will have to spit out the point size for each vertex in number of pixels). Rendering quads is probably a better way to go though, you get more control.

Share this post


Link to post
Share on other sites
Thanks for all the help guys..

I managed to get the numbers working using textured quads with their orientation set using a function I found in the DirectX sample application for billboarding..

Its an axis transform but it works pretty well.. thanx again!!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement