Tangant Mapping.

Blitz3D Forums/Blitz3D Programming/Tangant Mapping.

AntonyWells(Posted 2004) [#1]
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.



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



HNPhan(Posted 2004) [#2]
you might wanna take a look at this:
http://www.ati.com/developer/vertexblendD3D.html

it has full source code in c++


AntonyWells(Posted 2004) [#3]
Thanks.

Hey t, got a link to that next-gen engine you posted about on bc a while back? Finally got a decent gpu, dying to take a look now ;)


HNPhan(Posted 2004) [#4]
cool man, if it does work (tangeant space) id love to hear from it, drop me an e-mail if you want :)


AntonyWells(Posted 2004) [#5]
I'll send a demo your way if I get it going. Btw, you never asnwered..got a url to that engine? I may be remembering wrong, was it you who posted a link to this freeware next-gen engine?


Tangent(Posted 2004) [#6]
www.nevrax.org
That's one.

www.3dengines.net

Good listing


HNPhan(Posted 2004) [#7]
http://www.tenebrae2.com/
was the engine we used at school