Original Post
Hello, I having problems trying to implement Eric Lengyel's tangent generation code. I'm using my own model format, and I can successfully bump-map a quad because the tangents behave when its just a quad facing the positive-z direction. In the lower-left of the image is an isolated quad facing the positive z direction, and to the right of that is a tri-strip that curves. You can see the funky rotated tangents on that curve. By the way, my coord system is [x:right, y:up, z:facing camera]. I'd appreciate any suggestions and can provide more screenshots/code if it helps. If you'd like to see the problem in any kind of test model let me know!! I'm a 3d artist, so creating test models is no issue. Below is my tangent generation code. I'd be happy to answer any questions.
Thank you [Edited by - sneakyrobot on February 6, 2008 4:37:11 PM]
num_vertex = vertex_vector.size() / const_vertex_floats; // get the actual number of vertices
vec3df *tan1 = new vec3df[num_index];
vec3df *tan2 = new vec3df[num_index];
uint cur_tan = 0;
for(uint j=0; j<num_vertex-3; j+=3) //// ***** j<num_vertex caused a vector bounds error
{
const vec3df v1( vertex_vector[j*const_vertex_floats], vertex_vector[j*const_vertex_floats+1], vertex_vector[j*const_vertex_floats+2]);
const vec3df v2( vertex_vector[(j+1)*const_vertex_floats], vertex_vector[(j+1)*const_vertex_floats+1], vertex_vector[(j+1)*const_vertex_floats+2]);
const vec3df v3( vertex_vector[(j+2)*const_vertex_floats], vertex_vector[(j+2)*const_vertex_floats+1], vertex_vector[(j+2)*const_vertex_floats+2]);
const vec2df w1( vertex_vector[j*const_vertex_floats+6], vertex_vector[j*const_vertex_floats+7]);
const vec2df w2( vertex_vector[(j+1)*const_vertex_floats+6], vertex_vector[(j+1)*const_vertex_floats+7]);
const vec2df w3( vertex_vector[(j+2)*const_vertex_floats+6], vertex_vector[(j+2)*const_vertex_floats+7]);
float x1 = v2.x - v1.x;
float x2 = v3.x - v1.x;
float y1 = v2.y - v1.y;
float y2 = v3.y - v1.y;
float z1 = v2.z - v1.z;
float z2 = v3.z - v1.z;
float s1 = w2.x - w1.x;
float s2 = w3.x - w1.x;
float t1 = w2.y - w1.y;
float t2 = w3.y - w1.y;
float r = 1.0f / (s1 * t2 - s2 * t1);
vec3df sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
vec3df tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
tan1[cur_tan] += sdir.normalize();
tan1[cur_tan+1] += sdir.normalize();
tan1[cur_tan+2] += sdir.normalize();
tan2[cur_tan] += tdir.normalize();
tan2[cur_tan+1] += tdir.normalize();
tan2[cur_tan+2] += tdir.normalize();
cur_tan += 3;
}
vec3df n;
vec3df t;
vec3df temp;
float sign;
for (uint c = 0; c < num_vertex; c++)
{
t = tan1[c];
n = vec3df( vertex_vector[c*const_vertex_floats+3],
vertex_vector[c*const_vertex_floats+4],
vertex_vector[c*const_vertex_floats+5] );
// Gram-Schmidt orthogonalize
temp = (t - n * n.dot(t)).normalize();
// Calculate handedness of the bitangent
sign = ( (n.cross(t)).dot(tan2[c]) < 0.0f ) ? -1.0f : 1.0f;
vertex_vector[c*const_vertex_floats+8] = temp.x;
vertex_vector[c*const_vertex_floats+9] = temp.y;
vertex_vector[c*const_vertex_floats+10] = temp.z;
vertex_vector[c*const_vertex_floats+11] = sign;
/*
log_write("tangent[%d]: [%f, %f, %f]", c,
vertex_vector[c*const_vertex_floats+8],
vertex_vector[c*const_vertex_floats+9],
vertex_vector[c*const_vertex_floats+10]);*/
}