static bool IsClockwise(const DirectX::XMFLOAT3 *vertex, int num_verts, const FbxVector4 &polygon_normal) { // Compute a normal using two edges of the triangle FbxVector4 edge_1(vertex[1].x - vertex[0].x, vertex[1].y - vertex[0].y, vertex[1].z - vertex[0].z); FbxVector4 edge_2(vertex[2].x - vertex[0].x, vertex[2].y - vertex[0].y, vertex[2].z - vertex[0].z); FbxVector4 normal = edge_1.CrossProduct(edge_2); // Dot product between computed normal and supplied normal will reveal winding double dot = polygon_normal.DotProduct(normal); return dot < 0; }
/* mend face with colinear vertices */ static int mendface (face *f) { edge *e, *h, *x, *y, *z, *w, *o; double u [3], v [3], d, l [2]; double *a, *b, *c; face *g; for (e = f->e; e; e = e->n) { a = e->v [0]; b = e->v [1]; if (!(c = otherv (f, a, b))) return 0; SUB (b, a, u); SUB (c, a, v); l[0] = LEN (u); l[1] = LEN (v); d = DOT (u, v); if (d >= 0 && l[1] <= l[0]) break; /* c in [a, b] */ } if (e) { a = c; g = e->f; if (!(h = othere (g, f))) return 0; if (!(b = otherv (g, h->v[0], h->v[1]))) return 0; if (!(x = edge_0 (f, a))) return 0; if (!(y = edge_1 (g, b))) return 0; if (!(z = edge_0 (g, b))) return 0; if (!(w = edge_1 (f, a))) return 0; if (!(o = othere (y->f, g))) return 0; o->f = f; if (!(o = othere (w->f, f))) return 0; o->f = g; e->v [0] = b; e->v [1] = a; h->v [0] = a; h->v [1] = b; e->n = NULL; y->n = e; x->n = y; f->e = x; h->n = NULL; w->n = h; z->n = w; g->e = z; #if GEOMDEBUG ASSERT_DEBUG (setplane (f), "Zero normal (when mending face)"); ASSERT_DEBUG (setplane (g), "Zero normal (when mending face)"); #else if (!(setplane (f) && setplane (g))) return 0; #endif } #if GEOMDEBUG else { ASSERT_DEBUG (0, "Face mending failed"); } #else else return 0;