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