Today I came across Inigo Quilez’s algorithm for computing a mesh surface’s normals at every vertex: Inigo Quilez :: computer graphics, mathematics, shaders, fractals, demoscene and more
It explains some of the unnecessary computation that the naive algorithms do and presents a short and sweet imperative algorithm which is faster, simpler, and equally correct.
Now, I need to write this algorithm in Haskell. And this seemed like an interesting and short enough problem to pose to more people. A little challenge if you will
. Here is the algorithm:
void Mesh_normalize( Mesh *myself )
{
Vert *vert = myself->vert;
Triangle *face = myself->face;
for( int i=0; i<myself->mNumVerts; i++ ) vert[i].normal = vec3(0.0f);
for( int i=0; i<myself->mNumFaces; i++ )
{
const int ia = face[i].v[0];
const int ib = face[i].v[1];
const int ic = face[i].v[2];
const vec3 e1 = vert[ia].pos - vert[ib].pos;
const vec3 e2 = vert[ic].pos - vert[ib].pos;
const vec3 no = cross( e1, e2 );
vert[ia].normal += no;
vert[ib].normal += no;
vert[ic].normal += no;
}
for( i=0; i<myself->mNumVerts; i++ ) verts[i].normal = normalize( verts[i].normal );
}
How would you implement this? I’d be happy to see both the most elegant functional versions of this and direct ST implementations alike.
If you are looking for a starting point (but feel free to do this however you’d like!), here’s roughly how I understand the type signature should be:
mesh_normalize :: [(Int, Int, Int)] -- ^ A list of faces, each composed of three indices into the vertices array
-> [Vec3] -- ^ A list of vertices, with x,y,z being the vertex position in 3D space
-> [Vec3] -- ^ The normal vector for each input vertex.
Or, say, using `[Int]` for the list of faces, where every 3 indices in a row form the face
Further thoughts: it could be cool to setup a little benchmark game so people can try them out



