commit 80c1e00b87d2cc644866c9f614a40036c3f7fd6a
parent ea54aeabde131965518bf6355c82ddaa612ac2f4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 16 Oct 2019 12:31:09 +0200
Test the s3d_scene_view_closest_point on spheres only
Diffstat:
1 file changed, 140 insertions(+), 3 deletions(-)
diff --git a/src/test_s3d_closest_point.c b/src/test_s3d_closest_point.c
@@ -194,6 +194,7 @@ closest_point_sphere
f3_sub(vec, pos, sphere_org);
len = f3_normalize(vec, vec);
+ CHK(len > 0);
pt->dst = (float)fabs(len - sphere_radius);
f3_set(pt->normal, vec);
@@ -465,6 +466,141 @@ test_cbox_sphere(struct s3d_device* dev)
}
/*******************************************************************************
+ * Sphere test
+ ******************************************************************************/
+struct sphere_filter_data {
+ float query_pos[3];
+};
+
+static int
+sphere_filter
+ (const struct s3d_hit* hit,
+ const float org[3],
+ const float dir[3],
+ void* query_data,
+ void* filter_data)
+{
+ struct sphere_filter_data* data = query_data;
+ struct s3d_attrib attr;
+ float pos[3];
+ float vec[3];
+
+ CHK(hit && org && dir && !S3D_HIT_NONE(hit));
+ CHK((intptr_t)filter_data == (intptr_t)0xDECAFBAD);
+ CHK(f3_normalize(vec, dir) != 0);
+
+ f3_add(pos, org, f3_mulf(pos, vec, hit->distance));
+ CHK(s3d_primitive_get_attrib
+ (&hit->prim, S3D_POSITION, hit->uv, &attr) == RES_OK);
+ CHK(f3_eq_eps(attr.value, pos, POSITION_EPSILON));
+
+ CHK(f3_eq_eps(data->query_pos, org, POSITION_EPSILON));
+
+ return 1;
+}
+
+static void
+test_sphere(struct s3d_device* dev)
+{
+ struct s3d_attrib attr;
+ struct s3d_hit hit = S3D_HIT_NULL;
+ struct s3d_shape* sphere = NULL;
+ struct s3d_scene* scn = NULL;
+ struct s3d_scene_view* scnview = NULL;
+ struct sphere_filter_data filter_data;
+ void* ptr = (void*)((intptr_t)0xDECAFBAD);
+ size_t i;
+ float sphere_pos[3];
+ float query_pos[3];
+ float sphere_radius;
+ float pos[3];
+ float dir[3];
+ unsigned sphere_id;
+
+ CHK(s3d_scene_create(dev, &scn) == RES_OK);
+ CHK(s3d_shape_create_sphere(dev, &sphere) == RES_OK);
+ CHK(s3d_shape_get_id(sphere, &sphere_id) == RES_OK);
+ CHK(s3d_scene_attach_shape(scn, sphere) == RES_OK);
+
+ f3_splat(sphere_pos, 1);
+ sphere_radius = 2;
+ f3_set(query_pos, sphere_pos);
+ CHK(s3d_sphere_setup(sphere, query_pos, sphere_radius) == RES_OK);
+ CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK);
+
+ /* Check a closest point query exactly at the center of the sphere */
+ CHK(s3d_scene_view_closest_point
+ (scnview, sphere_pos, (float)INF, NULL, &hit) == RES_OK);
+ CHK(!S3D_HIT_NONE(&hit));
+ CHK(s3d_primitive_get_attrib(&hit.prim, S3D_POSITION, hit.uv, &attr) == RES_OK);
+
+ f3_normalize(dir, f3_sub(dir, attr.value, query_pos));
+ f3_add(pos, attr.value, f3_mulf(pos, dir, -hit.distance));
+ CHK(hit.distance == sphere_radius);
+ CHK(f3_eq_eps(pos, sphere_pos, POSITION_EPSILON));
+
+ /* Check the exclusive bound of the search radius */
+ CHK(s3d_scene_view_closest_point
+ (scnview, sphere_pos, sphere_radius, NULL, &hit) == RES_OK);
+ CHK(S3D_HIT_NONE(&hit));
+
+ /* Check closest point query on a sphere */
+ FOR_EACH(i, 0, 10000) {
+ struct closest_pt pt;
+ float Ng[3];
+ query_pos[0] = sphere_pos[0] + (rand_canonic() * 2 - 1) * sphere_radius;
+ query_pos[1] = sphere_pos[1] + (rand_canonic() * 2 - 1) * sphere_radius;
+ query_pos[2] = sphere_pos[2] + (rand_canonic() * 2 - 1) * sphere_radius;
+
+ CHK(s3d_scene_view_closest_point
+ (scnview, query_pos, (float)INF, NULL, &hit) == RES_OK);
+ CHK(!S3D_HIT_NONE(&hit));
+ CHK(s3d_primitive_get_attrib(&hit.prim, S3D_POSITION, hit.uv, &attr) == RES_OK);
+
+ /* Cross check the closest point query result */
+ closest_point_sphere(query_pos, sphere_pos, sphere_radius,
+ sphere_id, S3D_INVALID_ID, &pt);
+
+ f3_normalize(Ng, hit.normal);
+
+ CHK(pt.dst == hit.distance);
+ CHK(pt.iprim == hit.prim.prim_id);
+ CHK(pt.igeom == hit.prim.geom_id);
+ CHK(pt.iinst == hit.prim.inst_id);
+ CHK(f3_eq_eps(pt.pos, attr.value, POSITION_EPSILON));
+ CHK(f3_eq_eps(pt.normal, Ng, 1.e-4f));
+
+ /* Check search radius exclusivity */
+ CHK(s3d_scene_view_closest_point
+ (scnview, query_pos, hit.distance, NULL, &hit) == RES_OK);
+ CHK(S3D_HIT_NONE(&hit));
+ hit.distance = nextafterf(hit.distance, 0.f);
+ CHK(s3d_scene_view_closest_point
+ (scnview, query_pos, hit.distance, NULL, &hit) == RES_OK);
+ CHK(!S3D_HIT_NONE(&hit));
+ }
+
+ /* Check the filtering function */
+ CHK(s3d_sphere_set_hit_filter_function(sphere, sphere_filter, ptr) == RES_OK);
+
+ f3_splat(query_pos, 10);
+ f3_set(filter_data.query_pos, query_pos);
+ CHK(s3d_scene_view_closest_point
+ (scnview, query_pos, (float)INF, &filter_data, &hit) == RES_OK);
+ CHK(!S3D_HIT_NONE(&hit));
+
+ CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
+ CHK(s3d_scene_view_create(scn, S3D_TRACE, &scnview) == RES_OK);
+ CHK(s3d_scene_view_closest_point
+ (scnview, query_pos, (float)INF, &filter_data, &hit) == RES_OK);
+ CHK(S3D_HIT_NONE(&hit));
+
+ CHK(s3d_shape_ref_put(sphere) == RES_OK);
+ CHK(s3d_scene_ref_put(scn) == RES_OK);
+ CHK(s3d_scene_view_ref_put(scnview) == RES_OK);
+}
+
+/*******************************************************************************
* Cornell box test
******************************************************************************/
enum cbox_geom {
@@ -610,7 +746,7 @@ test_cbox(struct s3d_device* dev)
mid[1] = (low[1] + upp[1]) * 0.5f;
mid[2] = (low[2] + upp[2]) * 0.5f;
- /* Check point query on Cornell box */
+ /* Check closest point query on Cornell box */
FOR_EACH(i, 0, 10000) {
/* Randomly generate a point in a bounding box that is 2 times the size of
* the triangle AABB */
@@ -629,7 +765,7 @@ test_cbox(struct s3d_device* dev)
geom_id[CBOX_TALL_BLOCK] = S3D_INVALID_ID;
geom_id[CBOX_SHORT_BLOCK] = S3D_INVALID_ID;
- /* Check point query filtering */
+ /* Check closest point query filtering */
FOR_EACH(i, 0, 10000) {
/* Randomly generate a point in a bounding box that is 2 times the size of
* the triangle AABB */
@@ -734,7 +870,7 @@ test_single_triangle(struct s3d_device* dev)
CHK(!S3D_HIT_NONE(&hit));
CHK(s3d_primitive_get_attrib(&hit.prim, S3D_POSITION, hit.uv, &attr) == RES_OK);
- /* Cross check the point query result */
+ /* Cross check the closest point query result */
closest_point_triangle(pos, v0, v1, v2, closest_pos);
CHK(f3_eq_eps(closest_pos, attr.value, 1.e-4f));
}
@@ -811,6 +947,7 @@ main(int argc, char** argv)
test_api(dev);
test_single_triangle(dev);
test_cbox(dev);
+ test_sphere(dev);
test_cbox_sphere(dev);
CHK(s3d_device_ref_put(dev) == RES_OK);