+#if FIND_NORMALS == 2
+
+#include "map.h"
+DECLARE_AND_DEFINE_MAP_TYPE3(vec_t, list_t*, vnorm, vec_compare(*a, *b));
+
+
+/*
+ * Associate a triangle with one of its vertices.
+ */
+static void _find_normals_add_vertex(map_t* m, vec_t v, tri_t* t)
+{
+ list_t** l = map_vnorm_search(m, v);
+ if (l == NULL) {
+ map_vnorm_data_t* d = map_vnorm_insert(m, v, NULL);
+ l = &d->val;
+ }
+ list_push(l, t);
+}
+
+/*
+ * Associate a triangle with all of its vertices.
+ */
+static void _find_normals_add_triangle(map_t* m, tri_t* t)
+{
+ _find_normals_add_vertex(m, t->a.v, t);
+ _find_normals_add_vertex(m, t->b.v, t);
+ _find_normals_add_vertex(m, t->c.v, t);
+}
+
+
+/*
+ * Calculate an averaged normal from a list of triangles that share a common
+ * vertex.
+ */
+static void _find_normals_average(const vec_t* v, list_t** l)
+{
+ // first, compute the average normal
+ vec_t n = VEC_ZERO;
+ for (list_t* i = *l; i; i = i->link) {
+ tri_t* t = (tri_t*)i->val;
+ n = vec_add(n, tri_normal(*t));
+ }
+ n = vec_normalize(n);
+
+ // set the normal on each triangle's vertex that is shared
+ while (*l) {
+ tri_t* t = (tri_t*)(*l)->val;
+ if (vec_isequal(*v, t->a.v)) {
+ t->a.n = n;
+ }
+ else if (vec_isequal(*v, t->b.v)) {
+ t->b.n = n;
+ }
+ else if (vec_isequal(*v, t->c.v)) {
+ t->c.n = n;
+ }
+ list_pop(l);
+ }
+}
+
+#endif // FIND_NORMALS
+
+