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:
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;