10/15/10

Simple Code to Calculate normals for a Quad Mesh

I'm ripping iq here. However, I've fiound a lot of people haven't read his brilliant normals idea buried deep in one of his presentations, plus I add face normals and a subtle way to rewrite crossproduct that shortens code again.

Here is some tiny  pseudo-code to calculate both the vertex and face normals of a  mesh made of quads. It is pseudo-code because your mesh structure will not be the same as mine.  The idea is based on iqs idea in his Breakpoint presentation.
 for ( i=0; i<numberofquads; i++) {
         for (uint k=0; k<4; k++)  cross ( &quad[i].v[k], &quad[i].v[(k+1)&3], &facenormals[i] );
         for (uint k=0; k<4; k++)  add ( &facenormals[i], &vertexnormals[&quad[i].v[k]]);
 }
Now this neat and easy to read and incredibly small for such power. Essentially it is:
for each quad
    for each edge in quad
         accumulate crossproduct of edge vertices into face normal
   for each vertex in quad
         add face normal

One subtle trick here in the code is that cross product is redefined thus:
cross(v1,v2,v3) ::  v3 = v3 + crossproduct (v1,v2)
Add is as you expect::
add(v1,v2):: v2=v2+v1;

During qoob modeller writing I found redefining cross product in this way was fine, after all it can be called with a zeroed vector in last place if a true cross product is required rather than accumulating. If you don't understand how accumulating cross products of each edge of the polygon equates to calculating a normal, see iqs presentation. That is the really smart thing here.

N.B.: Assumes facenormals and vertexnormals contain zero values before calling this function.
 The normals are not normalised (leave that to shaders or GL_NORMALIZE).

1 comment:

  1. thank you so much! this might be a very helpful hint. I think this is what my small project missed

    ReplyDelete