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 51546e35d5eec090a3474b1baea4f5dc939a52ed
parent a17ed8ec0a67bc3cf490968200665d6377ca1c42
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 26 May 2015 09:03:35 +0200

Add the s3d_scene_trace_rays and s3d_scene_is_traced functions

Diffstat:
Mcmake/CMakeLists.txt | 2+-
Msrc/s3d.h | 28++++++++++++++++++++++++++++
Msrc/s3d_scene.c | 43+++++++++++++++++++++++++++++++++++++++++++
Msrc/test_s3d_scene.c | 13+++++++++++++
4 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -57,7 +57,7 @@ rcmake_append_runtime_dirs(_runtime_dirs RSys Embree) # Configure and define targets ################################################################################ set(VERSION_MAJOR 0) -set(VERSION_MINOR 0) +set(VERSION_MINOR 1) set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) diff --git a/src/s3d.h b/src/s3d.h @@ -58,6 +58,12 @@ * functor to S3D_KEEP means that this vertex data will not be updated */ #define S3D_KEEP NULL +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 */ +}; + /* Attributes of a shape */ enum s3d_attrib_usage { S3D_POSITION, /* World space position */ @@ -228,6 +234,12 @@ S3D_API res_T s3d_scene_end_trace (struct s3d_scene* scn); +/* Define if the begin scene is currently invoked on `scn' */ +S3D_API res_T +s3d_scene_is_traceable + (struct s3d_scene* scn, + char* is_traceable); + /* Trace a ray into the `scn' and return the closest intersection. The ray is * defined by `origin' + t*`direction' = 0 with t in [`range[0]', `range[1]'). * Note that if range is degenerated (i.e. `range[0]' >= `range[1]') then the @@ -241,6 +253,22 @@ s3d_scene_trace_ray const float range[2], /* In [0, INF)^2 */ struct s3d_hit* hit); +/* Trace a bundle of rays into `scn' and return the closest intersection along + * them. The rays are defined by `origin' + t*`direction' = 0 with t in + * [`range[0]', `range[1]'). Note that if a range is degenerated (i.e. + * `range[0]' >= `range[1]') then its associated ray is not traced and `hit' is + * set to S3D_HIT_NULL. This function can be called only if a + * s3d_scene_begin_trace operation is active on `scn' */ +S3D_API res_T +s3d_scene_trace_rays + (struct s3d_scene* scn, + const size_t nrays, /* # rays */ + const int mask, /* Combination of s3d_ray_flag */ + 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 */ + struct s3d_hit* hits); + /******************************************************************************* * Shape API - A shape defines a geometry that can be attached to *one* scene. ******************************************************************************/ diff --git a/src/s3d_scene.c b/src/s3d_scene.c @@ -579,6 +579,15 @@ s3d_scene_end_trace(struct s3d_scene* scn) } res_T +s3d_scene_is_traceable(struct s3d_scene* scn, char* is_traceable) +{ + if(!scn || !is_traceable) + return RES_BAD_ARG; + *is_traceable = scn->build_type != BUILD_NONE; + return RES_OK; +} + +res_T s3d_scene_trace_ray (struct s3d_scene* scn, const float org[3], @@ -651,3 +660,37 @@ s3d_scene_trace_ray return RES_OK; } +res_T +s3d_scene_trace_rays + (struct s3d_scene* scn, + const size_t nrays, + const int mask, + const float* origins, + const float* directions, + const float* ranges, + struct s3d_hit* hits) +{ + size_t iray; + size_t iorg, idir, irange; + size_t org_step, dir_step, range_step; + res_T res = RES_OK; + + if(!scn) return RES_BAD_ARG; + if(!nrays) return RES_OK; + + 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; + + FOR_EACH(iray, 0, nrays) { + res = s3d_scene_trace_ray + (scn, origins+iorg, directions+idir, ranges+irange, hits+iray); + if(UNLIKELY(res != RES_OK)) break; + iorg += org_step; + idir += dir_step; + irange += range_step; + } + return res; +} + diff --git a/src/test_s3d_scene.c b/src/test_s3d_scene.c @@ -42,6 +42,7 @@ main(int argc, char** argv) struct s3d_shape* shapes[4]; const size_t nshapes = sizeof(shapes)/sizeof(struct s3d_shape*); size_t i; + char b; (void)argc, (void)argv; mem_init_proxy_allocator(&allocator, &mem_default_allocator); @@ -82,14 +83,26 @@ main(int argc, char** argv) CHECK(s3d_scene_clear(scn), RES_OK); CHECK(s3d_scene_instantiate(scn, shapes + 2), RES_OK); + CHECK(s3d_scene_is_traceable(NULL, NULL), RES_BAD_ARG); + CHECK(s3d_scene_is_traceable(scn, NULL), RES_BAD_ARG); + CHECK(s3d_scene_is_traceable(NULL, &b), RES_BAD_ARG); + CHECK(s3d_scene_is_traceable(scn, &b), RES_OK); + CHECK(b, 0); + CHECK(s3d_scene_begin_trace(NULL), RES_BAD_ARG); CHECK(s3d_scene_begin_trace(scn), RES_OK); CHECK(s3d_scene_begin_trace(scn), RES_BAD_OP); + CHECK(s3d_scene_is_traceable(scn, &b), RES_OK); + CHECK(b, 1); + CHECK(s3d_scene_end_trace(NULL), RES_BAD_ARG); CHECK(s3d_scene_end_trace(scn), RES_OK); CHECK(s3d_scene_end_trace(scn), RES_BAD_OP); + CHECK(s3d_scene_is_traceable(scn, &b), RES_OK); + CHECK(b, 0); + CHECK(s3d_shape_ref_put(shapes[0]), RES_OK); CHECK(s3d_shape_ref_put(shapes[1]), RES_OK); CHECK(s3d_shape_ref_put(shapes[2]), RES_OK);