PDA

View Full Version : Calculating face normals



c_olin
04-16-2004, 01:59 PM
I've written programs that calculate face normals for triangles before, but I'm stuck!



void computeFaceNormals( void ) {
cVector3 v1, v2, faceNormal;

for(int i = 0; i < m_numTriangles; i++) {
v1 = m_vertices[m_triangles[i].indices[2]].point - m_vertices[m_triangles[i].indices[0]].point;
v2 = m_vertices[m_triangles[i].indices[2]].point - m_vertices[m_triangles[i].indices[1]].point;
faceNormal = cross(v1, v2);
m_triangles[i].normal = normalize(faceNormal);
}
}I'm drawing my polygons clockwise, but when i render it with lights, the normals are obviously screwed up!

whats the problem?

_new_horizon
04-16-2004, 03:32 PM
Here's how I did it:

void CTriangle::ComputeNormal()
{
CVertex v1 = vertices[0]->Difference(vertices[2]);
CVertex v2 = vertices[2]->Difference(vertices[1]);

CVertex norm = v1.CrossProduct(v2);
norm.Normalize();

faceNormal = norm;
}

where vertices[0] - [2] reference the three vertices, and faceNomal holds the resulting normal. Difference is just subtracting one point from another and returning the result.

This code will work for n-gons, providing they are planar.

But if you want *smooth* lighting, you'll need to compute the normals of each vertex...

c_olin
04-16-2004, 04:02 PM
Thanks for the reply!

But Thats the same thing that I have, here is my class:


//*---obj.h---*//

class obj { //Mesh file exported from Lightwave
public:
int m_tid; //Texture ID
int m_numVertices;
int m_numTriangles;
cVertex *m_vertices;
cTriangle *m_triangles;

void computeFaceNormals( void ) {
cVector3 v1, v2, faceNormal;

for(int i = 0; i < m_numTriangles; i++) {
v1 = m_vertices[m_triangles[i].indices[0]].point - m_vertices[m_triangles[i].indices[2]].point;
v2 = m_vertices[m_triangles[i].indices[2]].point - m_vertices[m_triangles[i].indices[1]].point;
faceNormal = cross(v1, v2);
m_triangles[i].normal = normalize(faceNormal);
}
}

void loadObj(char* filename) {
char tga[25];
char blank[10];

console.newCMsg("Loading mesh: %s...", filename);

ifstream ifs(filename);

ifs >> tga;

m_tid = texCount;
loadTexture(tga, false, 0);

ifs >> blank;
ifs >> m_numVertices;
ifs >> blank;
ifs >> m_numTriangles;

m_vertices = new cVertex[m_numVertices];
m_triangles = new cTriangle[m_numTriangles];

for(int i = 0; i < m_numVertices; i++) { //Read Vertices
ifs >> blank;
ifs >> m_vertices[i].point.x;
ifs >> m_vertices[i].point.y;
ifs >> m_vertices[i].point.z;
}

for(i = 0; i < m_numTriangles; i++) { //Read Triangles
ifs >> blank;
ifs >> m_triangles[i].u[0];
ifs >> m_triangles[i].v[0];
ifs >> blank;
ifs >> m_triangles[i].u[1];
ifs >> m_triangles[i].v[1];
ifs >> blank;
ifs >> m_triangles[i].u[2];
ifs >> m_triangles[i].v[2];

ifs >> blank;
ifs >> m_triangles[i].indices[0];
ifs >> blank;
ifs >> m_triangles[i].indices[1];
ifs >> blank;
ifs >> m_triangles[i].indices[2];
ifs >> blank;
}

computeFaceNormals();

console.newCMsg("done");
}

void renderObj(float x, float y, float z, bool vertexNormals) { //Render mesh
glEnable(GL_TEXTURE_2D);

glTranslatef(x, y, z);

glBindTexture(GL_TEXTURE_2D, texture[m_tid].texID);

if(vertexNormals) {
glBegin(GL_TRIANGLES);
for(int i = 0; i < m_numTriangles; i++) {
glNormal3f(m_vertices[m_triangles[i].indices[0]-1].normal.x, m_vertices[m_triangles[i].indices[0]-1].normal.y, m_vertices[m_triangles[i].indices[0]-1].normal.z); glTexCoord2f(m_triangles[i].u[2], m_triangles[i].v[2]); glVertex3f(m_vertices[m_triangles[i].indices[0]-1].point.x, m_vertices[m_triangles[i].indices[0]-1].point.y, m_vertices[m_triangles[i].indices[0]-1].point.z);
glNormal3f(m_vertices[m_triangles[i].indices[0]-1].normal.x, m_vertices[m_triangles[i].indices[0]-1].normal.y, m_vertices[m_triangles[i].indices[0]-1].normal.z); glTexCoord2f(m_triangles[i].u[1], m_triangles[i].v[1]); glVertex3f(m_vertices[m_triangles[i].indices[1]-1].point.x, m_vertices[m_triangles[i].indices[1]-1].point.y, m_vertices[m_triangles[i].indices[1]-1].point.z);
glNormal3f(m_vertices[m_triangles[i].indices[0]-1].normal.x, m_vertices[m_triangles[i].indices[0]-1].normal.y, m_vertices[m_triangles[i].indices[0]-1].normal.z); glTexCoord2f(m_triangles[i].u[0], m_triangles[i].v[0]); glVertex3f(m_vertices[m_triangles[i].indices[2]-1].point.x, m_vertices[m_triangles[i].indices[2]-1].point.y, m_vertices[m_triangles[i].indices[2]-1].point.z);
}
glEnd();
}
else {
glBegin(GL_TRIANGLES);
for(int i = 0; i < m_numTriangles; i++) {
glNormal3f(m_triangles[i].normal.x, m_triangles[i].normal.y, m_triangles[i].normal.z);
glTexCoord2f(m_triangles[i].u[2], m_triangles[i].v[2]); glVertex3f(m_vertices[m_triangles[i].indices[0]-1].point.x, m_vertices[m_triangles[i].indices[0]-1].point.y, m_vertices[m_triangles[i].indices[0]-1].point.z);
glTexCoord2f(m_triangles[i].u[1], m_triangles[i].v[1]); glVertex3f(m_vertices[m_triangles[i].indices[1]-1].point.x, m_vertices[m_triangles[i].indices[1]-1].point.y, m_vertices[m_triangles[i].indices[1]-1].point.z);
glTexCoord2f(m_triangles[i].u[0], m_triangles[i].v[0]); glVertex3f(m_vertices[m_triangles[i].indices[2]-1].point.x, m_vertices[m_triangles[i].indices[2]-1].point.y, m_vertices[m_triangles[i].indices[2]-1].point.z);
}
glEnd();
}

glTranslatef(-x, -y, -z);
}
};My normals aren't calculated correctly! It loks like it in the code, but when I draw the object with lighting it looks way screwed up..

