PDA

View Full Version : tangents and binormals ...



andreasMank
06-23-2004, 12:03 AM
a ati used 3ds-lib generates automaticly tangents and binormals .. but they are all (1,0,0) for the hole mesh .. not sure this depends on the planar mapping .. but normally it cant be .. why are the tangents and binormals sets to this static values, if some texture coords are the same??? i though, this function sets the tangents space .. doesn't this mean, that the three axis stored are the tangent, normal and binormal in world space??? how can i do it right???

</font><blockquote><font size="1" face="Verdana, Arial">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">void TangentSpace(float* vert1, float* vert2, float* vert3,
float* t1, float* t2, float* t3,
float* normal, float *tangentSpace)
{

float a, b;
float u1, u2;
float v1, v2;
float edge1[3];
float edge2[3];
float dot;
float dvTmp[3];
float duTmp[3];

//printf("t1:%f,%f t2:%f,%f t3:%f,%f\n", t1[0], t1[1], t2[0], t2[1], t3[0], t3[1]);
//printf("normal:%f, %f, %f\n", normal[0], normal[1], normal[2]);

if ((t1[0] == t2[0])

andreasMank
06-23-2004, 12:34 AM
ok .. here again

float a, b;
float u1, u2;
float v1, v2;
float edge1[3];
float edge2[3];
float dot;
float dvTmp[3];
float duTmp[3];

//printf("t1:%f,%f t2:%f,%f t3:%f,%f\n", t1[0], t1[1], t2[0], t2[1], t3[0], t3[1]);
//printf("normal:%f, %f, %f\n", normal[0], normal[1], normal[2]);

if ((t1[0] == t2[0]) &#0124;&#0124;
(t1[1] == t2[1]) &#0124;&#0124;
(t1[0] == t3[0]) &#0124;&#0124;
(t1[1] == t3[1]))
{
tangentSpace[0] = 1.0f;
tangentSpace[1] = 0.0f;
tangentSpace[2] = 0.0f;

tangentSpace[3] = 0.0f;
tangentSpace[4] = 1.0f;
tangentSpace[5] = 0.0f;

tangentSpace[6] = 0.0f;
tangentSpace[7] = 0.0f;
tangentSpace[8] = 1.0f;
return;
}

//===================================//
// compute vertex space edge vectors //
//===================================//
edge1[0] = vert2[0] - vert1[0];
edge1[1] = vert2[1] - vert1[1];
edge1[2] = vert2[2] - vert1[2];
edge2[0] = vert3[0] - vert1[0];
edge2[1] = vert3[1] - vert1[1];
edge2[2] = vert3[2] - vert1[2];

//====================================//
// compute texture space edge vectors //
//====================================//
u1 = t2[0] - t1[0];
u2 = t3[0] - t1[0];
v1 = t2[1] - t1[1];
v2 = t3[1] - t1[1];

//================================================== =======//
// compute releation between how edges change as u changes //
//================================================== =======//
a = (u1 - v1 * u2 / v2);
if (a != 0.0f)
{
a = 1.0f / a;
}
b = (u2 - v2 * u1 / v1);
if (b != 0.0f)
{
b = 1.0f / b;
}
duTmp[0] = a * edge1[0] + b * edge2[0];
duTmp[1] = a * edge1[1] + b * edge2[1];
duTmp[2] = a * edge1[2] + b * edge2[2];
VEC_Normalizef(duTmp);

//================================================== =======//
// compute releation between how edges change as v changes //
//================================================== =======//
a = (v1 - u1 * v2 / u2);
if (a != 0.0f)
{
a = 1.0f / a;
}
b = (v2 - u2 * v1 / u1);
if (b != 0.0f)
{
b = 1.0f / b;
}
dvTmp[0] = a * edge1[0] + b * edge2[0];
dvTmp[1] = a * edge1[1] + b * edge2[1];
dvTmp[2] = a * edge1[2] + b * edge2[2];
VEC_Normalizef(dvTmp);

//=====================================//
// normal portion of the tangent space //
//=====================================//
tangentSpace[6] = normal[0];
tangentSpace[7] = normal[1];
tangentSpace[8] = normal[2];

dot = VEC_DotProduct(duTmp, &tangentSpace[6]);

//======================================//
// tangent portion of the tangent space //
//======================================//
tangentSpace[0] = duTmp[0] - (dot * tangentSpace[6]);
tangentSpace[1] = duTmp[1] - (dot * tangentSpace[7]);
tangentSpace[2] = duTmp[2] - (dot * tangentSpace[8]);
VEC_Normalizef(tangentSpace);

dot = VEC_DotProduct(dvTmp, &tangentSpace[6]);

//=======================================//
// binormal portion of the tangent space //
//=======================================//
tangentSpace[3] = dvTmp[0] - (dot * tangentSpace[6]);
tangentSpace[4] = dvTmp[1] - (dot * tangentSpace[7]);
tangentSpace[5] = dvTmp[2] - (dot * tangentSpace[8]);
VEC_Normalizef(&tangentSpace[3]);

Eric Lengyel
06-23-2004, 08:48 PM
The code you have posted does not use the correct mathematics. You can find a robust implementation here:

http://www.terathon.com/code/tangent.html

-- Eric Lengyel

T101
06-24-2004, 12:01 AM
Without looking at the rest of the code, it's the IF statement that's doing exactly what you describe.
I suppose it's meant to prevent all those heavy calculations if ALL coordinates are the same or something, but you're using &#0124;&#0124;...

Eric Lengyel
06-24-2004, 04:59 PM
The IF statement in the code posted here is designed to prevent division by zero. Obviously wrong, since it's perfectly acceptable for two adjacent vertices to have the same s or t coordinate.