commit 82b96559fd42a829dcf533ed97ed3789381b83cd
parent a228b87cb2b36d22c88cdbf45f9424c565ec5032
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 17 Oct 2018 17:41:58 +0200
Add support of "infinite ground" in X and Y
Diffstat:
5 files changed, 95 insertions(+), 27 deletions(-)
diff --git a/src/htrdr.c b/src/htrdr.c
@@ -372,7 +372,8 @@ htrdr_init
goto error;
}
- res = htrdr_ground_create(htrdr, args->filename_obj, 0, &htrdr->ground);
+ res = htrdr_ground_create
+ (htrdr, args->filename_obj, args->repeat_ground, &htrdr->ground);
if(res != RES_OK) goto error;
proj_ratio =
diff --git a/src/htrdr_args.c b/src/htrdr_args.c
@@ -38,22 +38,24 @@ print_help(const char* cmd)
printf(
" -C <camera> define the rendering point of view.\n");
printf(
-" -d dump octree data to OUTPUT wrt the VTK ASCII file format.\n");
- printf(
" -D AZIMUTH,ELEVATION\n"
" sun direction in degrees. Following the right-handed\n"
" convention, the azimuthal rotation is counter-clockwise\n"
" around the Z axis, with 0 aligned on the X axis. The\n"
" elevation rotation starts from 0 up to 90 at zenith.\n");
printf(
+" -d dump octree data to OUTPUT wrt the VTK ASCII file format.\n");
+ printf(
" -f overwrite the OUTPUT file if it already exists.\n");
printf(
-" -g FILENAME path of the OBJ geometry file.\n");
+" -g FILENAME path of an OBJ file representing the ground geometry.\n");
printf(
" -h display this help and exit.\n");
printf(
" -i <image> define the image to compute.\n");
printf(
+" -R infinitely repeat the ground along the X and Y axis.\n");
+ printf(
" -r infinitely repeat the clouds along the X and Y axis.\n");
printf(
" -m FILENAME path of the Mie data file.\n");
@@ -61,13 +63,13 @@ print_help(const char* cmd)
" -o OUTPUT file where data are written. If not defined, data are\n"
" written to standard output.\n");
printf(
-" -t THREADS hint on the number of threads to use. By default use as\n"
-" many threads as CPU cores.\n");
- printf(
" -T THRESHOLD optical thickness used as threshold during the octree\n"
" building. By default its value is `%g'.\n",
HTRDR_ARGS_DEFAULT.optical_thickness);
printf(
+" -t THREADS hint on the number of threads to use. By default use as\n"
+" many threads as CPU cores.\n");
+ printf(
" -v make the program more verbose.\n");
printf("\n");
printf(
@@ -318,7 +320,7 @@ htrdr_args_init(struct htrdr_args* args, int argc, char** argv)
*args = HTRDR_ARGS_DEFAULT;
- while((opt = getopt(argc, argv, "a:C:c:D:dfg:hi:m:o:rT:t:v")) != -1) {
+ while((opt = getopt(argc, argv, "a:C:c:D:dfg:hi:m:o:RrT:t:v")) != -1) {
switch(opt) {
case 'a': args->filename_gas = optarg; break;
case 'C':
@@ -342,6 +344,7 @@ htrdr_args_init(struct htrdr_args* args, int argc, char** argv)
case 'm': args->filename_mie = optarg; break;
case 'o': args->output = optarg; break;
case 'r': args->repeat_clouds = 1; break;
+ case 'R': args->repeat_ground = 1; break;
case 'T':
res = cstr_to_double(optarg, &args->optical_thickness);
if(res == RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG;
diff --git a/src/htrdr_args.h b/src/htrdr_args.h
@@ -52,7 +52,8 @@ struct htrdr_args {
int force_overwriting;
int dump_vtk; /* Dump the loaded cloud properties in a VTK file */
int verbose; /* Verbosity level */
- int repeat_clouds; /* Make clouds infinite in X and Y */
+ int repeat_clouds; /* Make the clouds infinite in X and Y */
+ int repeat_ground; /* Make the ground infinite in X and Y */
int quit; /* Quit the application */
};
@@ -84,6 +85,7 @@ struct htrdr_args {
0, /* dump VTK */ \
0, /* Verbose flag */ \
0, /* Repeat clouds */ \
+ 0, /* Repeat ground */ \
0 /* Quit the application */ \
}
static const struct htrdr_args HTRDR_ARGS_DEFAULT = HTRDR_ARGS_DEFAULT__;
diff --git a/src/htrdr_ground.c b/src/htrdr_ground.c
@@ -15,8 +15,11 @@
#include "htrdr.h"
#include "htrdr_ground.h"
+#include "htrdr_slab.h"
#include <rsys/cstr.h>
+#include <rsys/double2.h>
+#include <rsys/double3.h>
#include <rsys/float2.h>
#include <rsys/float3.h>
@@ -26,9 +29,18 @@
struct ray_context {
float range[2];
struct s3d_hit hit_prev;
+ int id[2];
};
-static const struct ray_context RAY_CONTEXT_NULL = {
- {0, INF}, S3D_HIT_NULL__
+#define RAY_CONTEXT_NULL__ {{0,INF}, S3D_HIT_NULL__, {0,0}}
+static const struct ray_context RAY_CONTEXT_NULL = RAY_CONTEXT_NULL__;
+
+struct trace_ground_context {
+ struct s3d_scene_view* view;
+ struct ray_context context;
+ struct s3d_hit* hit;
+};
+static const struct trace_ground_context TRACE_GROUND_CONTEXT_NULL = {
+ NULL, RAY_CONTEXT_NULL__, NULL
};
struct htrdr_ground {
@@ -87,6 +99,33 @@ ground_filter
|| hit->distance >= ray_ctx->range[1];
}
+static INLINE res_T
+trace_ground
+ (const double org[3],
+ const double dir[3],
+ const double range[2],
+ void* context,
+ int* hit)
+{
+ struct trace_ground_context* ctx = context;
+ float ray_org[3];
+ float ray_dir[3];
+ float ray_range[2];
+ res_T res = RES_OK;
+ ASSERT(org && dir && range && context && hit);
+
+ f3_set_d3(ray_org, org);
+ f3_set_d3(ray_dir, dir);
+ f2_set_d2(ray_range, range);
+
+ res = s3d_scene_view_trace_ray
+ (ctx->view, ray_org, ray_dir, ray_range, &ctx->context, ctx->hit);
+ if(res != RES_OK) return res;
+
+ *hit = !S3D_HIT_NONE(ctx->hit);
+ return RES_OK;
+}
+
static void
release_ground(ref_T* ref)
{
@@ -223,24 +262,44 @@ htrdr_ground_trace_ray
const struct s3d_hit* prev_hit,
struct s3d_hit* hit)
{
- struct ray_context ctx = RAY_CONTEXT_NULL;
- float ray_org[3];
- float ray_dir[3];
res_T res = RES_OK;
ASSERT(ground && org && dir && range && hit);
- f3_set_d3(ray_org, org);
- f3_set_d3(ray_dir, dir);
- f2_set_d2(ctx.range, range);
- ctx.hit_prev = prev_hit ? *prev_hit : S3D_HIT_NULL;
+ if(!ground->repeat) {
+ struct ray_context ray_ctx = RAY_CONTEXT_NULL;
+ float ray_org[3];
+ float ray_dir[3];
- res = s3d_scene_view_trace_ray
- (ground->view, ray_org, ray_dir, ctx.range, &ctx, hit);
- if(res != RES_OK) {
- htrdr_log_err(ground->htrdr,
- "%s: could not trace the ray against the ground geometry -- %s.\n",
- FUNC_NAME, res_to_cstr(res));
- goto error;
+ f3_set_d3(ray_org, org);
+ f3_set_d3(ray_dir, dir);
+ f2_set_d2(ray_ctx.range, range);
+ ray_ctx.hit_prev = prev_hit ? *prev_hit : S3D_HIT_NULL;
+
+ res = s3d_scene_view_trace_ray
+ (ground->view, ray_org, ray_dir, ray_ctx.range, &ray_ctx, hit);
+ if(res != RES_OK) {
+ htrdr_log_err(ground->htrdr,
+ "%s: could not trace the ray against the ground geometry -- %s.\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
+ } else {
+ struct trace_ground_context slab_ctx = TRACE_GROUND_CONTEXT_NULL;
+ double low[3], upp[3];
+
+ *hit = S3D_HIT_NULL;
+ slab_ctx.view = ground->view;
+ slab_ctx.context.range[0] = (float)range[0];
+ slab_ctx.context.range[1] = (float)range[1];
+ slab_ctx.context.hit_prev = prev_hit ? *prev_hit : S3D_HIT_NULL;
+ slab_ctx.hit = hit;
+
+ d3_set_f3(low, ground->lower);
+ d3_set_f3(upp, ground->upper);
+
+ res = htrdr_slab_trace_ray(ground->htrdr, org, dir, range, low, upp,
+ trace_ground, &slab_ctx);
+ if(res != RES_OK) goto error;
}
exit:
diff --git a/src/htrdr_sky.c b/src/htrdr_sky.c
@@ -257,11 +257,14 @@ trace_cloud
{
struct trace_cloud_context* ctx = context;
res_T res = RES_OK;
- ASSERT(org && dir && range && context && hit && ctx->hit);
+ ASSERT(org && dir && range && context && hit);
+
res = svx_tree_trace_ray(ctx->clouds, org, dir, range, ctx->challenge,
ctx->filter, ctx->context, ctx->hit);
+ if(res != RES_OK) return res;
+
*hit = !SVX_HIT_NONE(ctx->hit);
- return res;
+ return RES_OK;
}
static FINLINE float