commit 4a1dbab2e0dffebcacdefb996752a03abe449d94
parent 93aee2c1a7f3cd9065265ba831c0aaf83037abdf
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 27 Aug 2021 09:09:11 +0200
Merge branch 'feature_camera_orthographic' into develop
Diffstat:
16 files changed, 469 insertions(+), 167 deletions(-)
diff --git a/cmake/combustion/CMakeLists.txt b/cmake/combustion/CMakeLists.txt
@@ -74,7 +74,6 @@ set(HTRDR_COMBUSTION_FILES_SRC
set(HTRDR_COMBUSTION_FILES_INC
htrdr_combustion.h
htrdr_combustion_c.h
- htrdr_combustion_args.h
htrdr_combustion_geometry_ray_filter.h
htrdr_combustion_laser.h)
diff --git a/cmake/core/CMakeLists.txt b/cmake/core/CMakeLists.txt
@@ -55,14 +55,15 @@ include_directories(
################################################################################
# Generate files
################################################################################
-set(HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN "0.0" CACHE INTERNAL "")
-set(HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX "180.0" CACHE INTERNAL "")
+set(HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN "0.0" CACHE INTERNAL "")
+set(HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX "180.0" CACHE INTERNAL "")
set(HTRDR_ARGS_DEFAULT_CAMERA_POS "0,0,0" CACHE INTERNAL "")
set(HTRDR_ARGS_DEFAULT_CAMERA_TGT "0,1,0" CACHE INTERNAL "")
set(HTRDR_ARGS_DEFAULT_CAMERA_UP "0,0,1" CACHE INTERNAL "")
-set(HTRDR_ARGS_DEFAULT_CAMERA_FOV "70" CACHE INTERNAL "")
-set(HTRDR_ARGS_DEFAULT_CAMERA_LENS_RADIUS "0" CACHE INTERNAL "")
-set(HTRDR_ARGS_DEFAULT_CAMERA_FOCAL_DST "1" CACHE INTERNAL "")
+set(HTRDR_ARGS_DEFAULT_CAMERA_ORTHOGRAPHIC_HEIGHT "1" CACHE INTERNAL "")
+set(HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOV "70" CACHE INTERNAL "")
+set(HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_LENS_RADIUS "0" CACHE INTERNAL "")
+set(HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST "1" CACHE INTERNAL "")
set(HTRDR_ARGS_DEFAULT_RECTANGLE_POS "0,0,0" CACHE INTERNAL "")
set(HTRDR_ARGS_DEFAULT_RECTANGLE_TGT "0,0,1" CACHE INTERNAL "")
set(HTRDR_ARGS_DEFAULT_RECTANGLE_UP "0,1,0" CACHE INTERNAL "")
diff --git a/doc/htrdr-atmosphere.1.txt.in b/doc/htrdr-atmosphere.1.txt.in
@@ -101,12 +101,12 @@ OPTIONS
are taken into account.
*-C* <__camera-parameter__:...>::
- Define the camera. Available parameters are:
+ Define a perspective camera. Available parameters are:
**focal-dst**=**_dst_**;;
Distance to focus on with a thin lens camera, that is, a camera whose
*lens-radius* is not zero. The default focal distance is
- @HTRDR_ARGS_DEFAULT_CAMERA_FOCAL_DST@ meter.
+ @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST@ meter.
**focal-length**=**_length_**;;
Focal length of a camera lens. It is another way to control the field of
@@ -115,14 +115,15 @@ OPTIONS
**fov**=**_angle_**;;
Vertical field of view of the camera in
- ]@HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN@,
- @HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX@[ degrees. By default _angle_ is set to
- @HTRDR_ARGS_DEFAULT_CAMERA_FOV@ degrees.
+ ]@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN@,
+ @HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX@[ degrees. By
+ default _angle_ is set to
+ @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOV@ degrees.
**lens-radius**=**_radius_**;;
Radius of the camera lens. A non-zero radius means that the camera is a
thin lens camera while a zero radius defines a pinhole camera. By default
- the lens radius is @HTRDR_ARGS_DEFAULT_CAMERA_LENS_RADIUS@.
+ the lens radius is @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_LENS_RADIUS@.
**pos**=**_x_**,**_y_**,**_z_**;;
Camera lens position. By default it is set to
@@ -212,6 +213,25 @@ OPTIONS
File where *htrdr-atmosphere* writes its _output_ data. If not defined, write
results to standard output.
+*-P* <__camera-parameter__:...>::
+ Define an orthographic camera. Available parameters are:
+
+ **height**=**_radius_**;;
+ Height of the image plane. By default it is set to
+ @HTRDR_ARGS_DEFAULT_CAMERA_ORTHOGRAPHIC_HEIGHT@.
+
+ **pos**=**_x_**,**_y_**,**_z_**;;
+ Camera lens position. By default it is set to
+ {@HTRDR_ARGS_DEFAULT_CAMERA_POS@}.
+
+ **tgt**=**_x_**,**_y_**,**_z_**;;
+ Position targeted by the camera. By default it is set to
+ {@HTRDR_ARGS_DEFAULT_CAMERA_TGT@}.
+
+ **up**=**_x_**,**_y_**,**_z_**;;
+ Up vector of the camera. By default it is set to
+ {@HTRDR_ARGS_DEFAULT_CAMERA_UP@}.
+
*-p* <__rectangle-parameter__:...>::
Switch in flux map computation. The flux is computed for the part of the
sensor that is outside any geometry. The rectangular sensor onto which the
diff --git a/doc/htrdr-combustion.1.txt.in b/doc/htrdr-combustion.1.txt.in
@@ -84,7 +84,7 @@ OPTIONS
**focal-dst**=**_dst_**;;
Distance to focus on with a thin lens camera, that is, a camera whose
*lens-radius* is not zero. The default focal distance is
- @HTRDR_ARGS_DEFAULT_CAMERA_FOCAL_DST@ meter.
+ @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST@ meter.
**focal-length**=**_length_**;;
Focal length of a camera lens. It is another way to control the field of
@@ -93,14 +93,15 @@ OPTIONS
**fov**=**_angle_**;;
Vertical field of view of the camera in
- ]@HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN@,
- @HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX@[ degrees. By default _angle_ is set to
- @HTRDR_ARGS_DEFAULT_CAMERA_FOV@ degrees.
+ ]@HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN@,
+ @HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX@[ degrees. By
+ default _angle_ is set to
+ @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOV@ degrees.
**lens-radius**=**_radius_**;;
Radius of the camera lens. A non-zero radius means that the camera is a
thin lens camera while a zero radius defines a pinhole camera. By default
- the lens radius is @HTRDR_ARGS_DEFAULT_CAMERA_LENS_RADIUS@.
+ the lens radius is @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_LENS_RADIUS@.
**pos**=**_x_**,**_y_**,**_z_**;;
Camera lens position. By default it is set to
@@ -229,6 +230,25 @@ OPTIONS
Path to the file where *htrdr-combustion* writes the output data. If not set,
data is written to standard output.
+*-P* <__camera-parameter__:...>::
+ Define an orthographic camera. Available parameters are:
+
+ **height**=**_radius_**;;
+ Height of the image plane. By default it is set to
+ @HTRDR_ARGS_DEFAULT_CAMERA_ORTHOGRAPHIC_HEIGHT@.
+
+ **pos**=**_x_**,**_y_**,**_z_**;;
+ Camera lens position. By default it is set to
+ {@HTRDR_ARGS_DEFAULT_CAMERA_POS@}.
+
+ **tgt**=**_x_**,**_y_**,**_z_**;;
+ Position targeted by the camera. By default it is set to
+ {@HTRDR_ARGS_DEFAULT_CAMERA_TGT@}.
+
+ **up**=**_x_**,**_y_**,**_z_**;;
+ Up vector of the camera. By default it is set to
+ {@HTRDR_ARGS_DEFAULT_CAMERA_UP@}.
+
*-p* _thermprops_::
Path to the *atrtp*(5) file that stores the thermodynamic properties of the
combustion medium.
diff --git a/src/atmosphere/htrdr_atmosphere.c b/src/atmosphere/htrdr_atmosphere.c
@@ -150,61 +150,118 @@ spherical_to_cartesian_dir
}
static res_T
-setup_sensor
+setup_camera_orthographic
+ (struct htrdr_atmosphere* cmd,
+ const struct htrdr_atmosphere_args* args)
+{
+ struct scam_orthographic_args cam_args = SCAM_ORTHOGRAPHIC_ARGS_DEFAULT;
+ ASSERT(cmd && args && args->image.definition[0] && args->image.definition[1]);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE);
+ ASSERT(args->cam_type == HTRDR_ARGS_CAMERA_ORTHOGRAPHIC);
+
+ d3_set(cam_args.position, args->cam_ortho.position);
+ d3_set(cam_args.target, args->cam_ortho.target);
+ d3_set(cam_args.up, args->cam_ortho.up);
+ cam_args.height = args->cam_ortho.height;
+ cam_args.aspect_ratio =
+ (double)args->image.definition[0]
+ / (double)args->image.definition[1];
+
+ return scam_create_orthographic
+ (htrdr_get_logger(cmd->htrdr),
+ htrdr_get_allocator(cmd->htrdr),
+ htrdr_get_verbosity_level(cmd->htrdr),
+ &cam_args,
+ &cmd->camera);
+}
+
+static res_T
+setup_camera_perspective
(struct htrdr_atmosphere* cmd,
const struct htrdr_atmosphere_args* args)
{
- double proj_ratio;
struct scam_perspective_args cam_args = SCAM_PERSPECTIVE_ARGS_DEFAULT;
+ ASSERT(cmd && args && args->image.definition[0] && args->image.definition[1]);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE);
+ ASSERT(args->cam_type == HTRDR_ARGS_CAMERA_PERSPECTIVE);
+
+ d3_set(cam_args.position, args->cam_persp.position);
+ d3_set(cam_args.target, args->cam_persp.target);
+ d3_set(cam_args.up, args->cam_persp.up);
+ cam_args.aspect_ratio =
+ (double)args->image.definition[0]
+ / (double)args->image.definition[1];
+ cam_args.field_of_view = MDEG2RAD(args->cam_persp.fov_y);
+ cam_args.lens_radius = args->cam_persp.lens_radius;
+ cam_args.focal_distance = args->cam_persp.focal_dst;
+
+ return scam_create_perspective
+ (htrdr_get_logger(cmd->htrdr),
+ htrdr_get_allocator(cmd->htrdr),
+ htrdr_get_verbosity_level(cmd->htrdr),
+ &cam_args,
+ &cmd->camera);
+}
+
+static res_T
+setup_camera
+ (struct htrdr_atmosphere* cmd,
+ const struct htrdr_atmosphere_args* args)
+{
res_T res = RES_OK;
- ASSERT(cmd && args);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE);
+ switch(args->cam_type) {
+ case HTRDR_ARGS_CAMERA_ORTHOGRAPHIC:
+ res = setup_camera_orthographic(cmd, args);
+ break;
+ case HTRDR_ARGS_CAMERA_PERSPECTIVE:
+ res = setup_camera_perspective(cmd, args);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ return res;
+}
- cmd->sensor.type = args->sensor_type;
+static res_T
+setup_flux_map
+ (struct htrdr_atmosphere* cmd,
+ const struct htrdr_atmosphere_args* args)
+{
+ ASSERT(cmd && args);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP);
- if(args->spectral.spectral_type == HTRDR_SPECTRAL_SW_CIE_XYZ
- && args->sensor_type != HTRDR_SENSOR_CAMERA) {
- htrdr_log_err(cmd->htrdr, "the CIE 1931 XYZ spectral integration can be used "
- "only with a camera sensor.\n");
- res = RES_BAD_ARG;
- goto error;
+ if(args->spectral.spectral_type == HTRDR_SPECTRAL_SW_CIE_XYZ) {
+ htrdr_log_err(cmd->htrdr,
+ "the CIE 1931 XYZ spectral integration can be used only with a camera"
+ "sensor.\n");
+ return RES_BAD_ARG;
}
- switch(args->sensor_type) {
- case HTRDR_SENSOR_CAMERA:
- proj_ratio =
- (double)args->image.definition[0]
- / (double)args->image.definition[1];
- d3_set(cam_args.position, args->sensor.camera.position);
- d3_set(cam_args.target, args->sensor.camera.target);
- d3_set(cam_args.up, args->sensor.camera.up);
- cam_args.aspect_ratio = proj_ratio;
- cam_args.field_of_view = MDEG2RAD(args->sensor.camera.fov_y);
- cam_args.lens_radius = args->sensor.camera.lens_radius;
- cam_args.focal_distance = args->sensor.camera.focal_dst;
- res = scam_create_perspective
- (htrdr_get_logger(cmd->htrdr),
- htrdr_get_allocator(cmd->htrdr),
- htrdr_get_verbosity_level(cmd->htrdr),
- &cam_args,
- &cmd->sensor.camera);
+ return htrdr_rectangle_create
+ (cmd->htrdr,
+ args->flux_map.size,
+ args->flux_map.position,
+ args->flux_map.target,
+ args->flux_map.up,
+ &cmd->flux_map);
+}
+
+static res_T
+setup_sensor
+ (struct htrdr_atmosphere* cmd,
+ const struct htrdr_atmosphere_args* args)
+{
+ res_T res = RES_OK;
+ switch(cmd->output_type) {
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP:
+ res = setup_flux_map(cmd, args);
break;
- case HTRDR_SENSOR_RECTANGLE:
- res = htrdr_rectangle_create
- (cmd->htrdr,
- args->sensor.rectangle.size,
- args->sensor.rectangle.position,
- args->sensor.rectangle.target,
- args->sensor.rectangle.up,
- &cmd->sensor.rectangle);
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE:
+ res = setup_camera(cmd, args);
break;
- default: FATAL("Unreachable code.\n"); break;
+ default: /* Nothing to do */ break;
}
- if(res != RES_OK) goto error;
-
-exit:
return res;
-error:
- goto exit;
}
static res_T
@@ -251,8 +308,8 @@ atmosphere_release(ref_T* ref)
if(cmd->sun) htrdr_atmosphere_sun_ref_put(cmd->sun);
if(cmd->cie) htrdr_cie_xyz_ref_put(cmd->cie);
if(cmd->ran_wlen) htrdr_ran_wlen_ref_put(cmd->ran_wlen);
- if(cmd->sensor.camera) SCAM(ref_put(cmd->sensor.camera));
- if(cmd->sensor.rectangle) htrdr_rectangle_ref_put(cmd->sensor.rectangle);
+ if(cmd->camera) SCAM(ref_put(cmd->camera));
+ if(cmd->flux_map) htrdr_rectangle_ref_put(cmd->flux_map);
if(cmd->buf) htrdr_buffer_ref_put(cmd->buf);
if(cmd->sky) HTSKY(ref_put(cmd->sky));
if(cmd->output && cmd->output != stdout) fclose(cmd->output);
@@ -290,8 +347,7 @@ htrdr_atmosphere_create
}
ref_init(&cmd->ref);
str_init(htrdr_get_allocator(htrdr), &cmd->output_name);
- cmd->dump_volumetric_acceleration_structure =
- args->dump_volumetric_acceleration_structure;
+ cmd->output_type = args->output_type;
cmd->verbose = args->verbose;
cmd->spp = args->image.spp;
cmd->width = args->image.definition[0];
@@ -398,7 +454,7 @@ htrdr_atmosphere_create
}
- if(!cmd->dump_volumetric_acceleration_structure) {
+ if(cmd->output_type != HTRDR_ATMOSPHERE_ARGS_OUTPUT_OCTREES) {
struct htrdr_pixel_format pixfmt = HTRDR_PIXEL_FORMAT_NULL;
atmosphere_get_pixel_format(cmd, &pixfmt);
@@ -446,19 +502,17 @@ res_T
htrdr_atmosphere_run(struct htrdr_atmosphere* cmd)
{
res_T res = RES_OK;
-
- if(cmd->dump_volumetric_acceleration_structure) {
- res = dump_volumetric_acceleration_structure(cmd);
- if(res != RES_OK) goto error;
- } else {
- res = atmosphere_draw_map(cmd);
- if(res != RES_OK) goto error;
+ switch(cmd->output_type) {
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE:
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP:
+ res = atmosphere_draw_map(cmd);
+ break;
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_OCTREES:
+ res = dump_volumetric_acceleration_structure(cmd);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
}
-
-exit:
return res;
-error:
- goto exit;
}
/*******************************************************************************
@@ -470,12 +524,12 @@ atmosphere_get_pixel_format
struct htrdr_pixel_format* fmt)
{
ASSERT(cmd && fmt);
- switch(cmd->sensor.type) {
- case HTRDR_SENSOR_RECTANGLE:
+ switch(cmd->output_type) {
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP:
fmt->size = sizeof(struct atmosphere_pixel_flux);
fmt->alignment = ALIGNOF(struct atmosphere_pixel_flux);
break;
- case HTRDR_SENSOR_CAMERA:
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE:
switch(cmd->spectral_type) {
case HTRDR_SPECTRAL_LW:
case HTRDR_SPECTRAL_SW:
diff --git a/src/atmosphere/htrdr_atmosphere_args.c b/src/atmosphere/htrdr_atmosphere_args.c
@@ -36,10 +36,10 @@ print_help(const char* cmd)
printf(
" -a GAS filename of the gas optical properties.\n");
-
printf(
-" -C <camera> define the rendering point of view. Refer to the\n"
-" %s man page for the list of camera options.\n", cmd);
+" -C <perspective-camera>\n"
+" define the perspective camera. Refer to the man page\n"
+" for the list of camera options.\n");
printf(
" -c CLOUDS filename of the clouds properties.\n");
printf(
@@ -58,8 +58,8 @@ print_help(const char* cmd)
printf(
" -h display this help and exit.\n");
printf(
-" -i <image> define the image to compute. Refer to the %s man\n"
-" page for the list of image options\n", cmd);
+" -i <image> define the image to compute. Refer to the man\n"
+" page for the list of image options\n");
printf(
" -M MATERIALS filename of the ground materials.\n");
printf(
@@ -77,15 +77,19 @@ print_help(const char* cmd)
printf(
" -p <rectangle> switch in flux computation by defining the rectangular\n"
" sensor onto which the flux is computed. Refer to the\n"
-" %s man page for the list of rectangle options.\n", cmd);
+" man page for the list of rectangle options.\n");
+ printf(
+" -P <orthoraphic-camera>\n"
+" define the orthoraphic camera. Refer to the man page\n"
+" for the list of orthographic camera options.\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(
" -s <spectral> define the type and range of the spectral\n"
-" integration. Refer to the %s man page for the list\n"
-" of spectral options\n", cmd);
+" integration. Refer to the man page for the list\n"
+" of spectral options\n");
printf(
" -T THRESHOLD optical thickness used as threshold during the\n"
" building of the volumetric acceleration structure.\n"
@@ -193,16 +197,19 @@ htrdr_atmosphere_args_init
*args = HTRDR_ATMOSPHERE_ARGS_DEFAULT;
- while((opt = getopt(argc, argv, "a:C:c:D:dfg:hi:M:m:n:O:o:p:Rrs:T:t:V:v")) != -1) {
+ while((opt = getopt(argc, argv, "a:C:c:D:dfg:hi:M:m:n:O:o:P:p:Rrs:T:t:V:v")) != -1) {
switch(opt) {
case 'a': args->filename_gas = optarg; break;
- case 'C':
- args->sensor_type = HTRDR_SENSOR_CAMERA;
- res = htrdr_args_camera_parse(&args->sensor.camera, optarg);
+ case 'C':
+ args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE;
+ args->cam_type = HTRDR_ARGS_CAMERA_PERSPECTIVE;
+ res = htrdr_args_camera_perspective_parse(&args->cam_persp, optarg);
break;
case 'c': args->filename_les = optarg; break;
case 'D': res = parse_sun_dir(args, optarg); break;
- case 'd': args->dump_volumetric_acceleration_structure = 1; break;
+ case 'd':
+ args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_OCTREES;
+ break;
case 'f': args->force_overwriting = 1; break;
case 'g': args->filename_obj = optarg; break;
case 'h':
@@ -219,8 +226,13 @@ htrdr_atmosphere_args_init
case 'O': args->filename_cache = optarg; break;
case 'o': args->filename_output = optarg; break;
case 'p':
- args->sensor_type = HTRDR_SENSOR_RECTANGLE;
- res = htrdr_args_rectangle_parse(&args->sensor.rectangle, optarg);
+ args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP;;
+ res = htrdr_args_rectangle_parse(&args->flux_map, optarg);
+ break;
+ case 'P':
+ args->output_type = HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE;
+ args->cam_type = HTRDR_ARGS_CAMERA_ORTHOGRAPHIC;
+ res = htrdr_args_camera_orthographic_parse(&args->cam_ortho, optarg);
break;
case 'r': args->repeat_clouds = 1; break;
case 'R': args->repeat_ground = 1; break;
diff --git a/src/atmosphere/htrdr_atmosphere_args.h.in b/src/atmosphere/htrdr_atmosphere_args.h.in
@@ -19,12 +19,18 @@
#define HTRDR_ATMOSPHERE_ARGS_H
#include "core/htrdr_args.h"
-#include "core/htrdr_sensor.h"
#include <rsys/rsys.h>
#include <limits.h> /* UINT_MAX support */
+enum htrdr_atmosphere_args_output_type {
+ HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP,
+ HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE,
+ HTRDR_ATMOSPHERE_ARGS_OUTPUT_OCTREES,
+ HTRDR_ATMOSPHERE_ARGS_OUTPUT_TYPES_COUNT__
+};
+
struct htrdr_atmosphere_args {
const char* filename_gas; /* Path of the gas file */
const char* filename_les; /* Path of the HTCP file */
@@ -37,11 +43,11 @@ struct htrdr_atmosphere_args {
const char* sky_mtl_name; /* Name of the sky material */
- union {
- struct htrdr_args_camera camera; /* Pinhole Camera */
- struct htrdr_args_rectangle rectangle; /* Flux map */
- } sensor;
- enum htrdr_sensor_type sensor_type;
+ struct htrdr_args_camera_perspective cam_persp; /* Perspective camera */
+ struct htrdr_args_camera_orthographic cam_ortho; /* Orthographic camera */
+ enum htrdr_args_camera_type cam_type;
+
+ struct htrdr_args_rectangle flux_map; /* Flux map */
struct htrdr_args_image image; /* Output Image */
struct htrdr_args_spectral spectral; /* Spectral domain */
@@ -58,8 +64,8 @@ struct htrdr_atmosphere_args {
/* Miscellaneous parameters */
unsigned nthreads; /* Hint on the number of threads to use */
+ enum htrdr_atmosphere_args_output_type output_type;
int force_overwriting;
- int dump_volumetric_acceleration_structure;
int verbose; /* Verbosity level */
int quit; /* Stop the command */
};
@@ -76,8 +82,11 @@ struct htrdr_atmosphere_args {
\
@HTRDR_ATMOSPHERE_ARGS_DEFAULT_SKY_MTL_NAME@, /* Sky mtl name */ \
\
- {HTRDR_ARGS_CAMERA_DEFAULT__}, /* Sensor */ \
- HTRDR_SENSOR_CAMERA, /* Sensor type */ \
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT__, /* Perspective camera */ \
+ HTRDR_ARGS_CAMERA_ORTHOGRAPHIC_DEFAULT__, /* Orthographic camera */ \
+ HTRDR_ARGS_CAMERA_PERSPECTIVE, \
+ \
+ HTRDR_ARGS_RECTANGLE_DEFAULT__, /* Flux map */ \
\
HTRDR_ARGS_IMAGE_DEFAULT__, /* Image */ \
HTRDR_ARGS_SPECTRAL_DEFAULT__, /* Spectral */ \
@@ -92,8 +101,8 @@ struct htrdr_atmosphere_args {
0, /* Repeat ground */ \
\
UINT_MAX, /* #threads */ \
+ HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE, /* Output type */ \
0, /* Force overwriting */ \
- 0, /* dump volumetric acceleration structure */ \
0, /* Verbose flag */ \
0 /* Stop the command */ \
}
diff --git a/src/atmosphere/htrdr_atmosphere_c.h b/src/atmosphere/htrdr_atmosphere_c.h
@@ -18,9 +18,10 @@
#ifndef HTRDR_ATMOSPHERE_C_H
#define HTRDR_ATMOSPHERE_C_H
+#include "atmosphere/htrdr_atmosphere_args.h"
+
#include "core/htrdr_accum.h"
#include "core/htrdr_buffer.h"
-#include "core/htrdr_sensor.h"
#include "core/htrdr_spectral.h"
#include <rsys/ref_count.h>
@@ -83,6 +84,7 @@ struct htrdr_buffer;
struct htrdr_cie_xyz;
struct htrdr_materials;
struct htrdr_ran_wlen;
+struct ssp_rng;
struct htrdr_atmosphere {
struct htrdr_atmosphere_ground* ground;
@@ -91,7 +93,8 @@ struct htrdr_atmosphere {
struct htrdr_cie_xyz* cie;
struct htrdr_ran_wlen* ran_wlen;
- struct htrdr_sensor sensor;
+ struct scam* camera; /* Camera */
+ struct htrdr_rectangle* flux_map; /* Flux map */
struct htrdr_buffer_layout buf_layout;
struct htrdr_buffer* buf; /* NULL on non master processes */
@@ -111,7 +114,7 @@ struct htrdr_atmosphere {
unsigned grid_max_definition[3]; /* Max definition of the acceleration grids */
unsigned nthreads; /* #threads of the process */
- int dump_volumetric_acceleration_structure; /* Dump octrees */
+ enum htrdr_atmosphere_args_output_type output_type;
int verbose; /* Verbosity level */
ref_T ref;
diff --git a/src/atmosphere/htrdr_atmosphere_draw_map.c b/src/atmosphere/htrdr_atmosphere_draw_map.c
@@ -117,7 +117,7 @@ draw_pixel_image
cmd = args->context;
ASSERT(cmd);
ASSERT(cmd->spectral_type == HTRDR_SPECTRAL_SW_CIE_XYZ);
- ASSERT(cmd->sensor.type == HTRDR_SENSOR_CAMERA);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE);
/* Reset accumulators */
XYZ[0] = HTRDR_ACCUM_NULL;
@@ -152,7 +152,7 @@ draw_pixel_image
sample.lens[1] = ssp_rng_canonical(args->rng);
/* Generate a camera ray */
- scam_generate_ray(cmd->sensor.camera, &sample, &ray);
+ scam_generate_ray(cmd->camera, &sample, &ray);
r0 = ssp_rng_canonical(args->rng);
r1 = ssp_rng_canonical(args->rng);
@@ -216,7 +216,7 @@ draw_pixel_flux
cmd = args->context;
ASSERT(cmd);
- ASSERT(cmd->sensor.type == HTRDR_SENSOR_RECTANGLE);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP);
ASSERT(cmd->spectral_type == HTRDR_SPECTRAL_LW
|| cmd->spectral_type == HTRDR_SPECTRAL_SW);
@@ -240,7 +240,7 @@ draw_pixel_flux
/* Begin the registration of the time spent in the realisation */
time_current(&t0);
- res = sample_rectangle_ray(cmd, cmd->sensor.rectangle, args->pixel_coord,
+ res = sample_rectangle_ray(cmd, cmd->flux_map, args->pixel_coord,
args->pixel_normalized_size, args->rng, ray_org, ray_dir);
if(res != RES_OK) continue; /* Reject the current sample */
@@ -271,7 +271,7 @@ draw_pixel_flux
/* Compute direct contribution if necessary */
htrdr_atmosphere_sun_sample_direction(cmd->sun, args->rng, sun_dir);
- htrdr_rectangle_get_normal(cmd->sensor.rectangle, N);
+ htrdr_rectangle_get_normal(cmd->flux_map, N);
cos_N_sun_dir = d3_dot(N, sun_dir);
if(cos_N_sun_dir <= 0) {
@@ -331,7 +331,7 @@ draw_pixel_xwave
(void)htrdr;
cmd = args->context;
- ASSERT(cmd->sensor.type == HTRDR_SENSOR_CAMERA);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE);
ASSERT(cmd->spectral_type == HTRDR_SPECTRAL_LW
|| cmd->spectral_type == HTRDR_SPECTRAL_SW);
@@ -363,7 +363,7 @@ draw_pixel_xwave
sample.lens[1] = ssp_rng_canonical(args->rng);
/* Generate a camera ray */
- scam_generate_ray(cmd->sensor.camera, &sample, &ray);
+ scam_generate_ray(cmd->camera, &sample, &ray);
r0 = ssp_rng_canonical(args->rng);
r1 = ssp_rng_canonical(args->rng);
@@ -434,7 +434,8 @@ setup_draw_map_args_rectangle
(struct htrdr_atmosphere* cmd,
struct htrdr_draw_map_args* args)
{
- ASSERT(cmd && cmd->sensor.type == HTRDR_SENSOR_RECTANGLE && args);
+ ASSERT(cmd && args);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP);
*args = HTRDR_DRAW_MAP_ARGS_NULL;
args->draw_pixel = draw_pixel_flux;
args->buffer_layout = cmd->buf_layout;
@@ -447,7 +448,8 @@ setup_draw_map_args_camera
(struct htrdr_atmosphere* cmd,
struct htrdr_draw_map_args* args)
{
- ASSERT(cmd && cmd->sensor.type == HTRDR_SENSOR_CAMERA && args);
+ ASSERT(cmd && args);
+ ASSERT(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE);
*args = HTRDR_DRAW_MAP_ARGS_NULL;
args->buffer_layout = cmd->buf_layout;
@@ -561,7 +563,7 @@ dump_buffer
void* pix_raw = htrdr_buffer_at(buf, x, y);
ASSERT(IS_ALIGNED(pix_raw, pixfmt.alignment));
- if(cmd->sensor.type == HTRDR_SENSOR_RECTANGLE) {
+ if(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP) {
const struct atmosphere_pixel_flux* pix = pix_raw;
dump_pixel_flux(pix, time_acc, flux_acc, stream);
} else if(cmd->spectral_type == HTRDR_SPECTRAL_SW_CIE_XYZ) {
@@ -594,11 +596,11 @@ atmosphere_draw_map(struct htrdr_atmosphere* cmd)
args.spp = cmd->spp;
- switch(cmd->sensor.type) {
- case HTRDR_SENSOR_RECTANGLE:
+ switch(cmd->output_type) {
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP:
setup_draw_map_args_rectangle(cmd, &args);
break;
- case HTRDR_SENSOR_CAMERA:
+ case HTRDR_ATMOSPHERE_ARGS_OUTPUT_IMAGE:
setup_draw_map_args_camera(cmd, &args);
break;
default: FATAL("Unreachable code.\n"); break;
@@ -619,7 +621,7 @@ atmosphere_draw_map(struct htrdr_atmosphere* cmd)
"Time per radiative path (in micro seconds): %g +/- %g\n",
path_time.E, path_time.SE);
- if(cmd->sensor.type == HTRDR_SENSOR_RECTANGLE) {
+ if(cmd->output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_FLUX_MAP) {
htrdr_accum_get_estimation(&flux_acc, &flux);
htrdr_log(cmd->htrdr,
"Radiative flux density (in W/(external m^2)): %g +/- %g\n",
diff --git a/src/atmosphere/htrdr_atmosphere_main.c b/src/atmosphere/htrdr_atmosphere_main.c
@@ -53,7 +53,7 @@ htrdr_atmosphere_main(int argc, char** argv)
res = htrdr_create(&mem_default_allocator, &htrdr_args, &htrdr);
if(res != RES_OK) goto error;
- if(cmd_args.dump_volumetric_acceleration_structure
+ if(cmd_args.output_type == HTRDR_ATMOSPHERE_ARGS_OUTPUT_OCTREES
&& htrdr_get_mpi_rank(htrdr) != 0) {
goto exit; /* Nothing to do except for the master process */
}
@@ -74,7 +74,7 @@ exit:
memsz_end = MEM_ALLOCATED_SIZE(&mem_default_allocator);
if(memsz_begin != memsz_end) {
ASSERT(memsz_end >= memsz_begin);
- fprintf(stderr, HTRDR_LOG_WARNING_PREFIX"Memory leaks: %lu Bytes\n",
+ fprintf(stderr, HTRDR_LOG_WARNING_PREFIX"Memory leaks: %lu Bytes\n",
(unsigned long)(memsz_end - memsz_begin));
err = -1;
}
diff --git a/src/combustion/htrdr_combustion.c b/src/combustion/htrdr_combustion.c
@@ -161,23 +161,50 @@ error:
}
static res_T
-setup_camera
+setup_camera_orthographic
+ (struct htrdr_combustion* cmd,
+ const struct htrdr_combustion_args* args)
+{
+ struct scam_orthographic_args cam_args = SCAM_ORTHOGRAPHIC_ARGS_DEFAULT;
+ ASSERT(cmd && args && args->image.definition[0] && args->image.definition[1]);
+ ASSERT(cmd->output_type == HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE);
+ ASSERT(args->cam_type == HTRDR_ARGS_CAMERA_ORTHOGRAPHIC);
+
+ d3_set(cam_args.position, args->cam_ortho.position);
+ d3_set(cam_args.target, args->cam_ortho.target);
+ d3_set(cam_args.up, args->cam_ortho.up);
+ cam_args.height = args->cam_ortho.height;
+ cam_args.aspect_ratio =
+ (double)args->image.definition[0]
+ / (double)args->image.definition[1];
+
+ return scam_create_orthographic
+ (htrdr_get_logger(cmd->htrdr),
+ htrdr_get_allocator(cmd->htrdr),
+ htrdr_get_verbosity_level(cmd->htrdr),
+ &cam_args,
+ &cmd->camera);
+}
+
+static res_T
+setup_camera_perspective
(struct htrdr_combustion* cmd,
const struct htrdr_combustion_args* args)
{
struct scam_perspective_args cam_args = SCAM_PERSPECTIVE_ARGS_DEFAULT;
ASSERT(cmd && args && args->image.definition[0] && args->image.definition[1]);
ASSERT(cmd->output_type == HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE);
+ ASSERT(args->cam_type == HTRDR_ARGS_CAMERA_PERSPECTIVE);
- d3_set(cam_args.position, args->camera.position);
- d3_set(cam_args.target, args->camera.target);
- d3_set(cam_args.up, args->camera.up);
- cam_args.aspect_ratio =
+ d3_set(cam_args.position, args->cam_persp.position);
+ d3_set(cam_args.target, args->cam_persp.target);
+ d3_set(cam_args.up, args->cam_persp.up);
+ cam_args.aspect_ratio =
(double)args->image.definition[0]
/ (double)args->image.definition[1];
- cam_args.field_of_view = MDEG2RAD(args->camera.fov_y);
- cam_args.lens_radius = args->camera.lens_radius;
- cam_args.focal_distance = args->camera.focal_dst;
+ cam_args.field_of_view = MDEG2RAD(args->cam_persp.fov_y);
+ cam_args.lens_radius = args->cam_persp.lens_radius;
+ cam_args.focal_distance = args->cam_persp.focal_dst;
return scam_create_perspective
(htrdr_get_logger(cmd->htrdr),
@@ -188,6 +215,25 @@ setup_camera
}
static res_T
+setup_camera
+ (struct htrdr_combustion* cmd,
+ const struct htrdr_combustion_args* args)
+{
+ res_T res = RES_OK;
+ ASSERT(cmd->output_type == HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE);
+ switch(args->cam_type) {
+ case HTRDR_ARGS_CAMERA_ORTHOGRAPHIC:
+ res = setup_camera_orthographic(cmd, args);
+ break;
+ case HTRDR_ARGS_CAMERA_PERSPECTIVE:
+ res = setup_camera_perspective(cmd, args);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ return res;
+}
+
+static res_T
setup_flux_map
(struct htrdr_combustion* cmd,
const struct htrdr_combustion_args* args)
diff --git a/src/combustion/htrdr_combustion_args.c b/src/combustion/htrdr_combustion_args.c
@@ -39,8 +39,9 @@ print_help(const char* cmd)
"to the RDG-FA theory and lightened by a laser source.\n\n");
printf(
-" -C <camera> define the rendering point of view. Refer to the\n"
-" man page for the list of camera options.\n");
+" -C <perspective-camera>\n"
+" define the perspective camera. Refer to the man page\n"
+" for the list of camera options.\n");
printf(
" -D FLUX_DENSITY\n"
" flux density of the laser in W/m^2\n"
@@ -92,6 +93,10 @@ print_help(const char* cmd)
printf(
" -p THERMOPROPS path toward the thermodynamic properties.\n");
printf(
+" -P <orthoraphic-camera>\n"
+" define the orthoraphic camera. Refer to the man page\n"
+" for the list of orthographic camera options.\n");
+ printf(
" -r REFRACT_ID path toward the per wavelength refractive\n"
" indices.\n");
printf(
@@ -246,11 +251,12 @@ htrdr_combustion_args_init
*args = HTRDR_COMBUSTION_ARGS_DEFAULT;
- while((opt = getopt(argc, argv, "C:D:d:F:fg:hIi:l:m:NO:o:p:R:r:sT:t:V:vw:")) != -1) {
+ while((opt = getopt(argc, argv, "C:D:d:F:fg:hIi:l:m:NO:o:P:p:R:r:sT:t:V:vw:")) != -1) {
switch(opt) {
case 'C':
args->output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE;
- res = htrdr_args_camera_parse(&args->camera, optarg);
+ args->cam_type = HTRDR_ARGS_CAMERA_PERSPECTIVE;
+ res = htrdr_args_camera_perspective_parse(&args->cam_persp, optarg);
break;
case 'D':
res = cstr_to_double(optarg, &args->laser_flux_density);
@@ -286,6 +292,11 @@ htrdr_combustion_args_init
case 'O': args->path_cache = optarg; break;
case 'o': args->path_output = optarg; break;
case 'p': args->path_therm_props = optarg; break;
+ case 'P':
+ args->output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_IMAGE;
+ args->cam_type = HTRDR_ARGS_CAMERA_ORTHOGRAPHIC;
+ res = htrdr_args_camera_orthographic_parse(&args->cam_ortho, optarg);
+ break;
case 'r': args->path_refract_ids = optarg; break;
case 'R':
args->output_type = HTRDR_COMBUSTION_ARGS_OUTPUT_FLUX_MAP;
diff --git a/src/combustion/htrdr_combustion_args.h.in b/src/combustion/htrdr_combustion_args.h.in
@@ -68,7 +68,10 @@ struct htrdr_combustion_args {
const char* path_cache; /* Path of the file to store/restore cached data */
const char* path_output; /* Name of the output file */
- struct htrdr_args_camera camera; /* Pinhole Camera */
+ struct htrdr_args_camera_perspective cam_persp; /* Perspective camera */
+ struct htrdr_args_camera_orthographic cam_ortho; /* Ortographic camera */
+ enum htrdr_args_camera_type cam_type;
+
struct htrdr_args_rectangle flux_map; /* Flux map */
struct htrdr_args_rectangle laser; /* Laser surface emission */
@@ -106,7 +109,10 @@ struct htrdr_combustion_args {
NULL, /* Cache path */ \
NULL, /* Output path */ \
\
- HTRDR_ARGS_CAMERA_DEFAULT__, /* Pinhole camera */ \
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT__, /* Perspective camera */ \
+ HTRDR_ARGS_CAMERA_ORTHOGRAPHIC_DEFAULT__, /* Orthographic camera */ \
+ HTRDR_ARGS_CAMERA_PERSPECTIVE, \
+ \
HTRDR_ARGS_RECTANGLE_DEFAULT__, /* Flux map */ \
\
HTRDR_ARGS_RECTANGLE_DEFAULT__, /* Laser surface emission */ \
diff --git a/src/core/htrdr.h b/src/core/htrdr.h
@@ -77,9 +77,10 @@ htrdr_fprint_license(const char* cmd, FILE* stream)
{
ASSERT(cmd);
fprintf(stream,
-"%s is free software released under the GNU GPL license, version\n"
-"3 or later. You are free to change or redistribute it under certain\n"
-"conditions <http://gnu.org/licenses/gpl.html>.\n", cmd);
+"%s is free software released under the GNU GPL license,\n"
+"version 3 or later. You are free to change or redistribute it\n"
+"under certain conditions <http://gnu.org/licenses/gpl.html>.\n",
+ cmd);
}
BEGIN_DECLS
diff --git a/src/core/htrdr_args.c b/src/core/htrdr_args.c
@@ -68,10 +68,11 @@ parse_fov(const char* str, double* out_fov)
fprintf(stderr, "Invalid field of view `%s'.\n", str);
return RES_BAD_ARG;
}
- if(fov <= HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN
- || fov >= HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX) {
+ if(fov <= HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN
+ || fov >= HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX) {
fprintf(stderr, "The field of view %g is not in ]%g, %g[.\n", fov,
- HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN, HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX);
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN,
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX);
return RES_BAD_ARG;
}
*out_fov = fov;
@@ -139,6 +140,30 @@ parse_focal_dst(const char* str, double* out_dst)
}
static res_T
+parse_image_plane_height(const char* str, double* out_height)
+{
+ double height;
+ res_T res = RES_OK;
+ ASSERT(str && out_height);
+
+ res = cstr_to_double(str, &height);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Invalid height `%s' of the image plane of the orthographic camera.\n",
+ str);
+ return RES_BAD_ARG;
+ }
+ if(height <= 0) {
+ fprintf(stderr,
+ "Invalid negative or null height of the image plane "
+ "of the orthographic camera.\n");
+ return RES_BAD_ARG;
+ }
+ *out_height = height;
+ return RES_OK;
+}
+
+static res_T
parse_image_parameter(const char* str, void* args)
{
char buf[128];
@@ -201,10 +226,10 @@ error:
}
static res_T
-parse_camera_parameter(const char* str, void* args)
+parse_camera_perspective_parameter(const char* str, void* args)
{
char buf[128];
- struct htrdr_args_camera* cam = args;
+ struct htrdr_args_camera_perspective* cam = args;
char* key;
char* val;
char* ctx;
@@ -213,7 +238,7 @@ parse_camera_parameter(const char* str, void* args)
if(strlen(str) >= sizeof(buf) -1/*NULL char*/) {
fprintf(stderr,
- "Could not duplicate the camera option string `%s'.\n", str);
+ "Could not duplicate the perspective camera option string `%s'.\n", str);
res = RES_MEM_ERR;
goto error;
}
@@ -223,14 +248,15 @@ parse_camera_parameter(const char* str, void* args)
val = strtok_r(NULL, "", &ctx);
if(!val) {
- fprintf(stderr, "Missing value to the camera option `%s'.\n", key);
+ fprintf(stderr,
+ "Missing value to the perspective camera parameter `%s'.\n", key);
res = RES_BAD_ARG;
goto error;
}
#define PARSE(Name, Func) { \
if(RES_OK != (res = Func)) { \
- fprintf(stderr, "Invalid camera "Name" `%s'.\n", val); \
+ fprintf(stderr, "Invalid perspective camera "Name" `%s'.\n", val); \
goto error; \
} \
} (void)0
@@ -251,7 +277,61 @@ parse_camera_parameter(const char* str, void* args)
} else if(!strcmp(key, "focal-dst")) {
PARSE("focal distance", parse_focal_dst(val, &cam->focal_dst));
} else {
- fprintf(stderr, "Invalid camera parameter `%s'.\n", key);
+ fprintf(stderr, "Invalid perspective camera parameter `%s'.\n", key);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ #undef PARSE
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_camera_orthographic_parameter(const char* str, void* args)
+{
+ char buf[128];
+ struct htrdr_args_camera_orthographic* cam = args;
+ char* key;
+ char* val;
+ char* ctx;
+ res_T res = RES_OK;
+ ASSERT(cam && str);
+
+ if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) {
+ fprintf(stderr,
+ "Could not duplicate the orthographic camera option string `%s'.\n", str);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ strncpy(buf, str, sizeof(buf));
+
+ key = strtok_r(buf, "=", &ctx);
+ val = strtok_r(NULL, "", &ctx);
+
+ if(!val) {
+ fprintf(stderr,
+ "Missing value to the orthographic camera parameter `%s'.\n", key);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ #define PARSE(Name, Func) { \
+ if(RES_OK != (res = Func)) { \
+ fprintf(stderr, "Invalid orthographic camera "Name" `%s'.\n", val); \
+ goto error; \
+ } \
+ } (void)0
+ if(!strcmp(key, "pos")) {
+ PARSE("position", parse_doubleX(val, cam->position, 3));
+ } else if(!strcmp(key, "tgt")) {
+ PARSE("target", parse_doubleX(val, cam->target, 3));
+ } else if(!strcmp(key, "up")) {
+ PARSE("up vector", parse_doubleX(val, cam->up, 3));
+ } else if(!strcmp(key, "height")) {
+ PARSE("image plane height", parse_image_plane_height(val, &cam->height));
+ } else {
+ fprintf(stderr, "Invalid orthographic camera parameter `%s'.\n", key);
res = RES_BAD_ARG;
goto error;
}
@@ -464,7 +544,9 @@ error:
* Exported functions
******************************************************************************/
res_T
-htrdr_args_camera_parse(struct htrdr_args_camera* cam, const char* str)
+htrdr_args_camera_perspective_parse
+ (struct htrdr_args_camera_perspective* cam,
+ const char* str)
{
res_T res = RES_OK;
@@ -473,7 +555,7 @@ htrdr_args_camera_parse(struct htrdr_args_camera* cam, const char* str)
goto error;
}
- res = cstr_parse_list(str, ':', parse_camera_parameter, cam);
+ res = cstr_parse_list(str, ':', parse_camera_perspective_parameter, cam);
if(res != RES_OK) goto error;
if(cam->focal_length < 0) {
@@ -504,16 +586,16 @@ htrdr_args_camera_parse(struct htrdr_args_camera* cam, const char* str)
goto error;
}
cam->fov_y = MRAD2DEG(cam->fov_y);
- if(cam->fov_y <= HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN
- || cam->fov_y >= HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX) {
+ if(cam->fov_y <= HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN
+ || cam->fov_y >= HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX) {
fprintf(stderr,
"Invalid focal length %g regarding the lens radius %g. "
"The corresponding field of view %g is not in ]%g, %g[ degrees.\n",
cam->focal_length,
cam->lens_radius,
cam->fov_y,
- HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN,
- HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX);
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN,
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX);
res = RES_BAD_ARG;
goto error;
}
@@ -523,7 +605,16 @@ exit:
return res;
error:
goto exit;
-}
+}
+
+res_T
+htrdr_args_camera_orthographic_parse
+ (struct htrdr_args_camera_orthographic* cam,
+ const char* str)
+{
+ if(!cam || !str) return RES_BAD_ARG;
+ return cstr_parse_list(str, ':', parse_camera_orthographic_parameter, cam);
+}
res_T
htrdr_args_rectangle_parse(struct htrdr_args_rectangle* rect, const char* str)
diff --git a/src/core/htrdr_args.h.in b/src/core/htrdr_args.h.in
@@ -24,11 +24,18 @@
#include <rsys/rsys.h>
/* Exclusive bounds of the camera field of view (degrees) */
-#define HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN @HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MIN@
-#define HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX @HTRDR_ARGS_CAMERA_FOV_EXCLUSIVE_MAX@
+#define HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN \
+ @HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MIN@
+#define HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX \
+ @HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX@
+
+enum htrdr_args_camera_type {
+ HTRDR_ARGS_CAMERA_PERSPECTIVE,
+ HTRDR_ARGS_CAMERA_ORTHOGRAPHIC,
+ HTRDR_ARGS_CAMERA_TYPES_COUNT__
+};
-/* Arguments of a pinhole camera sensor */
-struct htrdr_args_camera {
+struct htrdr_args_camera_perspective {
double position[3]; /* Lens position */
double target[3]; /* Targeted position */
double up[3]; /* Up vector of the camera */
@@ -37,17 +44,32 @@ struct htrdr_args_camera {
double focal_dst; /* Distance to focus on */
double focal_length; /* Computed from fov_y and lens_radius. <0 => not used */
};
-#define HTRDR_ARGS_CAMERA_DEFAULT__ { \
+#define HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT__ { \
{@HTRDR_ARGS_DEFAULT_CAMERA_POS@}, /* position */ \
{@HTRDR_ARGS_DEFAULT_CAMERA_TGT@}, /* target */ \
{@HTRDR_ARGS_DEFAULT_CAMERA_UP@}, /* Camera up */ \
- @HTRDR_ARGS_DEFAULT_CAMERA_FOV@, /* Vertical field of view */ \
- @HTRDR_ARGS_DEFAULT_CAMERA_LENS_RADIUS@, /* Radius of the lens */ \
- @HTRDR_ARGS_DEFAULT_CAMERA_FOCAL_DST@, /* Distance to focus on */ \
+ @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOV@, /* Vertical field of view */ \
+ @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_LENS_RADIUS@, /* Radius of the lens */\
+ @HTRDR_ARGS_DEFAULT_CAMERA_PERSPECTIVE_FOCAL_DST@, /* Distance to focus on */\
-1 /* Focal length. <0 <=> not used */ \
}
-static const struct htrdr_args_camera HTRDR_ARGS_CAMERA_DEFAULT =
- HTRDR_ARGS_CAMERA_DEFAULT__;
+static const struct htrdr_args_camera_perspective
+HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT = HTRDR_ARGS_CAMERA_PERSPECTIVE_DEFAULT__;
+
+struct htrdr_args_camera_orthographic {
+ double position[3]; /* Lens position */
+ double target[3]; /* Targeted position */
+ double up[3]; /* Up vector of the camera */
+ double height; /* Height of the image plane */
+};
+#define HTRDR_ARGS_CAMERA_ORTHOGRAPHIC_DEFAULT__ { \
+ {@HTRDR_ARGS_DEFAULT_CAMERA_POS@}, /* position */ \
+ {@HTRDR_ARGS_DEFAULT_CAMERA_TGT@}, /* target */ \
+ {@HTRDR_ARGS_DEFAULT_CAMERA_UP@}, /* Camera up */ \
+ @HTRDR_ARGS_DEFAULT_CAMERA_ORTHOGRAPHIC_HEIGHT@ /* Image plane height */ \
+}
+static const struct htrdr_args_camera_orthographic
+HTRDR_ARGS_CAMERA_ORTHOGRAPHIC_DEFAULT = HTRDR_ARGS_CAMERA_ORTHOGRAPHIC_DEFAULT__;
/* Arguments of a rectangular sensor */
struct htrdr_args_rectangle {
@@ -106,8 +128,13 @@ static const struct htrdr_args_spectral HTRDR_ARGS_SPECTRAL_DEFAULT =
BEGIN_DECLS
HTRDR_CORE_API res_T
-htrdr_args_camera_parse
- (struct htrdr_args_camera* cam,
+htrdr_args_camera_perspective_parse
+ (struct htrdr_args_camera_perspective* cam,
+ const char* str);
+
+HTRDR_CORE_API res_T
+htrdr_args_camera_orthographic_parse
+ (struct htrdr_args_camera_orthographic* cam,
const char* str);
HTRDR_CORE_API res_T