commit 496e9c717254aff60263404becb78ce4e1b8ca1c
parent 1279c611af4b8bfc8a0b75d097c8f39e7d23fc9e
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 22 May 2026 14:21:15 +0200
Add the API function for finding the closest point
Like the ray-tracing function, it serves as an interface to the Star-3D
library used to partition the ground geometry.
Diffstat:
3 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/config.mk b/config.mk
@@ -1,4 +1,4 @@
-VERSION = 0.1.1
+VERSION = 0.2.0
PREFIX = /usr/local
LIB_TYPE = SHARED
diff --git a/src/rngrd.h b/src/rngrd.h
@@ -97,6 +97,23 @@ struct rngrd_trace_ray_args {
static const struct rngrd_trace_ray_args RNGRD_TRACE_RAY_ARGS_DEFAULT =
RNGRD_TRACE_RAY_ARGS_DEFAULT__;
+struct rngrd_closest_point_args {
+ double position[3];
+ double radius; /* Search radius around the position */
+
+ s3d_hit_filter_function_T filter; /* NULL <=> Return closest triangle */
+ void* filter_data; /* User data send to the filter function */
+};
+#define RNGRD_CLOSEST_POINT_ARGS_DEFAULT__ { \
+ {0,0,0}, /* Position */ \
+ DBL_MAX, /* Radius */ \
+ \
+ NULL, /* Filter function */ \
+ NULL /* Filter data */ \
+}
+static const struct rngrd_closest_point_args
+RNGRD_CLOSEST_POINT_ARGS_DEFAULT = RNGRD_CLOSEST_POINT_ARGS_DEFAULT__;
+
struct rngrd_create_bsdf_args {
struct s3d_primitive prim; /* Surface primitive to query */
double barycentric_coords[3]; /* Position into and relative to `prim' */
@@ -151,6 +168,12 @@ rngrd_trace_ray
struct s3d_hit* hit);
RNGRD_API res_T
+rngrd_closest_point
+ (const struct rngrd* ground,
+ struct rngrd_closest_point_args* args,
+ struct s3d_hit* hit);
+
+RNGRD_API res_T
rngrd_create_bsdf
(struct rngrd* ground,
const struct rngrd_create_bsdf_args* args,
diff --git a/src/rngrd_mesh.c b/src/rngrd_mesh.c
@@ -31,6 +31,14 @@
#include <rsys/float2.h>
#include <rsys/float3.h>
+struct filter_args {
+ struct s3d_hit hit;
+
+ s3d_hit_filter_function_T func; /* NULL <=> Stop RT at 1st hit triangle */
+ void* context; /* User data send to the filter function */
+};
+static const struct filter_args FILTER_ARGS_NULL = {S3D_HIT_NULL, NULL, NULL};
+
/*******************************************************************************
* Helper functions
******************************************************************************/
@@ -129,7 +137,7 @@ mesh_filter
void* ray_data,
void* filter_data)
{
- const struct rngrd_trace_ray_args* ray_args = ray_data;
+ const struct filter_args* filter = ray_data;
(void)filter_data;
/* Internally, Star-3D relies on Embree which, due to numerical imprecision,
@@ -138,18 +146,18 @@ mesh_filter
if(hit->distance <= ray_range[0] || hit->distance >= ray_range[1])
return 1;
- if(!ray_args) /* Nothing more to do */
+ if(!filter) /* Nothing more to do */
return 0;
/* Discard this intersection */
- if(self_hit(hit, ray_org, ray_dir, ray_range, &ray_args->hit_from))
+ if(self_hit(hit, ray_org, ray_dir, ray_range, &filter->hit))
return 1;
- if(!ray_args->filter) /* No user-defined filter functions */
+ if(!filter->func) /* No user-defined filter functions */
return 0;
- return ray_args->filter /* Invoke user-defined filtering */
- (hit, ray_org, ray_dir, ray_range, ray_args->filter_data, filter_data);
+ return filter->func /* Invoke user-defined filtering */
+ (hit, ray_org, ray_dir, ray_range, filter->context, filter_data);
}
static void
@@ -269,6 +277,7 @@ rngrd_trace_ray
struct rngrd_trace_ray_args* args,
struct s3d_hit* hit)
{
+ struct filter_args filter = FILTER_ARGS_NULL;
float org[3];
float dir[3];
float range[2];
@@ -283,9 +292,13 @@ rngrd_trace_ray
f3_set_d3(dir, args->ray_dir);
f2_set_d2(range, args->ray_range);
+ filter.hit = args->hit_from;
+ filter.func = args->filter;
+ filter.context = args->filter_data;
+
*hit = S3D_HIT_NULL;
- res = s3d_scene_view_trace_ray(ground->s3d_view, org, dir, range, args, hit);
+ res = s3d_scene_view_trace_ray(ground->s3d_view, org, dir, range, &filter, hit);
if(res != RES_OK) {
log_err(ground,
"%s: error tracing ray "
@@ -300,6 +313,44 @@ error:
goto exit;
}
+res_T
+rngrd_closest_point
+ (const struct rngrd* ground,
+ struct rngrd_closest_point_args* args,
+ struct s3d_hit* hit)
+{
+ struct filter_args filter = FILTER_ARGS_NULL;
+ float pos[3];
+ float radius;
+ res_T res = RES_OK;
+
+ if(!ground || !args || !hit) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ f3_set_d3(pos, args->position);
+ radius = (float)args->radius;
+ filter.func = args->filter;
+ filter.context = args->filter_data;
+
+ *hit = S3D_HIT_NULL;
+
+ res = s3d_scene_view_closest_point(ground->s3d_view, pos, radius, &filter, hit);
+ if(res != RES_OK) {
+ log_err(ground,
+ "%s: error finding the closest point "
+ "(position = %g, %g, %g; radius = %g)\n",
+ FUNC_NAME, SPLIT3(pos), radius);
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
* Local function
******************************************************************************/