star-vx

Structuring voxels for ray-tracing
git clone git://git.meso-star.fr/star-vx.git
Log | Files | Refs | README | LICENSE

commit a638ee17618af470f1ebac6a84abcd8624c2f976
parent ea7be46e4328f160bc00b9bcb9e03ed69721befd
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 22 Mar 2021 15:45:57 +0100

Upd the profile of the hit_challenge traversal functor

Add the ray origin/direction/range as input arguments

Diffstat:
Msrc/svx.h | 3+++
Msrc/svx_bintree_trace_ray.c | 3++-
Msrc/svx_octree_trace_ray.c | 3++-
Msrc/test_svx_bintree_trace_ray.c | 33++++++++++++++++++++++++++++-----
Msrc/test_svx_octree_trace_ray.c | 36++++++++++++++++++++++++++++++------
5 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/src/svx.h b/src/svx.h @@ -161,6 +161,9 @@ typedef void typedef int (*svx_hit_challenge_T) (const struct svx_hit* hit, + const double ray_org[3], + const double ray_dir[3], + const double ray_range[2], void* context); /* Hit filter function data type. The caller can define a function of this type diff --git a/src/svx_bintree_trace_ray.c b/src/svx_bintree_trace_ray.c @@ -187,7 +187,8 @@ bintree_trace_ray setup_hit(btree, iattr, t_min, t_max, low, scale_exp2, depth, is_leaf, flip, &hit_tmp); - if(is_leaf || challenge(&hit_tmp, context)) { + if(is_leaf + || challenge(&hit_tmp, ray_org, ray_dir, ray_range, context)) { go_deeper = 0; /* Stop the traversal if no filter is defined or if the filter * function returns 0 */ diff --git a/src/svx_octree_trace_ray.c b/src/svx_octree_trace_ray.c @@ -255,7 +255,8 @@ trace_ray setup_hit(oct, iattr, t_min, t_max_child, corner, scale_exp2, depth, is_leaf, ray->octant_mask, &hit_tmp); - if(is_leaf || challenge(&hit_tmp, context)) { + if(is_leaf + || challenge(&hit_tmp, ray->orgws, ray->dirws, ray->range, context)) { go_deeper = 0; /* Stop the traversal if no filter is defined or if the filter * function returns 0 */ diff --git a/src/test_svx_bintree_trace_ray.c b/src/test_svx_bintree_trace_ray.c @@ -103,15 +103,37 @@ voxels_challenge_merge } static int -hit_challenge(const struct svx_hit* hit, void* context) +hit_challenge + (const struct svx_hit* hit, + const double ray_org[3], + const double ray_dir[3], + const double ray_range[2], + void* context) { (void)context; - CHK(hit); + CHK(hit && ray_org && ray_dir && ray_range); CHK(!SVX_HIT_NONE(hit)); return 1; } static int +hit_challenge_pass_through + (const struct svx_hit* hit, + const double ray_org[3], + const double ray_dir[3], + const double ray_range[2], + void* context) +{ + const struct ray* ray = context; + CHK(hit && ray_org && ray_dir && ray_range && context); + CHK(!SVX_HIT_NONE(hit)); + CHK(d3_eq(ray->org, ray_org)); + CHK(d3_eq(ray->dir, ray_dir)); + CHK(d2_eq(ray->range, ray_range)); + return 0; +} + +static int hit_filter (const struct svx_hit* hit, const double ray_org[3], @@ -187,8 +209,8 @@ draw_image(struct image* img, struct svx_tree* btree) pix[0] = (double)ix / (double)width; camera_ray(&cam, pix, &r); - CHK(svx_tree_trace_ray - (btree, r.org, r.dir, r.range, NULL, hit_filter, &r, &hit) == RES_OK); + CHK(svx_tree_trace_ray(btree, r.org, r.dir, r.range, + hit_challenge_pass_through, hit_filter, &r, &hit) == RES_OK); pixels[ipix+0] = 0; pixels[ipix+1] = 0; pixels[ipix+2] = 0; @@ -332,7 +354,8 @@ main(int argc, char** argv) CHK(eq_eps(hit.distance[1], (hit.voxel.lower[0]-r.org[0])/r.dir[0], 1.e-6)); /* Use filter function to discard leaves with a value == 0 */ - CHK(RT(btree, r.org, r.dir, r.range, NULL, hit_filter, &r, &hit) == RES_OK); + CHK(RT(btree, r.org, r.dir, r.range, hit_challenge_pass_through, hit_filter, + &r, &hit) == RES_OK); CHK(!SVX_HIT_NONE(&hit)); CHK(hit.voxel.is_leaf == 1); CHK(hit.voxel.depth == 5); diff --git a/src/test_svx_octree_trace_ray.c b/src/test_svx_octree_trace_ray.c @@ -187,14 +187,36 @@ hit_filter3 } static int -hit_challenge(const struct svx_hit* hit, void* context) +hit_challenge + (const struct svx_hit* hit, + const double ray_org[3], + const double ray_dir[3], + const double ray_range[2], + void* context) { (void)context; - CHK(hit); + CHK(hit && ray_org && ray_dir && ray_range); CHK(!SVX_HIT_NONE(hit)); return 1; } +static int +hit_challenge_pass_through + (const struct svx_hit* hit, + const double ray_org[3], + const double ray_dir[3], + const double ray_range[2], + void* context) +{ + const struct ray* ray = context; + CHK(hit && ray_org && ray_dir && ray_range); + CHK(!SVX_HIT_NONE(hit)); + CHK(d3_eq(ray->org, ray_org)); + CHK(d3_eq(ray->dir, ray_dir)); + CHK(d2_eq(ray->range, ray_range)); + return 0; +} + static void draw_image(struct image* img, struct svx_tree* oct, const struct scene* scn) { @@ -227,8 +249,8 @@ draw_image(struct image* img, struct svx_tree* oct, const struct scene* scn) pix[0] = (double)ix / (double)width; camera_ray(&cam, pix, &r); - CHK(svx_tree_trace_ray - (oct, r.org, r.dir, r.range, NULL, hit_filter, &r, &hit) == RES_OK); + CHK(svx_tree_trace_ray(oct, r.org, r.dir, r.range, + hit_challenge_pass_through, hit_filter, &r, &hit) == RES_OK); if(SVX_HIT_NONE(&hit)) { pixels[ipix+0] = 0; pixels[ipix+1] = 0; @@ -343,7 +365,8 @@ main(int argc, char** argv) CHK(eq_eps(hit.distance[0], hit2.distance[0], 1.e-6)); /* Use filter function to discard leaves with a value == 0 */ - CHK(RT(oct, r.org, r.dir, r.range, NULL, hit_filter, &r, &hit) == RES_OK); + CHK(RT(oct, r.org, r.dir, r.range, hit_challenge_pass_through, hit_filter, + &r, &hit) == RES_OK); CHK(!SVX_HIT_NONE(&hit)); CHK(eq_eps(hit.distance[0], hit.voxel.lower[1] - r.org[1], 1.e-6)); CHK(eq_eps(hit.distance[1], hit.voxel.upper[1] - r.org[1], 1.e-6)); @@ -352,7 +375,8 @@ main(int argc, char** argv) /* Use the ray range to avoid the intersection with the closest voxel */ r.range[1] = nextafter(hit.distance[0], -1); - CHK(RT(oct, r.org, r.dir, r.range, NULL, hit_filter, &r, &hit) == RES_OK); + CHK(RT(oct, r.org, r.dir, r.range, hit_challenge_pass_through, hit_filter, + &r, &hit) == RES_OK); CHK(SVX_HIT_NONE(&hit)); r.range[1] = INF;