commit 9eeb638438df54945bcf6eb8105e611e7c61a2f5
parent 1e73722d4cee936b677eef817c8b5494b37a4f7a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 15 Dec 2020 11:48:46 +0100
Fix the setup of the tetrahedron
If a tetrahedron plane was orthogonal to an axis, its silhouette edges
along this axis might be wrongly oriented and could point outward the
tetrahedron. This commit fix this issue.
Diffstat:
1 file changed, 12 insertions(+), 25 deletions(-)
diff --git a/src/suvm_primitive.c b/src/suvm_primitive.c
@@ -148,9 +148,7 @@ tetrahedron_setup
const float* upp = upper;
float low__[3];
float upp__[3];
-#ifndef NDEBUG
float center[AXES_COUNT]; /* Center of the tetrahedron */
-#endif
float e[6][AXES_COUNT];
float (*v)[AXES_COUNT];
float (*N)[AXES_COUNT];
@@ -165,12 +163,10 @@ tetrahedron_setup
volume_primitive_get_vertex_position(vol, itetra, 3, tetra->v[3]);
v = tetra->v;
-#ifndef NDEBUG
/* Compute the center of the tetrahedron */
center[X] = (v[0][X] + v[1][X] + v[2][X] + v[3][X]) * 0.25f;
center[Y] = (v[0][Y] + v[1][Y] + v[2][Y] + v[3][Y]) * 0.25f;
center[Z] = (v[0][Z] + v[1][Z] + v[2][Z] + v[3][Z]) * 0.25f;
-#endif
/* Define the primitive AABB if necessary */
if(!low) {
@@ -232,6 +228,8 @@ tetrahedron_setup
* repairs are defined by the 'j' and 'k' variables. */
Ep = tetra->Ep;
FOR_EACH(i, 0, AXES_COUNT) {
+ float c[2]; /* Projected tetrahedron center */
+
/* On 1st iteration 'j' and 'k' define the YZ plane
* On 2nd iteration 'j' and 'k' define the ZX plane
* On 3rd ietration 'j' and 'k' define the XY plane */
@@ -241,6 +239,12 @@ tetrahedron_setup
/* Register the number of detected silhouette edges */
int n = 0;
+ int iedge;
+
+ /* Project the tetrahedron center */
+ c[0] = center[j];
+ c[1] = center[k];
+
/* To detect the silhouette edges, check the sign of the normals of two
* adjacent facets for the coordinate of the projection axis. If the signs
* are the same, the facets look at the same direction regarding the
@@ -280,37 +284,31 @@ tetrahedron_setup
* vertices. */
if(signf(N[0][i]) != signf(N[1][i])) { /* The edge 0 is silhouette */
f2_normalize(Ep[i][n], f2(Ep[i][n], e[0][k], -e[0][j]));
- if(N[0][i] > 0) f2_minus(Ep[i][n], Ep[i][n]);
Ep[i][n][2] = -f2_dot(Ep[i][n], v[0]);
++n;
}
if(signf(N[0][i]) != signf(N[2][i])) { /* The edge 1 is silhouette */
f2_normalize(Ep[i][n], f2(Ep[i][n], e[1][k], -e[1][j]));
- if(N[0][i] > 0) f2_minus(Ep[i][n], Ep[i][n]);
Ep[i][n][2] = -f2_dot(Ep[i][n], v[1]);
++n;
}
if(signf(N[0][i]) != signf(N[3][i])) { /* The edge 2 is silhouette */
f2_normalize(Ep[i][n], f2(Ep[i][n], e[2][k], -e[2][j]));
- if(N[0][i] > 0) f2_minus(Ep[i][n], Ep[i][n]);
Ep[i][n][2] = -f2_dot(Ep[i][n], v[2]);
++n;
}
if(signf(N[1][i]) != signf(N[3][i])) { /* The edge 3 is silhouette */
f2_normalize(Ep[i][n], f2(Ep[i][n], e[3][k], -e[3][j]));
- if(N[1][i] > 0) f2_minus(Ep[i][n], Ep[i][n]);
Ep[i][n][2] = -f2_dot(Ep[i][n], v[0]);
++n;
}
if(signf(N[1][i]) != signf(N[2][i])) { /* The edge 4 is silhouette */
f2_normalize(Ep[X][n], f2(Ep[i][n], e[4][k], -e[4][j]));
- if(N[2][i] > 0) f2_minus(Ep[i][n], Ep[i][n]);
Ep[i][n][2] = -f2_dot(Ep[i][n], v[1]);
++n;
}
if(signf(N[2][i]) != signf(N[3][i])) { /* The edge 5 is silhouette */
f2_normalize(Ep[i][n], f2(Ep[i][n], e[5][k], -e[5][j]));
- if(N[3][i] > 0) f2_minus(Ep[i][n], Ep[i][n]);
Ep[i][n][2] = -f2_dot(Ep[i][n], v[2]);
++n;
}
@@ -318,22 +316,11 @@ tetrahedron_setup
ASSERT(n == 3 || n == 4);
tetra->nEp[i] = n; /* Register the #silouhette edges for this project axis */
-#ifndef NDEBUG
- /* Assert that the normals points toward the expected half space */
- {
- int iedge;
- FOR_EACH(iedge, 0, n) {
- /* Evaluate the edge equation regarding the projected polyhedron center
- * and check that its sign is positive */
- const float dst =
- Ep[i][iedge][0] * center[j]
- + Ep[i][iedge][1] * center[k]
- + Ep[i][iedge][2];
- ASSERT(dst > 0);
- }
+ /* Ensure that the edge normals point toward the tetrahedron center */
+ FOR_EACH(iedge, 0, n) {
+ if(f2_dot(Ep[i][iedge], c) + Ep[i][iedge][2] < 0)
+ f3_minus(Ep[i][iedge], Ep[i][iedge]);
}
-#endif
}
}
-