Baggio

06-03-2005, 12:02 PM

It seems I'm doing something wrong when I calculate the tangents and binormals of my mesh. I really need some help with this since I'm trying to do bumpmapping and specular reflections and they look all wrong. Here I have the function I use to calculate the tangents and binormals. BTW, I did read http://www.terathon.com/code/tangent.html but it doesn't calculate binormals, and also the code is a bit wierd to me because the structures of the geometry are different so I don't really know what I'm supposed to do. Here is my code:

void MathFuncs::calculateTangent(Mesh *CurrentMesh)

{

for (int i = 0; i < (intCurrentMesh->meshLayers.size(); ++i)

{

for(int j = 0; j < CurrentMesh->meshLayers[i]->numLayerGroups; ++j)

{

for(int k = 0; k < (CurrentMesh->meshLayers[i]->layerMaterialIndices[j]->numIndices / 3); ++k)

{

Mesh::MeshVert *v0 = &CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3)];

Mesh::MeshVert *v1 = &CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3 + 1)];

Mesh::MeshVert *v2 = &CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3 + 2)];

vec3 normal, tangent, binormal;

vec3 e0 = vec3(0.0f, v1->UV.x - v0->UV.x, v1->UV.y - v0->UV.y);

vec3 e1 = vec3(0.0f, v2->UV.x - v0->UV.x, v2->UV.y - v0->UV.y);

for(int l = 0; l < 3; l++)

{

e0.x = v1->position[l] - v0->position[l];

e1.x = v2->position[l] - v0->position[l];

vec3 v;

v.cross(e0, e1);

tangent[l] = -v[1] / v[0];

binormal[l] = -v[2] / v[0];

}

tangent.normalize();

binormal.normalize();

normal.cross(tangent, binormal);

normal.normalize();

v0->binormal.cross(v0->normal, tangent);

v0->binormal.normalize();

v0->tangent.cross(v0->binormal, v0->normal);

if(normal * v0->normal < 0.0f)

v0->binormal = -v0->binormal;

v1->binormal.cross(v1->normal, tangent);

v1->binormal.normalize();

v1->tangent.cross(v1->binormal, v1->normal);

if(normal * v1->normal < 0.0f)

v1->binormal = -v1->binormal;

v2->binormal.cross(v2->normal, tangent);

v2->binormal.normalize();

v2->tangent.cross(v2->binormal, v2->normal);

if(normal * v2->normal < 0.0f)

v2->binormal = -v2->binormal;

}

}

}

}Just so it isn't so hard to understand the code, a Mesh is composed of several meshLayers, inside each meshLayers there are LayerGroups, each group has a number of lists, there is one list per material in the layer. The indices stored are actually indices to the vertex array in the meshLayer. So for example I have two triangles with different materials in a single layer, there would be just two layerMaterialIndices with 3 indices each, and 6 vertices in layerVertices in the layer.

Now, I have an example of why I think the tangent and binormals are wrong, I make a 100x100x100 box where all the faces face to the inside of the box, I put that box in such way that the coords 0.0f, 0.0f, 0.0f are the exact center of the box. Now I put a light at 0.0f, 0.0f, 0.0f and the camera at 0.0f, 0.0f, 0.0f. Now if everything is correct, all the faces should look the same but here is an screenshot:

http://img107.echo.cx/img107/8149/wrongbump2rq.th.jpg (http://img107.echo.cx/my.php?image=wrongbump2rq.jpg)

I hope you people can help me cause I really need to solve this. Thanks.

void MathFuncs::calculateTangent(Mesh *CurrentMesh)

{

for (int i = 0; i < (intCurrentMesh->meshLayers.size(); ++i)

{

for(int j = 0; j < CurrentMesh->meshLayers[i]->numLayerGroups; ++j)

{

for(int k = 0; k < (CurrentMesh->meshLayers[i]->layerMaterialIndices[j]->numIndices / 3); ++k)

{

Mesh::MeshVert *v0 = &CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3)];

Mesh::MeshVert *v1 = &CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3 + 1)];

Mesh::MeshVert *v2 = &CurrentMesh->meshLayers[i]->layerVertices[j + (k * 3 + 2)];

vec3 normal, tangent, binormal;

vec3 e0 = vec3(0.0f, v1->UV.x - v0->UV.x, v1->UV.y - v0->UV.y);

vec3 e1 = vec3(0.0f, v2->UV.x - v0->UV.x, v2->UV.y - v0->UV.y);

for(int l = 0; l < 3; l++)

{

e0.x = v1->position[l] - v0->position[l];

e1.x = v2->position[l] - v0->position[l];

vec3 v;

v.cross(e0, e1);

tangent[l] = -v[1] / v[0];

binormal[l] = -v[2] / v[0];

}

tangent.normalize();

binormal.normalize();

normal.cross(tangent, binormal);

normal.normalize();

v0->binormal.cross(v0->normal, tangent);

v0->binormal.normalize();

v0->tangent.cross(v0->binormal, v0->normal);

if(normal * v0->normal < 0.0f)

v0->binormal = -v0->binormal;

v1->binormal.cross(v1->normal, tangent);

v1->binormal.normalize();

v1->tangent.cross(v1->binormal, v1->normal);

if(normal * v1->normal < 0.0f)

v1->binormal = -v1->binormal;

v2->binormal.cross(v2->normal, tangent);

v2->binormal.normalize();

v2->tangent.cross(v2->binormal, v2->normal);

if(normal * v2->normal < 0.0f)

v2->binormal = -v2->binormal;

}

}

}

}Just so it isn't so hard to understand the code, a Mesh is composed of several meshLayers, inside each meshLayers there are LayerGroups, each group has a number of lists, there is one list per material in the layer. The indices stored are actually indices to the vertex array in the meshLayer. So for example I have two triangles with different materials in a single layer, there would be just two layerMaterialIndices with 3 indices each, and 6 vertices in layerVertices in the layer.

Now, I have an example of why I think the tangent and binormals are wrong, I make a 100x100x100 box where all the faces face to the inside of the box, I put that box in such way that the coords 0.0f, 0.0f, 0.0f are the exact center of the box. Now I put a light at 0.0f, 0.0f, 0.0f and the camera at 0.0f, 0.0f, 0.0f. Now if everything is correct, all the faces should look the same but here is an screenshot:

http://img107.echo.cx/img107/8149/wrongbump2rq.th.jpg (http://img107.echo.cx/my.php?image=wrongbump2rq.jpg)

I hope you people can help me cause I really need to solve this. Thanks.