commit 72cb802c1c7fa44839f666feeed8ee1fcf4c8ea4
parent da4b64dc969778124ad10baf3b08b060f0038032
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 15 Dec 2020 14:37:53 +0100
Fix tetrahedron/aabb intersection test
Update the profile of the suvm_polyhedron_intersect_aabb function: return
the intersection type, i.e. [is_]included, partial or none.
Diffstat:
2 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/src/suvm.h b/src/suvm.h
@@ -114,6 +114,13 @@ struct suvm_tetrahedral_mesh_args {
static const struct suvm_tetrahedral_mesh_args SUVM_TETRAHEDRAL_MESH_ARGS_NULL =
SUVM_TETRAHEDRAL_MESH_ARGS_NULL__;
+enum suvm_intersection_type {
+ SUVM_INTERSECT_NONE,
+ SUVM_INTERSECT_INCLUDE,
+ SUVM_INTERSECT_IS_INCLUDED,
+ SUVM_INTERSECT_PARTIAL
+};
+
/* Callback invoked on suvm_volume_intersect_aabb invocation on each primitives
* intersected by the submitted Axis Aligned Bounding Box */
typedef void
@@ -215,7 +222,7 @@ suvm_primitive_setup_polyhedron
(const struct suvm_primitive* prim,
struct suvm_polyhedron* poly);
-SUVM_API int
+SUVM_API enum suvm_intersection_type
suvm_polyhedron_intersect_aabb
(const struct suvm_polyhedron* poly,
const float low[3],
diff --git a/src/suvm_primitive.c b/src/suvm_primitive.c
@@ -36,7 +36,7 @@ suvm_primitive_setup_polyhedron
* Its implementation follows the algorithms proposed by N. Greene in
* "Detecting intersection of a rectangular solid and a convex polyhedron"
* (Graphics Gems IV, 1994, p74--82) */
-int
+enum suvm_intersection_type
suvm_polyhedron_intersect_aabb
(const struct suvm_polyhedron* tetra,
const float low[3],
@@ -45,10 +45,10 @@ suvm_polyhedron_intersect_aabb
enum { X, Y, Z, AXES_COUNT }; /* Syntactic sugar */
float intersect_aabb_low[AXES_COUNT];
float intersect_aabb_upp[AXES_COUNT];
- int i;
int nplanes_including_aabb;
+ int i;
- ASSERT(tetra && low && !upp);
+ ASSERT(tetra && low && upp);
ASSERT(low[0] < upp[0]);
ASSERT(low[1] < upp[1]);
ASSERT(low[2] < upp[2]);
@@ -58,14 +58,17 @@ suvm_polyhedron_intersect_aabb
intersect_aabb_low[i] = MMAX(low[i], tetra->lower[i]);
intersect_aabb_upp[i] = MMIN(upp[i], tetra->upper[i]);
if(intersect_aabb_low[i] > intersect_aabb_upp[i]) /* Do not intersect */
- return 0;
+ return SUVM_INTERSECT_NONE;
}
/* Check if the tetrahedron is included into the aabb */
- if(intersect_aabb_low[X] == low[X]
- && intersect_aabb_low[Y] == low[Y]
- && intersect_aabb_low[Z] == low[Z]) {
- return 1;
+ if(intersect_aabb_low[X] == tetra->lower[X]
+ && intersect_aabb_low[Y] == tetra->lower[Y]
+ && intersect_aabb_low[Z] == tetra->lower[Z]
+ && intersect_aabb_upp[X] == tetra->upper[X]
+ && intersect_aabb_upp[Y] == tetra->upper[Y]
+ && intersect_aabb_upp[Z] == tetra->upper[Z]) {
+ return SUVM_INTERSECT_IS_INCLUDED;
}
/* #planes that totally includes the aabb on its positive side */
@@ -87,19 +90,23 @@ suvm_polyhedron_intersect_aabb
* 'p', aka the farthest aabb vertex in the positive direction of the plane
* normal, is not in the positive half space. In this case, the aabb is
* entirely outside the tetrahedron */
- if((f3_dot(tetra->N[i], p) + tetra->D[i]) < 0) return 0;
+ if((f3_dot(tetra->N[i], p) + tetra->D[i]) < 0) {
+ return SUVM_INTERSECT_NONE;
+ }
/* Check if the box is totally inside the given plane. To do this, check
* that 'n', aka the farthest aabb vertex in the negative direction of the
* plane normal, is inside the positive half space */
- if((f3_dot(tetra->N[i], n) + tetra->D[i]) > 0) {
+ if((f3_dot(tetra->N[i], n) + tetra->D[i]) >= 0) {
/* Register this plane as a plane including the aabb */
nplanes_including_aabb += 1;
}
}
/* Check if the aabb is entirely included into the tetrahedron */
- if(nplanes_including_aabb == 4) return 1;
+ if(nplanes_including_aabb == 4) {
+ return SUVM_INTERSECT_INCLUDE;
+ }
/* For each silhouette edge in each projection plane, check if it totally
* exclude the projected aabb */
@@ -123,12 +130,14 @@ suvm_polyhedron_intersect_aabb
/* Check that the projected aabb along the 'i'th axis is totally outside
* the current silhouette edge. That means that the aabb is entirely
* outside the tetrahedron and thus that they do not intersect */
- if((f2_dot(tetra->Ep[i][iedge], p) + tetra->Ep[i][iedge][2]) < 0) return 0;
+ if((f2_dot(tetra->Ep[i][iedge], p) + tetra->Ep[i][iedge][2]) < 0) {
+ return SUVM_INTERSECT_NONE;
+ }
}
}
/* The tetrahedron and the aabb are partially intersecting */
- return 1;
+ return SUVM_INTERSECT_PARTIAL;
}