star-2d

Contour structuring for efficient 2D geometric queries
git clone git://git.meso-star.fr/star-2d.git
Log | Files | Refs | README | LICENSE

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:
Msrc/s2d.h | 19++++++++++++++++++-
Msrc/s2d_scene.c | 37+++++++++++++++++++++++++++++++++++++
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,