Sign in to follow this  
Dragon_Strike

vertex tangents for mesh

Recommended Posts

well ive looked through the net and read every single tangent vector tutorial i could find... i understand how they work but i still dont get how i should calculate them... im not quite getting the calculations.. for normal calculation i had no problem with the tutorials but for tangents.. i jsut dont get it... what happens if i have an avaraged normal vector? which tex coord should i use?... etc..? this is my normal calculation code ive written.. how would i calculate the tangent for each vertex? help with the code, some pointing in the right direction.. a good easy to understand tutorial.. anything would help..
void CTERRAIN::CalculateNormals( )
{
	CVECTOR A, B, C, D, E;
	CVECTOR CA, CB, CD, CE;

	CVECTOR AverageNormal; 
	CVECTOR NormalACB,NormalBCE,NormalECD,NormalDCA;

	for (int z = 1; z < m_iSize; z++)
	{
		for (int x = 1; x < m_iSize; x++)
		{	
			A.Set( float(x  ),GetHeight(x, z+1), float(z+1) ); 
			B.Set( float(x-1),GetHeight(x-1, z) , float(z  ) ); 
			C.Set( float(x  ),GetHeight(x, z) , float(z  ) ); 
			D.Set( float(x+1),GetHeight(x+1, z) , float(z  ) ); 
			E.Set( float(x  ),GetHeight(x, z-1), float(z-1) ); 
			
			CA = A - C;
			CB = B - C;
			CD = D - C;
			CE = E - C;

			NormalACB = CA.Cross(CB);
			NormalBCE = CB.Cross(CE);
			NormalECD = CE.Cross(CD);
			NormalDCA = CD.Cross(CA);

			NormalACB.Normalize();
			NormalBCE.Normalize();
			NormalECD.Normalize();
			NormalDCA.Normalize();

			AverageNormal = (NormalACB + NormalBCE + NormalECD + NormalDCA)/4.0f;
	
			AverageNormal.Normalize();

			NormalMap[(x+z*m_iSize)*4+0] = (AverageNormal.x+1.0f)*0.5f;
			NormalMap[(x+z*m_iSize)*4+1] = (AverageNormal.y+1.0f)*0.5f;
			NormalMap[(x+z*m_iSize)*4+2] = 
		}
	}
}


[Edited by - Dragon_Strike on September 26, 2006 3:14:17 PM]

Share this post


Link to post
Share on other sites
I don't remember what tutorial I looked at for this, if anyone knows by looking at my code, please give a link to the site, but here's my code.

It was a bit confusing at first, but then I got it:


MeshBlock* block = (MeshBlock*)baseBlock->m_Data;

if (block->TexCoordCount() > 0)
{
Vector *tan1 = new Vector[block->m_VertexList.Count()];
Vector *tan2 = new Vector[block->m_VertexList.Count()];

for (long a = 0; a < block->m_FaceList.Count(); a++)
{
long i1 = block->m_FaceList.Get(a).v0;
long i2 = block->m_FaceList.Get(a).v1;
long i3 = block->m_FaceList.Get(a).v2;

Vertex v1 = block->m_VertexList.Get(i1);
Vertex v2 = block->m_VertexList.Get(i2);
Vertex v3 = block->m_VertexList.Get(i3);

TexCoord w1 = block->m_TexCoordList.Get(i1);
TexCoord w2 = block->m_TexCoordList.Get(i2);
TexCoord w3 = block->m_TexCoordList.Get(i3);

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.u - w1.u;
float s2 = w3.u - w1.u;
float t1 = w2.v - w1.v;
float t2 = w3.v - w1.v;

float r = 1.0F / (s1 * t2 - s2 * t1);
Vector sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
(t2 * z1 - t1 * z2) * r);
Vector tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
(s1 * z2 - s2 * z1) * r);

tan1[i1] += sdir;
tan1[i2] += sdir;
tan1[i3] += sdir;

tan2[i1] += tdir;
tan2[i2] += tdir;
tan2[i3] += tdir;


}

Vector tangent;

for (long a = 0; a < block->m_VertexList.Count(); a++)
{
Vector n(block->m_NormalList.Get(a).x,block->m_NormalList.Get(a).y,block->m_NormalList.Get(a).z);
Vector& t = tan1[a];

// Gram-Schmidt orthogonalize
float dotValue = (float)DotProduct(n,t);
Vector tmp1 = n * dotValue;
Vector tmp2 = (t - tmp1);
tmp2.Normalize();

// Calculate handedness
float val = (float)DotProduct(CrossProduct(n,t),tan2[a]);
if (val < 0.0f)
{
tangent.X( -tmp2.X() );
tangent.Y( -tmp2.Y() );
tangent.Z( -tmp2.Z() );
}
else
{
tangent.X( -tmp2.X() );
tangent.Y( tmp2.Y() );
tangent.Z( tmp2.Z() );
}


block->m_TangentList.Add( tangent );
block->m_BiNormalList.Add( CrossProduct(tangent,n) );
}

delete [] tan1;
delete [] tan2;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this