Archived

This topic is now archived and is closed to further replies.

colinisinhere

Face normals?

Recommended Posts

I''ve searched the forums for this already but got no results... What is the math for calculating the normal of a triangle that is being drawn counter-clockwise? I know it has to do with cross-product and normalizing or somthing... but, can someone give me an example?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The answer is in the question. If your triangle has vertices A, B, C (in anti-clockwise order) form the vectors A->B, and B->C. Take the cross-product of those two vectors. Normalize it. Ta-da!

Share this post


Link to post
Share on other sites
VEC3D p1,p2,p3;
VEC3D v1,v2;

v1.x = p1.x - p2.x;
v1.y = p1.y - p2.y;
v1.z = p1.z - p2.z;

v2.x = p2.x - p3.x;
v2.y = p2.y - p3.y;
v2.z = p2.z - p3.z;

//Find the cross product of v1 and v2
//Then normalize the result

[edited by - starboarder on October 9, 2003 7:28:25 PM]

Share this post


Link to post
Share on other sites
Ok, i did some extra reasearch and I wrote this code for Calculating the normals:


void calcNorms(cMesh mesh)
{
fVector v1, v2;
float length;
for(int i = 0; i < mesh.nFaces; i++)
{
v1.x = mesh.pVertices[mesh.pFaces[i].nIndices[0]].x - mesh.pVertices[mesh.pFaces[i].nIndices[1]].x;
v1.y = mesh.pVertices[mesh.pFaces[i].nIndices[0]].y - mesh.pVertices[mesh.pFaces[i].nIndices[1]].y;
v1.z = mesh.pVertices[mesh.pFaces[i].nIndices[0]].z - mesh.pVertices[mesh.pFaces[i].nIndices[1]].z;

v2.x = mesh.pVertices[mesh.pFaces[i].nIndices[1]].x - mesh.pVertices[mesh.pFaces[i].nIndices[2]].x;
v2.y = mesh.pVertices[mesh.pFaces[i].nIndices[1]].y - mesh.pVertices[mesh.pFaces[i].nIndices[2]].y;
v2.z = mesh.pVertices[mesh.pFaces[i].nIndices[1]].z - mesh.pVertices[mesh.pFaces[i].nIndices[2]].z;

mesh.pFaces[i].pNormal.x = v2.y*v1.z - v2.z*v1.y;
mesh.pFaces[i].pNormal.y = v2.z*v1.x - v2.x*v1.z;
mesh.pFaces[i].pNormal.z = v2.x*v1.y - v2.y*v1.x;

length = sqrtf(mesh.pFaces[i].pNormal.x * mesh.pFaces[i].pNormal.y + mesh.pFaces[i].pNormal.y * mesh.pFaces[i].pNormal.y + mesh.pFaces[i].pNormal.y * mesh.pFaces[i].pNormal.y);

mesh.pFaces[i].pNormal.x /= length;
mesh.pFaces[i].pNormal.y /= length;
mesh.pFaces[i].pNormal.z /= length;
}
}


but they are Not calculated correctly because I get weird results!

What did i do wrong?!?

[edited by - colinisinhere on October 9, 2003 11:21:40 PM]

Share this post


Link to post
Share on other sites
lol... ok, i fixed that but i still get simalar results!:


void calcNorms(cMesh mesh)
{
fVector v1, v2;
float length;

for(int i = 0; i < mesh.nFaces; i++)
{
v1.x = mesh.pVertices[mesh.pFaces[i].nIndices[0]].x - mesh.pVertices[mesh.pFaces[i].nIndices[1]].x;
v1.y = mesh.pVertices[mesh.pFaces[i].nIndices[0]].y - mesh.pVertices[mesh.pFaces[i].nIndices[1]].y;
v1.z = mesh.pVertices[mesh.pFaces[i].nIndices[0]].z - mesh.pVertices[mesh.pFaces[i].nIndices[1]].z;

v2.x = mesh.pVertices[mesh.pFaces[i].nIndices[1]].x - mesh.pVertices[mesh.pFaces[i].nIndices[2]].x;
v2.y = mesh.pVertices[mesh.pFaces[i].nIndices[1]].y - mesh.pVertices[mesh.pFaces[i].nIndices[2]].y;
v2.z = mesh.pVertices[mesh.pFaces[i].nIndices[1]].z - mesh.pVertices[mesh.pFaces[i].nIndices[2]].z;

mesh.pFaces[i].pNormal.x = v2.y*v1.z - v2.z*v1.y;
mesh.pFaces[i].pNormal.y = v2.z*v1.x - v2.x*v1.z;
mesh.pFaces[i].pNormal.z = v2.x*v1.y - v2.y*v1.x;

length = sqrtf(mesh.pFaces[i].pNormal.x * mesh.pFaces[i].pNormal.x + mesh.pFaces[i].pNormal.y * mesh.pFaces[i].pNormal.y + mesh.pFaces[i].pNormal.z * mesh.pFaces[i].pNormal.z);

mesh.pFaces[i].pNormal.x /= length;
mesh.pFaces[i].pNormal.y /= length;
mesh.pFaces[i].pNormal.z /= length;
}
}


(FYI None of that was cut/pasted )

Share this post


Link to post
Share on other sites
Firstly, put the float length, inside the for loop... put variables in the smallest scope you require them, as this lets the compiler optimise as well as possible. Also, set their value with the copy constructor.
Secondly...

length=sqrtf(mesh.pFaces.pNormal.x * mesh.pFaces[i].pNormal.y + mesh.pFaces[i].pNormal.y * mesh.pFaces[i].pNormal.y + mesh.pFaces[i].pNormal.y * mesh.pFaces[i].pNormal.y);

Should be:

float length(sqrtf(mesh.pFaces[i].pNormal.x * mesh.pFaces[i].pNormal.x + mesh.pFaces[i].pNormal.y * mesh.pFaces[i].pNormal.y + mesh.pFaces[i].pNormal.z * mesh.pFaces[i].pNormal.z));

as someone already told you! (and get rid of the float length)
That should be all.

Share this post


Link to post
Share on other sites
here you go:


CVector3 *vNormals = NULL;
CVector3 sum, v1, v2, v3;
t3DObject* pObject;

int i, j, k, l;
bool e;

for (i = 0; i < pModel->numOfObjects; i++)
{
pObject = &pModel->pObject[i];
pObject->pNormals = new CVector3 [pObject->numOfVerts];

vNormals = new CVector3 [pObject->numOfFaces];

for (j = 0; j < pObject->numOfFaces; j++)
{
v1 = pObject->pVerts[pObject->pFaces[j].vertIndex[0]];
v2 = pObject->pVerts[pObject->pFaces[j].vertIndex[1]];
v3 = pObject->pVerts[pObject->pFaces[j].vertIndex[2]];
vNormals[j] = Normalize(Cross(v1 - v2, v1 - v3));
}

for (j = 0; j < pObject->numOfVerts; j++)
{
sum = CVector3(0, 0, 0);
for (l = 0; l < pObject->numOfFaces; l++)
{
e = false;
for (k = 0; k < 3; k++)
{
if (pObject->pFaces[l].vertIndex[k] == j) e = true;
}

if (e)
{
sum = sum + vNormals[l];
}
}
sum = Normalize(sum);
pObject->pNormals[j] = sum;
}

delete [] vNormals;
}



It calculates vertex normals from the face normals, which will make it look much better.



[ My Site ]
''I wish life was not so short,'' he thought. ''Languages take such a time, and so do all the things one wants to know about.'' - J.R.R Tolkien
/*ilici*/

Share this post


Link to post
Share on other sites