commit bc9708e087d8219885676721c9a1ae2b9b695559
parent ca72a7c2c598c9abbb2221d7be00e036529a575a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 27 Sep 2022 11:11:53 +0200
Add the rnatm_trace_ray function
Diffstat:
| M | src/rnatm.h | | | 36 | ++++++++++++++++++++++++++++++++++-- |
| M | src/rnatm_octree.c | | | 81 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 115 insertions(+), 2 deletions(-)
diff --git a/src/rnatm.h b/src/rnatm.h
@@ -23,6 +23,7 @@
#include <star/s3d.h>
#include <star/suvm.h>
+#include <star/svx.h>
#include <rsys/rsys.h>
@@ -50,8 +51,6 @@
/* Forward declaration of external data types */
struct logger;
struct mem_allocator;
-struct suvm_primitive;
-struct svx_voxel;
enum rnatm_radcoef {
RNATM_RADCOEF_Ka, /* Absorption coefficient */
@@ -117,6 +116,33 @@ struct rnatm_cell_get_radcoef_args {
static const struct rnatm_cell_get_radcoef_args
RNATM_CELL_GET_RADCOEF_ARGS_NULL = RNATM_CELL_GET_RADCOEF_ARGS_NULL__;
+struct rnatm_trace_ray_args {
+ double ray_org[3]; /* Origin of the ray */
+ double ray_dir[3]; /* Direction of the ray */
+ double ray_range[2]; /* Range of the ray */
+
+ svx_hit_challenge_T challenge; /* NULL <=> Traversed up to the leaves */
+ svx_hit_filter_T filter; /* NULL <=> Stop RT at the 1st intersected voxel */
+ void* context; /* User data send to the 'challenge' & 'filter' function */
+
+ size_t iband; /* Index of the spectral band to consider */
+ size_t iquad; /* Index of the quadrature point to consider */
+};
+#define RNATM_TRACE_RAY_ARGS_NULL__ { \
+ {0,0,0}, /* Ray origin */ \
+ {0,0,0}, /* Ray direction */ \
+ {0,DBL_MAX}, /* Ray range */ \
+ \
+ NULL, /* Challenge functor */ \
+ NULL, /* Filter functor */ \
+ NULL, /* User defined data */ \
+ \
+ SIZE_MAX, /* Index of the spectral band */ \
+ SIZE_MAX /* Index of the quadrature point */ \
+}
+static const struct rnatm_trace_ray_args
+RNATM_TRACE_RAY_ARGS_NULL = RNATM_TRACE_RAY_ARGS_NULL__;
+
struct rnatm_create_args {
struct rnatm_gas_args gas;
struct rnatm_aerosol_args* aerosols;
@@ -220,6 +246,12 @@ rnatm_cell_get_radcoef
const struct rnatm_cell_get_radcoef_args* args,
double* k);
+RNATM_API res_T
+rnatm_trace_ray
+ (struct rnatm* rnatm,
+ const struct rnatm_trace_ray_args* args,
+ struct svx_hit* hit);
+
RNATM_API size_t
rnatm_get_aerosols_count
(const struct rnatm* atm);
diff --git a/src/rnatm_octree.c b/src/rnatm_octree.c
@@ -220,6 +220,23 @@ check_voxelize_args(const struct voxelize_args* args)
return RES_OK;
}
+static INLINE res_T
+check_trace_ray_args
+ (const struct rnatm* atm,
+ const struct rnatm_trace_ray_args* args)
+{
+ size_t n;
+ if(!args) return RES_BAD_ARG;
+
+ /* Invalid band index */
+ n = darray_band_size_get(&atm->bands) - 1;
+ if(args->iband < darray_band_cdata_get(&atm->bands)[0].index
+ || args->iband > darray_band_cdata_get(&atm->bands)[n].index)
+ return RES_BAD_ARG;
+
+ return RES_OK;
+}
+
static void
build_sync_release(struct build_sync* sync)
{
@@ -1335,6 +1352,70 @@ error:
}
/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+rnatm_trace_ray
+ (struct rnatm* atm,
+ const struct rnatm_trace_ray_args* args,
+ struct svx_hit* hit)
+{
+ const struct accel_struct* accel_struct = NULL;
+ size_t i;
+ res_T res = RES_OK;
+
+ if(atm || !hit) { res = RES_BAD_ARG; goto error; }
+ res = check_trace_ray_args(atm, args);
+ if(res != RES_OK) goto error;
+
+ /* Start calculating the id of the acceleration structure to consider */
+ i = args->iband - darray_band_cdata_get(&atm->bands)[0].index;
+ ASSERT(i < darray_band_size_get(&atm->bands));
+ ASSERT(args->iband == darray_band_cdata_get(&atm->bands)[i].index);
+
+ /* Invalid quadrature point index */
+ if(args->iquad >= darray_band_cdata_get(&atm->bands)[i].nquad_pts)
+ return RES_BAD_ARG;
+
+ /* Finalize the calculation of the id of the acceleration structure */
+ i += args->iquad;
+
+ /* Retrieve the acceleration structure */
+ ASSERT(i < darray_accel_struct_size_get(&atm->accel_structs));
+ accel_struct = darray_accel_struct_cdata_get(&atm->accel_structs) + i;
+ ASSERT(args->iband == accel_struct->iband);
+ ASSERT(args->iquad == accel_struct->iquad_pt);
+
+ res = make_sure_octree_is_loaded(atm, i);
+ if(res != RES_OK) goto error;
+
+ *hit = SVX_HIT_NULL;
+
+ res = svx_tree_trace_ray
+ (accel_struct->octree,
+ args->ray_org,
+ args->ray_dir,
+ args->ray_range,
+ args->challenge,
+ args->filter,
+ args->context,
+ hit);
+ if(res != RES_OK) {
+ log_err(atm,
+ "%s: error tracing ray "
+ "(origin = %g, %g, %g; direction %g, %g, %g; range = %g, %g) -- %s\n",
+ FUNC_NAME, SPLIT3(args->ray_org), SPLIT3(args->ray_dir),
+ SPLIT2(args->ray_range), res_to_cstr(res));
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+/*******************************************************************************
* Local functions
******************************************************************************/
res_T