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 4ae8a3839f49464c05830b3b7d59da72e0e2b7cf
parent 370982f88a64f501edbdc7af4f357cccb23f022c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 18 May 2016 09:49:38 +0200

Change the s3d_scene_trace_ray(s) API

Add per ray user defined data sent to the hit filter function

Diffstat:
Msrc/s3d.h | 9+++++++--
Msrc/s3d_scene.c | 51++++++++++++++++++++++++++++++---------------------
Msrc/test_s3d_shape.c | 5+++--
Msrc/test_s3d_trace_ray.c | 79+++++++++++++++++++++++++++++++++++++++++--------------------------------------
4 files changed, 81 insertions(+), 63 deletions(-)

diff --git a/src/s3d.h b/src/s3d.h @@ -63,7 +63,8 @@ enum s3d_rays_flag { S3D_RAYS_SINGLE_ORIGIN = BIT(0), /* The rays have the same origin */ S3D_RAYS_SINGLE_DIRECTION = BIT(1), /* The rays have the same direction */ - S3D_RAYS_SINGLE_RANGE = BIT(2) /* The rays have the same range */ + S3D_RAYS_SINGLE_RANGE = BIT(2), /* The rays have the same range */ + S3D_RAYS_SINGLE_DATA = BIT(3) /* The rays shared the same user defined data */ }; /* Attributes of a shape */ @@ -177,7 +178,8 @@ typedef int (const struct s3d_hit* hit, const float ray_org[3], const float ray_dir[3], - void* user_data); + void* ray_data, /* User data submitted on trace ray(s) invocation */ + void* filter_data); /* Data defined on the setup of the filter function */ /* Forward declaration of s3d opaque data types */ struct s3d_device; /* Entry point of the library */ @@ -292,6 +294,7 @@ s3d_scene_trace_ray const float origin[3], /* Ray origin */ const float direction[3], /* Ray direction. Must be normalized */ const float range[2], /* In [0, INF)^2 */ + void* ray_data, /* User ray data sent to the hit filter func. May be NULL */ struct s3d_hit* hit); /* Trace a bundle of rays into `scn' and return the closest intersection along @@ -308,6 +311,8 @@ s3d_scene_trace_rays const float* origins, /* List of 3D ray origins */ const float* directions, /* List of 3D ray directions */ const float* ranges, /* List of 2D ray ranges. in [0, INF)^2 */ + void* rays_data, /* User ray data sent to the hit filter func. May be NULL */ + const size_t sizeof_ray_data, /* Size in Bytes of *one* ray data */ struct s3d_hit* hits); /* Uniformly sample the scene and returned the sampled primitive and its sample diff --git a/src/s3d_scene.c b/src/s3d_scene.c @@ -47,6 +47,7 @@ struct ray_extended : public RTCRay { struct s3d_scene* scene; + void* data; /* User defined data */ }; /******************************************************************************* @@ -133,10 +134,11 @@ filter_wrapper(void* user_ptr, RTCRay& ray) { struct s3d_hit hit; struct hit_filter* filter = (struct hit_filter*)user_ptr; - struct ray_extended* r = static_cast<struct ray_extended*>(&ray); + struct ray_extended* ray_ex = static_cast<struct ray_extended*>(&ray); - hit_setup(r->scene, &ray, &hit); - if(filter->func(&hit, ray.org, ray.dir, filter->data)) { /* Discard the hit */ + hit_setup(ray_ex->scene, &ray, &hit); + if(filter->func(&hit, ray_ex->org, ray_ex->dir, ray_ex->data, filter->data)) { + /* Discard the intersection */ ray.geomID = RTC_INVALID_GEOMETRY_ID; } } @@ -884,9 +886,10 @@ s3d_scene_trace_ray const float org[3], const float dir[3], const float range[2], + void* ray_data, struct s3d_hit* hit) { - struct ray_extended ray; + struct ray_extended ray_ex; if(!scn || !org || !dir || !range || !hit) return RES_BAD_ARG; if(!f3_is_normalized(dir)) @@ -898,20 +901,22 @@ s3d_scene_trace_ray return RES_OK; } - f3_set(ray.org, org); - f3_set(ray.dir, dir); - ray.tnear = range[0]; - ray.tfar = range[1]; - ray.geomID = RTC_INVALID_GEOMETRY_ID; - ray.primID = RTC_INVALID_GEOMETRY_ID; - ray.instID = RTC_INVALID_GEOMETRY_ID; - ray.mask = 0xFFFFFFFF; - ray.time = 0.f; - ray.scene = scn; + f3_set(ray_ex.org, org); + f3_set(ray_ex.dir, dir); + ray_ex.tnear = range[0]; + ray_ex.tfar = range[1]; + ray_ex.geomID = RTC_INVALID_GEOMETRY_ID; + ray_ex.primID = RTC_INVALID_GEOMETRY_ID; + ray_ex.instID = RTC_INVALID_GEOMETRY_ID; + ray_ex.mask = 0xFFFFFFFF; + ray_ex.time = 0.f; + ray_ex.scene = scn; + ray_ex.data = ray_data; - rtcIntersect(scn->rtc_scn, ray); + rtcIntersect(scn->rtc_scn, ray_ex); + + hit_setup(scn, &ray_ex, hit); - hit_setup(scn, &ray, hit); return RES_OK; } @@ -923,11 +928,13 @@ s3d_scene_trace_rays const float* origins, const float* directions, const float* ranges, + void* rays_data, + const size_t sizeof_ray_data, struct s3d_hit* hits) { size_t iray; - size_t iorg, idir, irange; - size_t org_step, dir_step, range_step; + size_t iorg, idir, irange, idata; + size_t org_step, dir_step, range_step, data_step; res_T res = RES_OK; if(!scn) return RES_BAD_ARG; @@ -936,15 +943,17 @@ s3d_scene_trace_rays org_step = mask & S3D_RAYS_SINGLE_ORIGIN ? 0 : 3; dir_step = mask & S3D_RAYS_SINGLE_DIRECTION ? 0 : 3; range_step = mask & S3D_RAYS_SINGLE_RANGE ? 0 : 2; - iorg = idir = irange = 0; + data_step = mask & S3D_RAYS_SINGLE_DATA ? 0 : sizeof_ray_data; + iorg = idir = irange = idata = 0; FOR_EACH(iray, 0, nrays) { - res = s3d_scene_trace_ray - (scn, origins+iorg, directions+idir, ranges+irange, hits+iray); + res = s3d_scene_trace_ray(scn, origins+iorg, directions+idir, + ranges+irange, (char*)rays_data+idata, hits+iray); if(UNLIKELY(res != RES_OK)) break; iorg += org_step; idir += dir_step; irange += range_step; + idata += data_step; } return res; } diff --git a/src/test_s3d_shape.c b/src/test_s3d_shape.c @@ -42,9 +42,10 @@ filter_none (const struct s3d_hit* hit, const float org[3], const float dir[3], - void* data) + void* ray_data, + void* filter_data) { - (void)hit, (void)org, (void)dir, (void)data; + (void)hit, (void)org, (void)dir, (void)ray_data, (void)filter_data; return 0; } diff --git a/src/test_s3d_trace_ray.c b/src/test_s3d_trace_ray.c @@ -88,12 +88,14 @@ filter_func (const struct s3d_hit* hit, const float pos[3], const float dir[3], - void* data) + void* ray_data, + void* filter_data) { NCHECK(hit, NULL); NCHECK(pos, NULL); NCHECK(dir, NULL); - CHECK((uintptr_t)data, 0xDECAFBAD); + CHECK((uintptr_t)ray_data, 0xDEADBEEF); + CHECK((uintptr_t)filter_data, 0xDECAFBAD); CHECK(S3D_HIT_NONE(hit), 0); return hit->prim.prim_id % 2 == 0; } @@ -166,45 +168,45 @@ main(int argc, char** argv) CHECK(s3d_shape_ref_put(walls), RES_OK); CHECK(s3d_scene_begin_session(scn, S3D_TRACE), RES_OK); - CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, NULL, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, NULL, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, NULL, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, NULL, dir, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, dir, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, dir, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, dir, NULL, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, NULL, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, NULL, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, NULL, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, NULL, dir, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, dir, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, dir, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, dir, range, NULL), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, NULL, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, NULL, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, NULL, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, NULL, dir, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, dir, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, dir, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, dir, NULL, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, range, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, NULL, range, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, NULL, range, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, NULL, range, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, NULL, dir, range, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, NULL, dir, range, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(NULL, org, dir, range, &hit), RES_BAD_ARG); - CHECK(s3d_scene_trace_ray(scn, org, dir, range, &hit), RES_OK); - CHECK(s3d_scene_trace_ray(scn, org, dir, range, &hit), RES_OK); + CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, NULL, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, NULL, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, NULL, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, NULL, dir, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, dir, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, dir, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, dir, NULL, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, NULL, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, NULL, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, NULL, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, NULL, dir, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, dir, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, dir, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, dir, range, NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, NULL, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, NULL, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, NULL, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, NULL, dir, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, dir, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, dir, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, dir, NULL, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, NULL, NULL, range, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, NULL, range, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, NULL, range, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, NULL, range, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, NULL, dir, range, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, NULL, dir, range, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(NULL, org, dir, range, NULL, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK); + CHECK(s3d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_OK); f3(dir, 1.f, 1.f, 1.f); - CHECK(s3d_scene_trace_ray(scn, org, dir, range, &hit), RES_BAD_ARG); + CHECK(s3d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_BAD_ARG); CHECK(s3d_scene_end_session(scn), RES_OK); f3(dir, 0.f, 1.f, 0.f); - CHECK(s3d_scene_trace_ray(scn, org, dir, range, &hit), RES_BAD_OP); + CHECK(s3d_scene_trace_ray(scn, org, dir, range, NULL, &hit), RES_BAD_OP); CHECK(s3d_scene_clear(scn), RES_OK); /* Update the inst with the CBox tall block mesh */ @@ -323,7 +325,8 @@ main(int argc, char** argv) pixel[0] = (float)ix/(float)IMG_WIDTH; camera_ray(&cam, pixel, org, dir); - CHECK(s3d_scene_trace_ray(scn2, org, dir, range, &hit), RES_OK); + CHECK(s3d_scene_trace_ray + (scn2, org, dir, range, (void*)0xDEADBEEF, &hit), RES_OK); if(S3D_HIT_NONE(&hit)) { if(img) {