What can possibly be wrong?!

_new_horizon
04-16-2004, 05:14 PM
Hard to say.
How are you normalizing you're, er, normals?

For flat shading, you only need to call glNormal() once per poly,

Have you set glEnable(GL_NORMALIZE)?

Have you set up the camera correctly? The default settings are rather poor.

Also, you don't need to reverse the transform to rest the model matrix. Just wrap you're code in glPushMatrix and glPopMatrix calls which is much safer and cleaner.

Have you set rendermode to GL_FLAT?

_new_horizon
04-16-2004, 05:18 PM
I tried posting the code I use but I get some error about parenthesis tags not be allowed fot html tags. I'm not using HTML!

And is it just my machine or is the message field really small?

c_olin
04-16-2004, 05:50 PM
if you looks closly in my code its set up to render vertex normals or poly normals... so i am calling glNormal once like you said...

I have tried everything that you posted, but I got nothing, Ill post my math functions, maybe they are wrong:

//*---3dmath.h---*//

struct cVector3 { //Structure for a 3d vector
public:
float x, y, z;

cVector3() {}

cVector3(float X, float Y, float Z) {
x = X; y = Y; z = Z;
}

cVector3 operator+(cVector3 vVector) {
return cVector3(vVector.x + x, vVector.y + y, vVector.z + z);
}

cVector3 operator-(cVector3 vVector) {
return cVector3(x - vVector.x, y - vVector.y, z - vVector.z);
}

cVector3 operator*(float num) {
return cVector3(x * num, y * num, z * num);
}

cVector3 operator/(float num) {
return cVector3(x / num, y / num, z / num);
}
};

cVector3 cross(cVector3 vVector1, cVector3 vVector2) { //Cross Product
cVector3 vNormal;

vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));
vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));
vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));

return vNormal;
}

float magnitude(cVector3 vNormal) { //Get magnitude of normal
return (float)sqrt( (vNormal.x * vNormal.x) +
(vNormal.y * vNormal.y) +
(vNormal.z * vNormal.z) );
}

cVector3 normalize(cVector3 vVector) { //Normalize a vector
float magnitude1 = magnitude(vVector);

vVector = vVector / magnitude1;

return vVector;
}

struct cVertex { //Struct for vertex
cVector3 point;
cVector3 normal;
};

struct cTriangle { //Struct for Triangle
int indices[3];
float u[3];
float v[3];
cVector3 normal;
};I checked all of that too! and found nothing wrong!