make polygon normal computation more robust

This commit is contained in:
Irlan 2018-05-09 14:48:58 -03:00
parent 57f0370cd2
commit 1dd59fd5b8

View File

@ -664,40 +664,57 @@ static B3_FORCE_INLINE b3Vec3 b3Newell(const b3Vec3& a, const b3Vec3& b)
return b3Vec3((a.y - b.y) * (a.z + b.z), (a.z - b.z) * (a.x + b.x), (a.x - b.x) * (a.y + b.y)); return b3Vec3((a.y - b.y) * (a.z + b.z), (a.z - b.z) * (a.x + b.x), (a.x - b.x) * (a.y + b.y));
} }
// Compute face centroid, normal, and area
static void b3ResetFaceData(qhFace* face) static void b3ResetFaceData(qhFace* face)
{ {
b3Vec3 n; // Compute polygon centroid
n.SetZero();
b3Vec3 c; b3Vec3 c;
c.SetZero(); c.SetZero();
u32 count = 0; u32 count = 0;
qhHalfEdge* e = face->edge; qhHalfEdge* e = face->edge;
do do
{
b3Vec3 v = e->tail->position;
c += v;
++count;
e = e->next;
} while (e != face->edge);
B3_ASSERT(count >= 3);
c /= float32(count);
// Compute normal
b3Vec3 n;
n.SetZero();
e = face->edge;
do
{ {
b3Vec3 v1 = e->tail->position; b3Vec3 v1 = e->tail->position;
b3Vec3 v2 = e->next->tail->position; b3Vec3 v2 = e->next->tail->position;
n += b3Newell(v1, v2); // Shift the polygon origin to the centroid
c += v1; v1 -= c;
v2 -= c;
++count; // Apply Newew's method
n += b3Newell(v1, v2);
e = e->next; e = e->next;
} while (e != face->edge); } while (e != face->edge);
B3_ASSERT(count > 0); // Centroid
c /= float32(count);
face->center = c; face->center = c;
float32 len = b3Length(n); float32 len = b3Length(n);
face->area = 0.5f * len;
B3_ASSERT(len > B3_EPSILON); B3_ASSERT(len > B3_EPSILON);
n /= len; n /= len;
// Area
face->area = 0.5f * len;
// Normal
face->plane.normal = n; face->plane.normal = n;
face->plane.offset = b3Dot(n, c); face->plane.offset = b3Dot(n, c);
} }