Normals generator

I have this function that I want to generate normals for on it’s own.It work’s fine. But Its really ugly and tacky. I just wanna be able to call it and that is it. But I have a function normalise. But I doubt that will determine what way it is supposely be looking at.

MATH_INLINE void glNormal3d(Vec3& p1, Vec3& p2)
{
Vec3 v = Vec3(x, y, z);
Vec3 v1 = p1 - v;
Vec3 v2 = p2 - p1;
Vec3 normal = Vec3(v1.cross(v2));
normal.normalise();
normal.printVec3();
glNormal3dv(normal.ptr());
}

glBegin(GL_TRIANGLES);
verts[0].glNormal3d(verts[1], verts[2]); verts[0].glVertex3d();
verts[1].glNormal3d(verts[2], verts[0]); verts[1].glVertex3d();
verts[2].glNormal3d(verts[0], verts[1]); verts[2].glVertex3d();
glEnd();

My 3DS-to-P3D (custom format) converter does something similar and it works. Did you check if yours really works? (you said you’re in doubt, right?) Here’s the code if you want to check, feel free to adapt it to your work if you want:

      u[0] = vertices[polygons[i].vertex[0]].coords[0] -
             vertices[polygons[i].vertex[1]].coords[0];
      u[1] = vertices[polygons[i].vertex[0]].coords[1] -
             vertices[polygons[i].vertex[1]].coords[1];
      u[2] = vertices[polygons[i].vertex[0]].coords[2] -
             vertices[polygons[i].vertex[1]].coords[2];
      v[0] = vertices[polygons[i].vertex[1]].coords[0] -
             vertices[polygons[i].vertex[2]].coords[0];
      v[1] = vertices[polygons[i].vertex[1]].coords[1] -
             vertices[polygons[i].vertex[2]].coords[1];
      v[2] = vertices[polygons[i].vertex[1]].coords[2] -
             vertices[polygons[i].vertex[2]].coords[2];
             
      polygons[i].normal[0] = u[1] * v[2] - u[2] * v[1];
      polygons[i].normal[1] = u[2] * v[0] - u[0] * v[2];
      polygons[i].normal[2] = u[0] * v[1] - u[1] * v[0];
      
      factor = sqrt(polygons[i].normal[0] * polygons[i].normal[0] +
                    polygons[i].normal[1] * polygons[i].normal[1] +
                    polygons[i].normal[2] * polygons[i].normal[2]);

No the code gives me the correct one. but the vector normalise itself. if I was to do

Vec3d v = Vec3d(3.4, 4.6, -2.0);
v.normalise();
glNormal3dv(v.ptr());

Where is the question here?

Eckos, if I understand correctly, you think your code should be simpler.
Since for lighting, any normal needs to be of unit length, I’m pretty certain you’ll need to call your normalise function at some point (which I assume makes it a unit vector).

I see three odd things with your code:

  1. you pass in only two vertices instead of three vertices or two vectors - you seem to use a vertex member function when conceptually you are calculating a triangle normal, not a vertex normal.
  2. you use a Vec3 constructor for v, when you could just use (*this)
  3. the Vec3(v1.cross(v2)) bit seems redundant. Presumably your cross method already returns a Vec3, so you won’t need to use a constructor or cast there.

W.r.t. code structure, it may (may) be more elegant to just do a single glNormal call per triangle, with the three vertices passed into your function. Since direct mode uses a state machine approach, the same normal will be used until a new glNormal call is issued. If you don’t want smoothed vertex normals, you can just use one glNormal, followed by the three glVertex calls.

If you do want smoothed normals, you’ll have to set the vertex normals to the average of the connected triangles’ normals and then normalise them again. That’s more of a preprocessing step I’m afraid (although it shouldn’t very long on a modern machine).
Once you have those stored somewhere, you’ll obviously have to do one glNormal per vertex.