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:
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) {