void FindInvTBN(Vertor3f Vertices[3], Vector2f TexCoords[3], Vector3f & InvNormal, Vector3f & InvBinormal, Vector3f & InvTangent) { /**//* Calculate the vectors from the current vertex to the two other vertices in the triangle */ Vector3f v2v1 = Vertices[0] - Vertices[2]; Vector3f v3v1 = Vertices[1] - Vertices[2]; //Calculate the “direction” of the triangle based on texture coordinates. // Calculate c2c1_T and c2c1_B float c2c1_T = TexCoords[0].x() - TexCoords[2].x(); float c2c1_B = TexCoords[0].y() - TexCoords[2].y(); // Calculate c3c1_T and c3c1_B float c3c1_T = TexCoords[1].x() - TexCoords[2].x(); float c3c1_B = TexCoords[1].y() - TexCoords[2].y(); //Look at the references for more explanation for this one. float fDenominator = c2c1_T * c3c1_B - c3c1_T * c2c1_B; /**//*ROUNDOFF here is a macro that sets a value to 0.0f if the value is a very small value, such as > -0.001f and < 0.001. */ /**//* EDIT by c programmer: you should NEVER perform an equality test against a floating point value, even if your macro has set fDenominator to 0.0f. The comparison can still fail. The code needs fixed. Instead you should check if fDenominator is within an epsilon value of 0.0f. */ if (ROUNDOFF(fDenominator) ==0.0f) { /**//* We won't risk a divide by zero, so set the tangent matrix to the identity matrix */ InvTangent = Vector3f(1.0f, 0.0f, 0.0f); InvBinormal = Vector3f(0.0f, 1.0f, 0.0f); InvNormal = Vector3f(0.0f, 0.0f, 1.0f); } else { // Calculate the reciprocal value once and for all (to achieve speed) float fScale1 =1.0f/ fDenominator; /**//* Time to calculate the tangent, binormal, and normal. Look at Søren’s article for more information. */ Vector3f T, B, N; T = Vector3f((c3c1_B * v2v1.x() - c2c1_B * v3v1.x()) * fscale1, (c3c1_B * v2v1.y() - c2c1_B * v3v1.y()) * fScale1, (c3c1_B * v2v1.z() - c2c1_B * v3v1.z()) * fScale1); B = Vector3f((-c3c1_T * v2v1.x() + c2c1_T * v3v1.x()) * fScale1, (-c3c1_T * v2v1.y() + c2c1_T * v3v1.y()) * fScale1, (-c3c1_T * v2v1.z() + c2c1_T * v3v1.z()) * fScale1); N = T%B; //Cross product! /**//*This is where programmers should break up the function to smooth the tangent, binormal and normal values. */ //Look at “Derivation of the Tangent Space Matrix” for more information. float fScale2 =1.0f/ ((T.x() * B.y() * N.z() - T.z() * B.y() * N.x()) + (B.x() * N.y() * T.z() - B.z() * N.y() * T.x()) + (N.x() * T.y() * B.z() - N.z() * T.y() * B.x())); InvTangent.set((B%N).x() * fScale2, ((-1.0f* N)%T).x() * fScale2, (T%B).x() * fScale2); InvTangent.normalize(); InvBinormal.set(((-1.0f*B)%N).y() * fScale2, (N%T).y() * fScale2, ((-1.0f* T)%B).y() * fScale2); InvBinormal.normalize(); InvNormal.set((B%N).z() * fScale2, ((-1.0f* N)%T).z() * fScale2, (T%B).z() * fScale2); InvNormal.normalize(); }