commit 7e3d3ff4e4219d4eb94635de29487c18b33c8021
parent 3d276fabd3897ce587ed402e212d0b47a22d1045
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 9 Nov 2022 09:00:22 +0100
Work around numerical inaccuracy of barycentric coordinates
Diffstat:
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/suvm_volume_at.c b/src/suvm_volume_at.c
@@ -44,7 +44,7 @@ intersect_leaf
float n0[3], n1[3], n2[3], n3[3];
float p[3];
float d0, d1, d2, d3;
- float h0, h1, h2, h3;
+ float h1, h2, h3;
size_t itetra;
ASSERT(vol && leaf && pos && bcoords);
ASSERT(leaf->prim_id < volume_get_primitives_count(vol));
@@ -80,7 +80,6 @@ intersect_leaf
v2 = darray_float_cdata_get(&vol->positions) + tetra[2]*3;
/* Distance of tetrahedron corners to their opposite face */
- h0 = f3_dot(n0, f3_sub(p, v3, v0));
h1 = f3_dot(n1, f3_sub(p, v2, v1));
h2 = f3_dot(n2, f3_sub(p, v0, v2));
h3 = f3_dot(n3, f3_sub(p, v1, v3));
@@ -89,7 +88,18 @@ intersect_leaf
bcoords[0] = d2 / h2;
bcoords[1] = d3 / h3;
bcoords[2] = d1 / h1;
- bcoords[3] = d0 / h0;
+
+#if 1
+ /* Do not use d0 and h0 to calculate the last barycentric coordinate but
+ * calculate it from the 3 others. This gets around the numerical imprecision
+ * and ensures that the sum of the bcoords is indeed 1 */
+ bcoords[3] = 1.f - bcoords[0] - bcoords[1] - bcoords[2];
+#else
+ {
+ const float h0 = f3_dot(n0, f3_sub(p, v3, v0));
+ bcoords[3] = d0 / h0;
+ }
+#endif
return 1;
}