star-3d

Surface structuring for efficient 3D geometric queries
git clone git://git.meso-star.fr/star-3d.git
Log | Files | Refs | README | LICENSE

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:
Msrc/test_s3d_closest_point.c | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
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);