Is there a good tutorial anyway on tangant mapping?(C++ tutorial is fine, don't expect there to be any blitz ones ;) )
Here's my attempt at it, ripped from the guts of FMC. But, despite being as far as I can tell, corret, it doesn't work at all.
Here's the vector lib it uses.(Free feel to use this lib btw.)
Here's my attempt at it, ripped from the guts of FMC. But, despite being as far as I can tell, corret, it doesn't work at all.
Local tmx#[16] tmx[0]=1 tmx[1]=0 tmx[2]=0 tmx[3]=0 tmx[4]=0 tmx[5]=-1 tmx[6]=0 tmx[7]=0 tmx[8]=0 tmx[9]=0 tmx[10]=1 tmx[11]=0 tmx[12]=0 tmx[13]=0 tmx[14]=0 tmx[15]=1 Local lpES#[3]; // light position in Eye space Local lpOS#[3]; // light position in Object space Local lv#[3]; // vector from vertex to light Local lv_ts#[3]; // light vector in tangent space Local modelViewMatrix#[16]; Local modelViewMatrixInverse#[16] fillMatrix( sys\cam,modelViewMatrix) matrixInvert( modelViewMatrix,modelViewMatrixInverse) If KeyDown(205) lpes[0]=lx lpes[1]=ly lpes[2]=lz Else TFormPoint lx,ly,lz,sys\cam,0 lpEs[0]=TFormedX() lpes[1]=TFormedY() lpes[2]=TFormedZ() EndIf vecMatMult(lpES, modelViewMatrixInverse, lpOS); Local vert1#[3],vert2#[3],vert3#[3] Local tvec#[3],bnorm#[3],norm#[3] Local pnorm#[3],tex1#[2],tex2#[2],tex3#[2] For b.bump=Each bump sc=CountSurfaces( b\mesh) For s=1 To sc srf=GetSurface( b\mesh,s) tc=CountTriangles(srf) For t=1 To tc-1 v1=TriangleVertex(srf,t,1) v2=TriangleVertex(srf,t,2) v3=TriangleVertex(srf,t,3) vector( VertexX(srf,v1),VertexY(srf,v1),VertexZ(srf,v1),vert1) vector( VertexX(srf,v2),VertexY(srf,v2),VertexZ(srf,v2),vert2) vector( VertexX(srf,v3),VertexY(srf,v3),VertexZ(srf,v3),vert3) tex1[0]=VertexU(srf,v1) tex1[1]=VertexV(srf,v1) tex2[0]=VertexU(srf,v2) tex2[1]=VertexV(srf,v2) tex3[0]=VertexU(srf,v3) tex3[1]=VertexV(srf,v3) pnorm[0]=triangleNx( srf,t) pnorm[1]=triangleNy( srf,t) pnorm[2]=triangleNz( srf,t) tang(vert1,vert2,vert3,tex1,tex2,tex3,pnorm,tvec,bnorm,norm) tmx[0] =tvec[0] tmx[1] =tvec[1] tmx[2] =tvec[2] ;tmx[3] tmx[4] =bnorm[0] tmx[5] =bnorm[1] tmx[6] =bnorm[2] ;tmx[7]= tmx[8] =norm[0] tmx[9] =norm[1] tmx[10] =norm[2] ; For vtt=0 To 2 v=TriangleVertex(srf,t,vtt) vx#=VertexX(srf,v) vy#=VertexY(srf,v) vz#=VertexZ(srf,v) ; lv[0] = (lx - vx); lv[1] = (ly - vy); lv[2] = (lz - vz); vecNormalize(lv); vecMat3x3Mult(lv, tmx, lv_ts); ;lv_ts[0] = lv_ts[0] * 0.5 + 0.5; ;lv_ts[1] = lv_ts[1] * 0.5 + 0.5; ;lv_ts[2] = lv_ts[2] * 0.5 + 0.5; rd#=255 VertexColor srf,v,rd+rd*lv_ts[0],rd+rd*lv_ts[1],rd+rd*lv_ts[2] Next Next Next Next
Here's the vector lib it uses.(Free feel to use this lib btw.)
Function matrixIdentity(matrix#[16]) matrix[ 0] = 1.0; matrix[ 1] = 0.0; matrix[ 2] = 0.0; matrix[ 3] = 0.0; matrix[ 4] = 0.0; matrix[ 5] = 1.0; matrix[ 6] = 0.0; matrix[ 7] = 0.0; matrix[ 8] = 0.0; matrix[ 9] = 0.0; matrix[10] = 1.0; matrix[11] = 0.0; matrix[12] = 0.0; matrix[13] = 0.0; matrix[14] = 0.0; matrix[15] = 1.0; End Function ;////////////////////////// ;// Invert a matrix. (Matrix MUST be orhtonormal!) ;// in - Input matrix ;// out - Output matrix ;////////////////////////// Function matrixInvert(in#[16], out#[16]) ; // Transpose rotation out[ 0] = in[ 0]; out[ 1] = in[ 4]; out[ 2] = in[ 8]; out[ 4] = in[ 1]; out[ 5] = in[ 5]; out[ 6] = in[ 9]; out[ 8] = in[ 2]; out[ 9] = in[ 6]; out[10] = in[10]; ; // Clear shearing terms out[3] = 0.0;f; out[7] = 0.0f; out[11] = 0.0f; out[15] = 1.0f; ; // Translation is minus the dot of tranlation And rotations out[12] = -(in[12]*in[ 0]) - (in[13]*in[ 1]) - (in[14]*in[ 2]); out[13] = -(in[12]*in[ 4]) - (in[13]*in[ 5]) - (in[14]*in[ 6]); out[14] = -(in[12]*in[ 8]) - (in[13]*in[ 9]) - (in[14]*in[10]); End Function ;////////////////////////// ;// Multiply a vector by a matrix. ;// vecIn - Input vector ;// m - Input matrix ;/////////////////////////// Function vecMatMult(vecIn#[3],m#[16], vecOut#[3]) vecOut[0] = (vecIn[0]*m[ 0]) + (vecIn[1]*m[ 4]) + (vecIn[2]*m[ 8]) + m[12]; vecOut[1] = (vecIn[0]*m[ 1]) + (vecIn[1]*m[ 5]) + (vecIn[2]*m[ 9]) + m[13]; vecOut[2] = (vecIn[0]*m[ 2]) + (vecIn[1]*m[ 6]) + (vecIn[2]*m[10]) + m[14]; End Function ;////////////////////////// ;// Multiply a vector by just the 3x3 portion of a matrix. ;// vecIn - Input vector ;// m - Input matrix ;// vecOut - Output vector ;////////////////////////// ;void Function vecMat3x3Mult(vecIn#[3], m#[16], vecOut#[3]) vecOut[0] = (vecIn[0]*m[ 0]) + (vecIn[1]*m[ 4]) + (vecIn[2]*m[ 8]); vecOut[1] = (vecIn[0]*m[ 1]) + (vecIn[1]*m[ 5]) + (vecIn[2]*m[ 9]); vecOut[2] = (vecIn[0]*m[ 2]) + (vecIn[1]*m[ 6]) + (vecIn[2]*m[10]); End Function Function vecCrossProd (vecA#[3], vecB#[3], vecOut#[3]) vecOut[0] = vecA[1]*vecB[2] - vecA[2]*vecB[1]; vecOut[1] = vecA[2]*vecB[0] - vecA[0]*vecB[2]; vecOut[2] = vecA[0]*vecB[1] - vecA[1]*vecB[0]; End Function Function vecNormalize#(vec#[3]) mag# = Sqr(vec[0]*vec[0] +vec[1]*vec[1] +vec[2]*vec[2]); ;// don't divide by zero If (mag=0) vec[0] = 0.0;f; vec[1] = 0.0;f; vec[2] = 0.0;f; Return(0.0); EndIf vec[0] =vec[0]/mag; vec[1] =vec[1]/mag; vec[2] =vec[2]/mag; Return(mag); End Function Function vecDotProd#(vecA#[3], vecB#[3]) Return(vecA[0]*vecB[0] +vecA[1]*vecB[1] +vecA[2]*vecB[2]); End Function Function vecCopy (vecIn#[3], vecOut#[3]) vecOut[0] = vecIn[0]; vecOut[1] = vecIn[1]; vecOut[2] = vecIn[2]; End Function Function vector( v1#,v2#,v3#,vect#[3]) vect[0]=v1 vect[1]=v2 vect[2]=v3 End Function Function tang( vertex#[3], vertex2#[3], vertex3#[3],texcoords#[2], texcoords2#[2], texcoords3#[2],polynormal#[3], tangent#[3], binormal#[3], normal#[3] ) Local txb#[3]; Local v1#[3],v2#[3] VECTOR( vertex2[0] - vertex[0], texcoords2[0] - texcoords[0], texcoords2[1] - texcoords[1],v1 ); VECTOR( vertex3[0] - vertex[0], texcoords3[0] - texcoords[0], texcoords3[1] - texcoords[1],v2 ); crossProduct( v1, v2,txb ); If( Abs( txb[0] ) > EPSILON ) tangent[0] = -txb[1] / txb[0]; binormal[0] = -txb[2] / txb[0]; EndIf v1[0] = vertex2[1] - vertex[1]; v2[0] = vertex3[1] - vertex[1]; CrossProduct( v1, v2,txb ); If( Abs( txb[0] ) > EPSILON ) tangent[1] = -txb[1] / txb[0]; binormal[1] = -txb[2] / txb[0]; EndIf v1[0] = vertex2[2] - vertex[2]; v2[0] = vertex3[2] - vertex[2]; CrossProduct( v1, v2,txb); If( Abs( txb[0] ) > EPSILON ) tangent[2] = -txb[1] / txb[0]; binormal[2] = -txb[2] / txb[0]; EndIf Normalize( tangent ); Normalize( binormal ); ;// Make a normal based on the tangent And binormal b/c it may be different than the poly's ;// normal, this normal being computed here is better CrossProduct( tangent, binormal,normal); Normalize( normal ); ;// Make tangent space vectors orthogonal by recomputing the binormal with the corrected ;// tangent space normal. CrossProduct( tangent, normal,biNormal); Normalize( binormal ); If( vecDotProd( normal, polynormal ) < 0.0 ) normal[0] = -normal[0]; normal[1] = -normal[1]; normal[2] = -normal[2]; EndIf End Function Function TriangleNormal#(v1#[3],v2#[3],v3#[3],o#[3]) ;SubVector v1,v2, ux#=VectorX() uy#=VectorY() uz#=VectorZ() ;SubVector Cx#,Cy#,Cz#,Bx#,By#,Bz# vx#=VectorX() vy#=VectorY() vz#=VectorZ() ;CrossProduct vx#,vy#,vz#,ux#,uy#,uz# ;Normalize vectorx,vectory,vectorz ;Return Ax#*vectorx+Ay#*vectory+Az#*vectorz End Function Function VectorX#() Return vectorx End Function Function VectorY#() Return vectory End Function Function VectorZ#() Return vectorz End Function Function VectorW#() Return vectorw End Function Function SubVector(v1#[3],v2#[3],o#[3]) o[0]=v1[0]-v2[0] o[1]=v1[1]-v2[1] o[2]=v1[2]=v2[2] End Function Function Normalize(v#[3]) If v[0]=0 And v[1]=0 And v[2]=0 Return m#=Magnitude(v) v[0]=v[0]/m# v[1]=v[1]/m# v[2]=v[2]/m# End Function Function CrossProduct(v1#[3],v2#[3],o#[3]) o[0]=v1[1]*v2[2]-v2[2]*v2[1] o[1]=v1[2]*v2[0]-v1[0]*v2[2] o[2]=v1[0]*v2[1]-v1[1]*v2[0] End Function Function Magnitude(v#[3]) Return Sqr( (v[0]*v[0]) + (v[1]*v[1]) + (v[2]*v[2]) ) End Function Function TriangleNX#(surf,tri_no) v0=TriangleVertex(surf,tri_no,0) v1=TriangleVertex(surf,tri_no,1) v2=TriangleVertex(surf,tri_no,2) ax#=VertexX#(surf,v1)-VertexX#(surf,v0) ay#=VertexY#(surf,v1)-VertexY#(surf,v0) az#=VertexZ#(surf,v1)-VertexZ#(surf,v0) bx#=VertexX#(surf,v2)-VertexX#(surf,v1) by#=VertexY#(surf,v2)-VertexY#(surf,v1) bz#=VertexZ#(surf,v2)-VertexZ#(surf,v1) nx#=(ay#*bz#)-(az#*by#) Return nx# End Function Function TriangleNY#(surf,tri_no) v0=TriangleVertex(surf,tri_no,0) v1=TriangleVertex(surf,tri_no,1) v2=TriangleVertex(surf,tri_no,2) ax#=VertexX#(surf,v1)-VertexX#(surf,v0) ay#=VertexY#(surf,v1)-VertexY#(surf,v0) az#=VertexZ#(surf,v1)-VertexZ#(surf,v0) bx#=VertexX#(surf,v2)-VertexX#(surf,v1) by#=VertexY#(surf,v2)-VertexY#(surf,v1) bz#=VertexZ#(surf,v2)-VertexZ#(surf,v1) ny#=(az#*bx#)-(ax#*bz#) Return ny# End Function Function TriangleNZ#(surf,tri_no) v0=TriangleVertex(surf,tri_no,0) v1=TriangleVertex(surf,tri_no,1) v2=TriangleVertex(surf,tri_no,2) ax#=VertexX#(surf,v1)-VertexX#(surf,v0) ay#=VertexY#(surf,v1)-VertexY#(surf,v0) az#=VertexZ#(surf,v1)-VertexZ#(surf,v0) bx#=VertexX#(surf,v2)-VertexX#(surf,v1) by#=VertexY#(surf,v2)-VertexY#(surf,v1) bz#=VertexZ#(surf,v2)-VertexZ#(surf,v1) nz#=(ax#*by#)-(ay#*bx#) Return nz# End Function