BillyBOb

05-31-2002, 06:41 PM

I can't figure out the correct Tangent, Binormal, and Normal. The code seems to work fine for cubes and planes but once a sphere or something more complex is used it goes wrong. It shows up as only half the triangles have textures and the other half is black, usually.

this is the code I'm using to get the tangent bais:

int TS_Basis(float v0[3], float v1[3], float v2[3], float uv0[2], float uv1[2], float uv2[2],

float *tangentMatrix)

{

/*

Tx Bx Nx *

Ty By Ny *

Tz Bz Nz *

* * * *

T are the tangent vectors

B are the binormals

N are the normals

* = the homogenous thingy

*/

float e0[3] = {0.0f, 0.0f, 0.0f};

float e1[3] = {0.0f, 0.0f, 0.0f};

float te0[2] = {0.0f, 0.0f};

float te1[2] = {0.0f, 0.0f};

float row0[3] = {0.0f, 0.0f, 0.0f};

float row1[3] = {0.0f, 0.0f, 0.0f};

//vector from vertex 0 to vertex 1

e0[0] = v0[0] - v1[0];

e0[1] = v0[1] - v1[1];

e0[2] = v0[2] - v1[2];

//vector from vertex 1 to vertex 2

e1[0] = v1[0] - v2[0];

e1[1] = v1[1] - v2[1];

e1[2] = v1[2] - v2[2];

//vector from UV 0 to UV 1

te0[0] = uv0[0] - uv1[0];

te0[1] = uv0[1] - uv1[1];

//vector from UV 1 to UV 2

te1[0] = uv1[0] - uv2[0];

te1[1] = uv1[1] - uv2[1];

//Calculates the normal for the face

float Normal[3];

crossprod(e0, e1, Normal);

vecNormalize(Normal);

tangentMatrix[2] = Normal[0];

tangentMatrix[6] = Normal[1];

tangentMatrix[10] = Normal[2];

//Calculate the Tangent vector

row0[0] = te0[0];

row0[1] = te0[1];

row0[2] = 1.0f;

row1[0] = te1[0];

row1[1] = te1[1];

row1[2] = 0.0f;

if(row0[0] == 0.0f)

{

row0[0] += row1[0];

row0[1] += row1[1];

row0[2] += row1[2];

}

row0[2] /= row0[0];

row0[1] /= row0[0];

row0[0] /= row0[0];

row1[2] -= row0[2]*row1[0];

row1[1] -= row0[1]*row1[0];

row1[0] -= row0[0]*row1[0];

row1[2] /= row1[1];

row1[0] /= row1[1];

row1[1] /= row1[1];

row0[0] -= row1[0]*row0[1];

row0[2] -= row1[2]*row0[1];

row0[1] -= row1[1]*row0[1];

float Tangent[3];

Tangent[0] = row0[2]*e0[0] + row1[2]*e1[0];

Tangent[1] = row0[2]*e0[1] + row1[2]*e1[1];

Tangent[2] = row0[2]*e0[2] + row1[2]*e1[2];

vecNormalize(Tangent);

tangentMatrix[0] = Tangent[0];

tangentMatrix[4] = Tangent[1];

tangentMatrix[8] = Tangent[2];

//Calculate BiNormal from the Cross Product of the Normal and Tangent

float BiNormal[3];

crossprod(Normal, Tangent, BiNormal);

tangentMatrix[1] = BiNormal[0];

tangentMatrix[5] = BiNormal[1];

tangentMatrix[9] = BiNormal[2];

vecNormalize(BiNormal);

tangentMatrix[1] = BiNormal[0];

tangentMatrix[5] = BiNormal[1];

tangentMatrix[9] = BiNormal[2];

return 1;

}

not very efficent but I don't see what's wrong with it. Different sources seem to have slightly different ways of finding the tangent basis and almost all the examples on the web use planes or cubes.

this is the code I'm using to get the tangent bais:

int TS_Basis(float v0[3], float v1[3], float v2[3], float uv0[2], float uv1[2], float uv2[2],

float *tangentMatrix)

{

/*

Tx Bx Nx *

Ty By Ny *

Tz Bz Nz *

* * * *

T are the tangent vectors

B are the binormals

N are the normals

* = the homogenous thingy

*/

float e0[3] = {0.0f, 0.0f, 0.0f};

float e1[3] = {0.0f, 0.0f, 0.0f};

float te0[2] = {0.0f, 0.0f};

float te1[2] = {0.0f, 0.0f};

float row0[3] = {0.0f, 0.0f, 0.0f};

float row1[3] = {0.0f, 0.0f, 0.0f};

//vector from vertex 0 to vertex 1

e0[0] = v0[0] - v1[0];

e0[1] = v0[1] - v1[1];

e0[2] = v0[2] - v1[2];

//vector from vertex 1 to vertex 2

e1[0] = v1[0] - v2[0];

e1[1] = v1[1] - v2[1];

e1[2] = v1[2] - v2[2];

//vector from UV 0 to UV 1

te0[0] = uv0[0] - uv1[0];

te0[1] = uv0[1] - uv1[1];

//vector from UV 1 to UV 2

te1[0] = uv1[0] - uv2[0];

te1[1] = uv1[1] - uv2[1];

//Calculates the normal for the face

float Normal[3];

crossprod(e0, e1, Normal);

vecNormalize(Normal);

tangentMatrix[2] = Normal[0];

tangentMatrix[6] = Normal[1];

tangentMatrix[10] = Normal[2];

//Calculate the Tangent vector

row0[0] = te0[0];

row0[1] = te0[1];

row0[2] = 1.0f;

row1[0] = te1[0];

row1[1] = te1[1];

row1[2] = 0.0f;

if(row0[0] == 0.0f)

{

row0[0] += row1[0];

row0[1] += row1[1];

row0[2] += row1[2];

}

row0[2] /= row0[0];

row0[1] /= row0[0];

row0[0] /= row0[0];

row1[2] -= row0[2]*row1[0];

row1[1] -= row0[1]*row1[0];

row1[0] -= row0[0]*row1[0];

row1[2] /= row1[1];

row1[0] /= row1[1];

row1[1] /= row1[1];

row0[0] -= row1[0]*row0[1];

row0[2] -= row1[2]*row0[1];

row0[1] -= row1[1]*row0[1];

float Tangent[3];

Tangent[0] = row0[2]*e0[0] + row1[2]*e1[0];

Tangent[1] = row0[2]*e0[1] + row1[2]*e1[1];

Tangent[2] = row0[2]*e0[2] + row1[2]*e1[2];

vecNormalize(Tangent);

tangentMatrix[0] = Tangent[0];

tangentMatrix[4] = Tangent[1];

tangentMatrix[8] = Tangent[2];

//Calculate BiNormal from the Cross Product of the Normal and Tangent

float BiNormal[3];

crossprod(Normal, Tangent, BiNormal);

tangentMatrix[1] = BiNormal[0];

tangentMatrix[5] = BiNormal[1];

tangentMatrix[9] = BiNormal[2];

vecNormalize(BiNormal);

tangentMatrix[1] = BiNormal[0];

tangentMatrix[5] = BiNormal[1];

tangentMatrix[9] = BiNormal[2];

return 1;

}

not very efficent but I don't see what's wrong with it. Different sources seem to have slightly different ways of finding the tangent basis and almost all the examples on the web use planes or cubes.