commit f599633b14950ea4679099d9695e9b056ac05662
parent a7d2697f8a9e40cd7d42332594bd6cc261b2508e
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 29 Jun 2016 15:51:30 +0200
Implement the s2d_scene_trace_ray_3d function
Diffstat:
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/src/s2d.h b/src/s2d.h
@@ -145,7 +145,7 @@ typedef int
(*s2d_hit_filter_function_T)
(const struct s2d_hit* hit,
const float ray_org[2],
- const float ray_dir[2],
+ const float ray_dir[],
void* ray_data, /* User data submitted on trace ray(s) invocation */
void* filter_data); /* Data defined on the setup of the filter function */
@@ -255,6 +255,23 @@ s2d_scene_trace_ray
void* ray_data, /* User ray data sent to the hit filter func. May be NULL */
struct s2d_hit* hit);
+/* Trace a 3D ray into `scn' and return the closest intersection. The third
+ * dimension of the scene primitives is assumed to be infinite, i.e. the
+ * contours are extruded to the infinity in Z. The ray is defined by `origin' +
+ * t*`direction' = 0 with t in [`range[0]', `range[1]'). The ray range as well
+ * as the potential hit distance are expressed with respect to the 3D
+ * direction. Note that if range is degenerated (i.e. `range[0]' >=
+ * `range[1]') then the ray is not traced and `hit' is set to S2D_HIT_NULL. Can
+ * be called only if an S2D_TRACE session is active on `scn'. */
+S2D_API res_T
+s2d_scene_trace_ray_3d
+ (struct s2d_scene* scn,
+ const float origin[3],
+ const float dir[3],
+ const float range[2],
+ void* ray_data,
+ struct s2d_hit* hit);
+
/* Uniformly sample the scene and returned the sampled primitive and its sample
* s position. Can be called only if a S2D_SAMPLE session is active on `scn'*/
S2D_API res_T
diff --git a/src/s2d_scene.c b/src/s2d_scene.c
@@ -795,6 +795,43 @@ s2d_scene_trace_ray
}
res_T
+s2d_scene_trance_ray_3d
+ (struct s2d_scene* scn,
+ const float org[3],
+ const float dir[3],
+ const float range[2],
+ void* ray_data,
+ struct s2d_hit* hit)
+{
+ float range_2d[2];
+ float dir_2d[3] = {0.f, 0.f, 0.f};
+ float dot;
+ res_T res = RES_OK;
+
+ if(!f3_is_normalized(dir)) {
+ log_error(scn->dev,
+ "%s: The ray direction should be normalized.\n", __FUNCTION__);
+ return RES_BAD_ARG;
+ }
+ if((dir[0] == 0.f && dir[1] == 0.f) || range[0] > range[1]) {
+ *hit = S2D_HIT_NULL;
+ return RES_OK;
+ }
+
+ f2_normalize(dir_2d, dir);
+ dot = f3_dot(dir_2d, dir); /* Cosine between dir and dir_2d */
+ range_2d[0] = dot*range[0];
+ range_2d[1] = dot*range[1];
+
+ res = s2d_scene_trace_ray(scn, org, dir_2d, range_2d, ray_data, hit);
+ if(res != RES_OK) return res;
+
+ if(!S2D_HIT_NONE(hit))
+ hit->distance = hit->distance / dot;
+ return RES_OK;
+}
+
+res_T
s2d_scene_sample
(struct s2d_scene* scn,
const float u,