commit dafade50cb4f5af6f02b4f406e5bbcdfb7022107
parent c9bf58dd006a13e86c54208feaa4ecabe7f2f67d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 27 Aug 2021 15:00:57 +0200
Merge branch 'release_0.8'
Diffstat:
27 files changed, 721 insertions(+), 429 deletions(-)
diff --git a/README.md b/README.md
@@ -76,6 +76,18 @@ informations on CMake.
## Release notes
+### Version 0.8
+
+- Adds support for a thin lens camera model and an orthographic camera model
+ for combustion and atmosphere modes.
+- Updates the size of a tile from 32x32 pixels to 8x8 pixels. A tile is a
+ block of pixels rendered by a thread. However, a size of 32x32 pixels could
+ be too large when rendering on several dozen threads: the image definition
+ could be insufficient to give tiles to all threads.
+- Fixes the calculation of shortwave radiance by `htrdr-combustion` and the
+ calculation of longwave radiance by `htrdr-atmosphere`. At each scattering
+ position, the range of the traced ray could be incorrect.
+
### Version 0.7
#### Adds the simulation of radiative transfer in combustion media
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -23,7 +23,7 @@ set(HTRDR_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
set(HTRDR_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(VERSION_MAJOR 0)
-set(VERSION_MINOR 7)
+set(VERSION_MINOR 8)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
diff --git a/cmake/atmosphere/CMakeLists.txt b/cmake/atmosphere/CMakeLists.txt
@@ -25,8 +25,9 @@ find_package(HTSky 0.2 REQUIRED)
find_package(RCMake 0.3 REQUIRED)
find_package(RSys 0.11 REQUIRED)
find_package(Star3D 0.8 REQUIRED)
+find_package(StarCamera 0.0 REQUIRED)
find_package(StarSF 0.6 REQUIRED)
-find_package(StarSP 0.9 REQUIRED)
+find_package(StarSP 0.10 REQUIRED)
find_package(StarVX 0.1 REQUIRED)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
@@ -36,6 +37,7 @@ include(rcmake_runtime)
include_directories(
${HTSky_INCLUDE_DIR}
${RSys_INCLUDE_DIR}
+ ${StarCamera_INCLUDE_DIR}
${Star3D_INCLUDE_DIR}
${StarSF_INCLUDE_DIR}
${StarSP_INCLUDE_DIR}
@@ -84,7 +86,8 @@ add_library(htrdr-atmosphere SHARED
${HTRDR_ATMOSPHERE_FILES_SRC}
${HTRDR_ATMOSPHERE_FILES_INC}
${HTRDR_ATMOSPHERE_FILES_INC2})
-target_link_libraries(htrdr-atmosphere htrdr-core HTSky RSys Star3D StarSF StarSP)
+target_link_libraries(htrdr-atmosphere
+ htrdr-core HTSky RSys Star3D StarCamera StarSF StarSP)
if(CMAKE_COMPILER_IS_GNUCC)
target_link_libraries(htrdr-atmosphere m)
diff --git a/cmake/combustion/CMakeLists.txt b/cmake/combustion/CMakeLists.txt
@@ -25,6 +25,7 @@ find_package(AtrSTM REQUIRED)
find_package(RCMake 0.3 REQUIRED)
find_package(RSys 0.11 REQUIRED)
find_package(Star3D 0.8 REQUIRED)
+find_package(StarCamera 0.0 REQUIRED)
find_package(StarSF 0.6 REQUIRED)
find_package(StarSP 0.10 REQUIRED)
find_package(StarVX 0.1 REQUIRED)
@@ -37,6 +38,7 @@ include_directories(
${AtrSTM_INCLUDE_DIR}
${RSys_INCLUDE_DIR}
${Star3D_INCLUDE_DIR}
+ ${StarCamera_INCLUDE_DIR}
${StarSF_INCLUDE_DIR}
${StarSP_INCLUDE_DIR}
${StarVX_INCLUDE_DIR}
@@ -72,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)
@@ -84,7 +85,8 @@ rcmake_prepend_path(HTRDR_COMBUSTION_FILES_INC ${HTRDR_SOURCE_DIR}/combustion)
add_library(htrdr-combustion SHARED
${HTRDR_COMBUSTION_FILES_SRC}
${HTRDR_COMBUSTION_FILES_INC})
-target_link_libraries(htrdr-combustion htrdr-core AtrSTM RSys Star3D StarSF StarSP)
+target_link_libraries(htrdr-combustion
+ htrdr-core AtrSTM RSys Star3D StarCamera StarSF StarSP)
set_target_properties(htrdr-combustion PROPERTIES
DEFINE_SYMBOL HTRDR_SHARED_BUILD
diff --git a/cmake/core/CMakeLists.txt b/cmake/core/CMakeLists.txt
@@ -26,8 +26,9 @@ find_package(MruMtl 0.0 REQUIRED)
find_package(RCMake 0.3 REQUIRED)
find_package(RSys 0.11 REQUIRED)
find_package(Star3D 0.8 REQUIRED)
+find_package(StarCamera 0.0 REQUIRED)
find_package(StarSF 0.6 REQUIRED)
-find_package(StarSP 0.9 REQUIRED)
+find_package(StarSP 0.10 REQUIRED)
find_package(OpenMP 1.2 REQUIRED)
find_package(MPI 2 REQUIRED)
@@ -42,6 +43,7 @@ include_directories(
${MruMtl_INCLUDE_DIR}
${RSys_INCLUDE_DIR}
${Star3D_INCLUDE_DIR}
+ ${StarCamera_INCLUDE_DIR}
${StarSF_INCLUDE_DIR}
${StarSP_INCLUDE_DIR}
${StarVX_INCLUDE_DIR}
@@ -53,10 +55,15 @@ include_directories(
################################################################################
# Generate files
################################################################################
+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_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 "")
@@ -77,7 +84,6 @@ set(HTRDR_CORE_FILES_SRC
htrdr.c
htrdr_args.c
htrdr_buffer.c
- htrdr_camera.c
htrdr_cie_xyz.c
htrdr_draw_map.c
htrdr_geometry.c
@@ -91,7 +97,6 @@ set(HTRDR_CORE_FILES_INC
htrdr.h
htrdr_accum.h
htrdr_buffer.h
- htrdr_camera.h
htrdr_c.h
htrdr_cie_xyz.h
htrdr_draw_map.h
@@ -118,7 +123,7 @@ add_library(htrdr-core SHARED
${HTRDR_CORE_FILES_SRC}
${HTRDR_CORE_FILES_INC}
${HTRDR_CORE_FILES_INC2})
-target_link_libraries(htrdr-core AW MruMtl RSys Star3D StarSF StarSP)
+target_link_libraries(htrdr-core AW MruMtl RSys Star3D StarCamera StarSF StarSP)
if(CMAKE_COMPILER_IS_GNUCC)
target_link_libraries(htrdr-core m)
diff --git a/doc/htrdr-atmosphere.1.txt.in b/doc/htrdr-atmosphere.1.txt.in
@@ -82,7 +82,7 @@ W/sr/m^2 excepted for monochromatic computations where the computed spectral
radiance is defined in W/sr/m^2/nm. The flux densities are saved in W/m^2. The
results are written to the output file if the *-o* option is defined and the
standard output otherwise. The output image is a list of raw ASCII data
-formatted with respect to the *htrdr-image*(5) file format.
+formatted with respect to the *htrdr-image*(5) file format.
*htrdr-atmosphere* supports shared memory parallelism and relies on the Message
Passing Interface specification [4] to parallelise its computations in a
@@ -101,14 +101,32 @@ OPTIONS
are taken into account.
*-C* <__camera-parameter__:...>::
- Define the rendering point of view. Available camera 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_PERSPECTIVE_FOCAL_DST@ meter.
+
+ **focal-length**=**_length_**;;
+ Focal length of a camera lens. It is another way to control the field of
+ view of a thin lens camera. Be default, the field of view is directly set
+ through the **fov** parameter.
**fov**=**_angle_**;;
- Vertical field of view of the camera in [30, 120] degrees. By default
- _angle_ is set to @HTRDR_ARGS_DEFAULT_CAMERA_FOV@ degrees.
+ Vertical field of view of the camera in
+ ]@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_PERSPECTIVE_LENS_RADIUS@.
**pos**=**_x_**,**_y_**,**_z_**;;
- Position of the camera. By default it is set to
+ Camera lens position. By default it is set to
{@HTRDR_ARGS_DEFAULT_CAMERA_POS@}.
**tgt**=**_x_**,**_y_**,**_z_**;;
@@ -195,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
@@ -290,7 +327,7 @@ integrated radiance in W/sr/m^2 for the X, Y, and Z components of the CIE
1931 XYZ color space. The first value of each pair is the expected value of the
average radiance of the pixel. The second value is its associated standard
deviation. The fourth and final pair records the microsecond estimate of the
-computation time per radiative path and its standard error.
+computation time per radiative path and its standard error.
Longwave image
~~~~~~~~~~~~~~
@@ -304,7 +341,7 @@ spectral radiance in W/sr/m^2/nm depending on whether this radiance was
calculated for a spectral range or at a single wavelength. The fifth and sixth
pixel components are not used. Finally, the last 2 components of the pixel
record the estimate in microseconds of the computation time per radiative path
-and its standard error.
+and its standard error.
Shortwave image
~~~~~~~~~~~~~~~
diff --git a/doc/htrdr-combustion.1.txt.in b/doc/htrdr-combustion.1.txt.in
@@ -79,14 +79,32 @@ OPTIONS
-------
*-C* <__camera-parameter__:...>::
- Define the rendering point of view. Available camera parameters are:
+ Define the 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_PERSPECTIVE_FOCAL_DST@ meter.
+
+ **focal-length**=**_length_**;;
+ Focal length of a camera lens. It is another way to control the field of
+ view of a thin lens camera. Be default, the field of view is directly set
+ through the **fov** parameter.
**fov**=**_angle_**;;
- Vertical field of view of the camera in [30, 120] degrees. By default
- _angle_ is set to @HTRDR_ARGS_DEFAULT_CAMERA_FOV@ degrees.
+ Vertical field of view of the camera in
+ ]@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_PERSPECTIVE_LENS_RADIUS@.
**pos**=**_x_**,**_y_**,**_z_**;;
- Position of the camera. By default it is set to
+ Camera lens position. By default it is set to
{@HTRDR_ARGS_DEFAULT_CAMERA_POS@}.
**tgt**=**_x_**,**_y_**,**_z_**;;
@@ -212,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.
@@ -306,7 +343,7 @@ EXAMPLES
Make htrdr-combustion verbose (option *-v*) and render an image of a combustion
medium whose tetrahedral mesh is stored in *tetra.sth* and its associated
-thermodynamic properties are saved in *thermprops.atrtp*. The spectrallyole
+thermodynamic properties are saved in *thermprops.atrtp*. The spectrally
varying indices of the medium are listed in the *refract_ids.atrri* file. The
center of the laser surface emission is positioned at the origin and its
direction is aligned to the Y axis. The definition of the rendered image is
@@ -329,8 +366,8 @@ Add a combustion chamber to the previous example: its mesh is defined in
*chamber.obj* while its materials are listed in *materials.mtls*. Save the
volumetric acceleration structure in *octree.cache* or reused it if it was
already populated in a previous run with compatible input data. Set the finest
-resolution of this acceleration structure to 1000 along the major extend of the
-medium and use a optical thickness criterion of 5 to build it. Use the *-f*
+resolution of this acceleration structure to *1000* along the major extend of the
+medium and use a optical thickness criterion of *5* to build it. Use the *-f*
option to force the overwrite of the *output* file if it exists and use *-s* to
speed up the rendering with the available SIMD instruction sets.
diff --git a/src/atmosphere/htrdr_atmosphere.c b/src/atmosphere/htrdr_atmosphere.c
@@ -24,7 +24,6 @@
#include "atmosphere/htrdr_atmosphere_sun.h"
#include "core/htrdr_buffer.h"
-#include "core/htrdr_camera.h"
#include "core/htrdr_cie_xyz.h"
#include "core/htrdr_log.h"
#include "core/htrdr_materials.h"
@@ -33,7 +32,10 @@
#include <high_tune/htsky.h>
+#include <star/scam.h>
+
#include <rsys/cstr.h>
+#include <rsys/double3.h>
#include <math.h>
@@ -148,55 +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)
+{
+ 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)
{
- double proj_ratio;
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];
- res = htrdr_camera_create
- (cmd->htrdr,
- args->sensor.camera.position,
- args->sensor.camera.target,
- args->sensor.camera.up,
- proj_ratio,
- MDEG2RAD(args->sensor.camera.fov_y),
- &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
@@ -243,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) htrdr_camera_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);
@@ -282,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];
@@ -390,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);
@@ -438,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;
}
/*******************************************************************************
@@ -462,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_compute_radiance_lw.c b/src/atmosphere/htrdr_atmosphere_compute_radiance_lw.c
@@ -163,8 +163,8 @@ atmosphere_compute_radiance_lw
/* Setup the phase function for this spectral band & quadrature point */
CHK(RES_OK == ssf_phase_create
- (htrdr_get_thread_allocator(cmd->htrdr, ithread),
- &ssf_phase_hg,
+ (htrdr_get_thread_allocator(cmd->htrdr, ithread),
+ &ssf_phase_hg,
&phase_hg));
g = htsky_fetch_per_wavelength_particle_phase_function_asymmetry_parameter
(cmd->sky, wlen);
@@ -178,6 +178,11 @@ atmosphere_compute_radiance_lw
for(;;) {
struct filter_context ctx = FILTER_CONTEXT_NULL;
+ /* Find the first intersection with the surface geometry */
+ d2(range, 0, DBL_MAX);
+ HTRDR(atmosphere_ground_trace_ray
+ (cmd->ground, pos, dir, range, &s3d_hit_prev, &s3d_hit));
+
/* Sample an optical thickness */
ctx.Ts = ssp_ran_exp(rng, 1);
@@ -187,13 +192,8 @@ atmosphere_compute_radiance_lw
ctx.iband = iband;
ctx.iquad = iquad;
- /* Found the first intersection with the surface geometry */
- HTRDR(atmosphere_ground_trace_ray
- (cmd->ground, pos, dir, range, &s3d_hit_prev, &s3d_hit));
-
/* Fit the ray range to the surface distance along the ray */
- range[0] = 0;
- range[1] = s3d_hit.distance;
+ d2(range, 0, s3d_hit.distance);
/* Trace a ray into the participating media */
HTSKY(trace_ray(cmd->sky, pos, dir, range, NULL,
diff --git a/src/atmosphere/htrdr_atmosphere_draw_map.c b/src/atmosphere/htrdr_atmosphere_draw_map.c
@@ -21,7 +21,6 @@
#include "core/htrdr.h"
#include "core/htrdr_buffer.h"
-#include "core/htrdr_camera.h"
#include "core/htrdr_cie_xyz.h"
#include "core/htrdr_draw_map.h"
#include "core/htrdr_interface.h"
@@ -32,6 +31,7 @@
#include <high_tune/htsky.h>
#include <star/s3d.h>
+#include <star/scam.h>
#include <star/ssp.h>
#include <rsys/clock_time.h>
@@ -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;
@@ -130,9 +130,8 @@ draw_pixel_image
FOR_EACH(isamp, 0, args->spp) {
struct time t0, t1;
- double pix_samp[2];
- double ray_org[3];
- double ray_dir[3];
+ struct scam_sample sample = SCAM_SAMPLE_NULL;
+ struct scam_ray ray = SCAM_RAY_NULL;
double weight;
double r0, r1, r2;
double wlen; /* Sampled wavelength into the spectral band */
@@ -145,14 +144,15 @@ draw_pixel_image
time_current(&t0);
/* Sample a position into the pixel, in the normalized image plane */
- pix_samp[0] = (double)args->pixel_coord[0] + ssp_rng_canonical(args->rng);
- pix_samp[1] = (double)args->pixel_coord[1] + ssp_rng_canonical(args->rng);
- pix_samp[0] *= args->pixel_normalized_size[0];
- pix_samp[1] *= args->pixel_normalized_size[1];
+ sample.film[0] = (double)args->pixel_coord[0]+ssp_rng_canonical(args->rng);
+ sample.film[1] = (double)args->pixel_coord[1]+ssp_rng_canonical(args->rng);
+ sample.film[0] *= args->pixel_normalized_size[0];
+ sample.film[1] *= args->pixel_normalized_size[1];
+ sample.lens[0] = ssp_rng_canonical(args->rng);
+ sample.lens[1] = ssp_rng_canonical(args->rng);
- /* Generate a ray starting from the pinhole camera and passing through the
- * pixel sample */
- htrdr_camera_ray(cmd->sensor.camera, pix_samp, ray_org, ray_dir);
+ /* Generate a camera ray */
+ scam_generate_ray(cmd->camera, &sample, &ray);
r0 = ssp_rng_canonical(args->rng);
r1 = ssp_rng_canonical(args->rng);
@@ -172,7 +172,7 @@ draw_pixel_image
/* Compute the radiance in W/m^2/sr/m */
weight = atmosphere_compute_radiance_sw(cmd, args->ithread, args->rng,
- ATMOSPHERE_RADIANCE_ALL, ray_org, ray_dir, wlen, iband, iquad);
+ ATMOSPHERE_RADIANCE_ALL, ray.org, ray.dir, wlen, iband, iquad);
ASSERT(weight >= 0);
weight /= pdf; /* In W/m^2/sr */
@@ -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);
@@ -341,9 +341,8 @@ draw_pixel_xwave
FOR_EACH(isamp, 0, args->spp) {
struct time t0, t1;
- double pix_samp[2];
- double ray_org[3];
- double ray_dir[3];
+ struct scam_sample sample = SCAM_SAMPLE_NULL;
+ struct scam_ray ray = SCAM_RAY_NULL;
double weight;
double r0, r1, r2;
double wlen;
@@ -356,14 +355,15 @@ draw_pixel_xwave
time_current(&t0);
/* Sample a position into the pixel, in the normalized image plane */
- pix_samp[0] = (double)args->pixel_coord[0] + ssp_rng_canonical(args->rng);
- pix_samp[1] = (double)args->pixel_coord[1] + ssp_rng_canonical(args->rng);
- pix_samp[0] *= args->pixel_normalized_size[0];
- pix_samp[1] *= args->pixel_normalized_size[1];
+ sample.film[0] = (double)args->pixel_coord[0]+ssp_rng_canonical(args->rng);
+ sample.film[1] = (double)args->pixel_coord[1]+ssp_rng_canonical(args->rng);
+ sample.film[0] *= args->pixel_normalized_size[0];
+ sample.film[1] *= args->pixel_normalized_size[1];
+ sample.lens[0] = ssp_rng_canonical(args->rng);
+ sample.lens[1] = ssp_rng_canonical(args->rng);
- /* Generate a ray starting from the pinhole camera and passing through the
- * pixel sample */
- htrdr_camera_ray(cmd->sensor.camera, pix_samp, ray_org, ray_dir);
+ /* Generate a camera ray */
+ scam_generate_ray(cmd->camera, &sample, &ray);
r0 = ssp_rng_canonical(args->rng);
r1 = ssp_rng_canonical(args->rng);
@@ -381,11 +381,11 @@ draw_pixel_xwave
switch(cmd->spectral_type) {
case HTRDR_SPECTRAL_LW:
weight = atmosphere_compute_radiance_lw(cmd, args->ithread, args->rng,
- ray_org, ray_dir, wlen, iband, iquad);
+ ray.org, ray.dir, wlen, iband, iquad);
break;
case HTRDR_SPECTRAL_SW:
weight = atmosphere_compute_radiance_sw(cmd, args->ithread, args->rng,
- ATMOSPHERE_RADIANCE_ALL, ray_org, ray_dir, wlen, iband, iquad);
+ ATMOSPHERE_RADIANCE_ALL, ray.org, ray.dir, wlen, iband, iquad);
break;
default: FATAL("Unreachable code.\n"); break;
}
@@ -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
@@ -21,7 +21,6 @@
#include "combustion/htrdr_combustion_laser.h"
#include "core/htrdr.h"
-#include "core/htrdr_camera.h"
#include "core/htrdr_log.h"
#include "core/htrdr_geometry.h"
#include "core/htrdr_materials.h"
@@ -29,9 +28,11 @@
#include <astoria/atrstm.h>
+#include <star/scam.h>
#include <star/ssf.h>
#include <rsys/cstr.h>
+#include <rsys/double3.h>
#include <rsys/mem_allocator.h>
/*******************************************************************************
@@ -160,29 +161,79 @@ error:
}
static res_T
-setup_camera
+setup_camera_orthographic
(struct htrdr_combustion* cmd,
const struct htrdr_combustion_args* args)
{
- double proj_ratio = 0;
+ 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);
- proj_ratio =
+ 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 htrdr_camera_create
- (cmd->htrdr,
- args->camera.position,
- args->camera.target,
- args->camera.up,
- proj_ratio,
- MDEG2RAD(args->camera.fov_y),
+ 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->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_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)
@@ -509,7 +560,7 @@ combustion_release(ref_T* ref)
if(cmd->geom) htrdr_geometry_ref_put(cmd->geom);
if(cmd->mats) htrdr_materials_ref_put(cmd->mats);
if(cmd->medium) ATRSTM(ref_put(cmd->medium));
- if(cmd->camera) htrdr_camera_ref_put(cmd->camera);
+ if(cmd->camera) SCAM(ref_put(cmd->camera));
if(cmd->flux_map) htrdr_rectangle_ref_put(cmd->flux_map);
if(cmd->laser) htrdr_combustion_laser_ref_put(cmd->laser);
if(cmd->buf) htrdr_buffer_ref_put(cmd->buf);
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/combustion/htrdr_combustion_c.h b/src/combustion/htrdr_combustion_c.h
@@ -32,11 +32,11 @@
/* Forward declarations */
struct atrstm;
struct htrdr;
-struct htrdr_camera;
struct htrdr_combustion_laser;
struct htrdr_geometry;
struct htrdr_materials;
struct htrdr_rectangle;
+struct scam;
struct ssf_phase;
struct ssp_rng;
struct suvm_primitive;
@@ -68,7 +68,7 @@ struct htrdr_combustion {
struct htrdr_materials* mats; /* Materials of the combustion chamber */
struct atrstm* medium; /* Semi transparent medium */
- struct htrdr_camera* camera; /* Pinhole camera */
+ struct scam* camera; /* Camera */
struct htrdr_rectangle* flux_map; /* Flux map */
struct htrdr_combustion_laser* laser; /* Laser sheet */
double wavelength; /* Wavelength of the laser in nanometer */
diff --git a/src/combustion/htrdr_combustion_compute_radiance_sw.c b/src/combustion/htrdr_combustion_compute_radiance_sw.c
@@ -878,7 +878,6 @@ combustion_compute_radiance_sw
d3_set(pos, pos_in);
d3_set(dir, dir_in);
- d2(range, 0, FLT_MAX);
wlen = htrdr_combustion_laser_get_wavelength(cmd->laser);
@@ -904,7 +903,7 @@ combustion_compute_radiance_sw
/* Find the intersection with the combustion chamber geometry */
d3_set(rt_args.ray_org, pos);
d3_set(rt_args.ray_dir, dir);
- d2_set(rt_args.ray_range, range);
+ d2(rt_args.ray_range, 0, DBL_MAX);
rt_args.hit_from = hit_prev; /* Avoid self intersection */
HTRDR(geometry_trace_ray(cmd->geom, &rt_args, &hit_curr));
diff --git a/src/combustion/htrdr_combustion_draw_map.c b/src/combustion/htrdr_combustion_draw_map.c
@@ -18,11 +18,11 @@
#include "combustion/htrdr_combustion_c.h"
#include "core/htrdr_accum.h"
-#include "core/htrdr_camera.h"
#include "core/htrdr_draw_map.h"
#include "core/htrdr_log.h"
#include "core/htrdr_rectangle.h"
+#include <star/scam.h>
#include <star/ssp.h>
#include <rsys/clock_time.h>
@@ -50,9 +50,8 @@ draw_pixel_image
FOR_EACH(isamp, 0, args->spp) {
struct time t0, t1;
- double pix_samp[2];
- double ray_org[3];
- double ray_dir[3];
+ struct scam_sample sample = SCAM_SAMPLE_NULL;
+ struct scam_ray ray = SCAM_RAY_NULL;
double weight;
double usec;
@@ -60,18 +59,19 @@ draw_pixel_image
time_current(&t0);
/* Sample a position into the pixel, in the normalized image plane */
- pix_samp[0] = (double)args->pixel_coord[0] + ssp_rng_canonical(args->rng);
- pix_samp[1] = (double)args->pixel_coord[1] + ssp_rng_canonical(args->rng);
- pix_samp[0] *= args->pixel_normalized_size[0];
- pix_samp[1] *= args->pixel_normalized_size[1];
+ sample.film[0] = (double)args->pixel_coord[0]+ssp_rng_canonical(args->rng);
+ sample.film[1] = (double)args->pixel_coord[1]+ssp_rng_canonical(args->rng);
+ sample.film[0] *= args->pixel_normalized_size[0];
+ sample.film[1] *= args->pixel_normalized_size[1];
+ sample.lens[0] = ssp_rng_canonical(args->rng);
+ sample.lens[1] = ssp_rng_canonical(args->rng);
- /* Generate a ray starting from the pinhole camera and passing through the
- * pixel sample */
- htrdr_camera_ray(cmd->camera, pix_samp, ray_org, ray_dir);
+ /* Generate a camera ray */
+ scam_generate_ray(cmd->camera, &sample, &ray);
/* Backward trace the path */
res = combustion_compute_radiance_sw(cmd, args->ithread, args->rng,
- ray_org, ray_dir, &weight);
+ ray.org, ray.dir, &weight);
if(res != RES_OK) continue; /* Reject the path */
/* End the registration of the per realisation time */
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
@@ -21,6 +21,8 @@
#include "core/htrdr_args.h"
#include "core/htrdr_version.h"
+#include <star/scam.h>
+
#include <rsys/cstr.h>
#include <rsys/double3.h>
#include <rsys/str.h>
@@ -66,8 +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 <= 0 || fov >= 180) {
- fprintf(stderr, "The field of view %g is not in [30, 120].\n", fov);
+ 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_PERSPECTIVE_FOV_EXCLUSIVE_MIN,
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX);
return RES_BAD_ARG;
}
*out_fov = fov;
@@ -75,6 +80,90 @@ parse_fov(const char* str, double* out_fov)
}
static res_T
+parse_focal_length(const char* str, double* out_length)
+{
+ double length;
+ res_T res = RES_OK;
+ ASSERT(str && out_length);
+
+ res = cstr_to_double(str, &length);
+ if(res != RES_OK) {
+ fprintf(stderr, "Invalid focal length `%s'.\n", str);
+ return RES_BAD_ARG;
+ }
+ if(length <= 0) {
+ fprintf(stderr, "Invalid negative or null focal length %g.\n", length);
+ return RES_BAD_ARG;
+ }
+ *out_length = length;
+ return RES_OK;
+}
+
+static res_T
+parse_lens_radius(const char* str, double* out_radius)
+{
+ double radius;
+ res_T res = RES_OK;
+ ASSERT(str && out_radius);
+
+ res = cstr_to_double(str, &radius);
+ if(res != RES_OK) {
+ fprintf(stderr, "Invalid lens radius `%s'.\n", str);
+ return RES_BAD_ARG;
+ }
+ if(radius < 0) {
+ fprintf(stderr, "Invalid negative lens radius %g.\n", radius);
+ return RES_BAD_ARG;
+ }
+ *out_radius = radius;
+ return RES_OK;
+}
+
+static res_T
+parse_focal_dst(const char* str, double* out_dst)
+{
+ double dst;
+ res_T res = RES_OK;
+ ASSERT(str && out_dst);
+
+ res = cstr_to_double(str, &dst);
+ if(res != RES_OK) {
+ fprintf(stderr, "Invalid focal distance `%s'.\n", str);
+ return RES_BAD_ARG;
+ }
+ if(dst <= 0) {
+ fprintf(stderr, "Invalid negative or null focal disrtance %g.\n", dst);
+ return RES_BAD_ARG;
+ }
+ *out_dst = dst;
+ return RES_OK;
+}
+
+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];
@@ -137,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;
@@ -149,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;
}
@@ -159,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
@@ -178,8 +268,70 @@ parse_camera_parameter(const char* str, void* args)
PARSE("up vector", parse_doubleX(val, cam->up, 3));
} else if(!strcmp(key, "fov")) {
PARSE("field-of-view", parse_fov(val, &cam->fov_y));
+ cam->focal_length = -1; /* Overwrite the focal_length */
+ } else if(!strcmp(key, "focal-length")) {
+ PARSE("focal-length", parse_focal_length(val, &cam->focal_length));
+ cam->fov_y = -1; /* Overwrite the fov */
+ } else if(!strcmp(key, "lens-radius")) {
+ PARSE("lens radius", parse_lens_radius(val, &cam->lens_radius));
+ } else if(!strcmp(key, "focal-dst")) {
+ PARSE("focal distance", parse_focal_dst(val, &cam->focal_dst));
+ } else {
+ 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 camera parameter `%s'.\n", key);
+ fprintf(stderr, "Invalid orthographic camera parameter `%s'.\n", key);
res = RES_BAD_ARG;
goto error;
}
@@ -392,10 +544,76 @@ 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;
+
+ if(!cam || !str) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = cstr_parse_list(str, ':', parse_camera_perspective_parameter, cam);
+ if(res != RES_OK) goto error;
+
+ if(cam->focal_length < 0) {
+ ASSERT(cam->fov_y > 0);
+ res = scam_field_of_view_to_focal_length
+ (cam->lens_radius, MDEG2RAD(cam->fov_y), &cam->focal_length);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Cannot compute the focal length from the lens radius %g "
+ "and the field of view %g -- %s.\n",
+ cam->lens_radius,
+ cam->fov_y,
+ res_to_cstr(res));
+ goto error;
+ }
+
+ } else if(cam->fov_y < 0) {
+ ASSERT(cam->focal_length > 0);
+ res = scam_focal_length_to_field_of_view
+ (cam->lens_radius, cam->focal_length, &cam->fov_y);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Cannot compute the field of view from the lens radius %g "
+ "and the focal length %g -- %s.\n",
+ cam->lens_radius,
+ cam->focal_length,
+ res_to_cstr(res));
+ goto error;
+ }
+ cam->fov_y = MRAD2DEG(cam->fov_y);
+ 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_PERSPECTIVE_FOV_EXCLUSIVE_MIN,
+ HTRDR_ARGS_CAMERA_PERSPECTIVE_FOV_EXCLUSIVE_MAX);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
+
+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_parameter, cam);
+ return cstr_parse_list(str, ':', parse_camera_orthographic_parameter, cam);
}
res_T
diff --git a/src/core/htrdr_args.h.in b/src/core/htrdr_args.h.in
@@ -23,21 +23,53 @@
#include <rsys/rsys.h>
-/* Arguments of a pinhole camera sensor */
-struct htrdr_args_camera {
- double position[3]; /* Focal point */
+/* Exclusive bounds of the camera field of view (degrees) */
+#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__
+};
+
+struct htrdr_args_camera_perspective {
+ double position[3]; /* Lens position */
double target[3]; /* Targeted position */
double up[3]; /* Up vector of the camera */
double fov_y; /* Vertical field of view of the camera, in degrees */
+ double lens_radius; /* Radius of the lens. 0 means for pinhole */
+ 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_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 {
@@ -96,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
diff --git a/src/core/htrdr_camera.c b/src/core/htrdr_camera.c
@@ -1,157 +0,0 @@
-/* Copyright (C) 2018, 2019, 2020, 2021 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2018, 2019, 2021 CNRS
- * Copyright (C) 2018, 2019 Université Paul Sabatier
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "core/htrdr.h"
-#include "core/htrdr_camera.h"
-#include "core/htrdr_log.h"
-
-#include <rsys/double3.h>
-#include <rsys/mem_allocator.h>
-#include <rsys/ref_count.h>
-
-struct htrdr_camera {
- /* Orthogonal basis of the camera */
- double axis_x[3];
- double axis_y[3];
- double axis_z[3];
-
- double position[3];
-
- ref_T ref;
- struct htrdr* htrdr;
-};
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static void
-camera_release(ref_T* ref)
-{
- struct htrdr_camera* cam;
- struct htrdr* htrdr;
- ASSERT(ref);
- cam = CONTAINER_OF(ref, struct htrdr_camera, ref);
- htrdr = cam->htrdr;
- MEM_RM(htrdr_get_allocator(htrdr), cam);
- htrdr_ref_put(htrdr);
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-res_T
-htrdr_camera_create
- (struct htrdr* htrdr,
- const double position[3],
- const double target[3],
- const double up[3],
- const double proj_ratio,
- const double fov, /* In radian */
- struct htrdr_camera** out_cam)
-{
- double x[3], y[3], z[3];
- double img_plane_depth;
- struct htrdr_camera* cam = NULL;
- res_T res = RES_OK;
- ASSERT(htrdr && position && target && up && out_cam);
-
- cam = MEM_CALLOC(htrdr_get_allocator(htrdr), 1, sizeof(*cam));
- if(!cam) {
- htrdr_log_err(htrdr, "could not allocate the camera data structure.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&cam->ref);
- htrdr_ref_get(htrdr);
- cam->htrdr = htrdr;
-
- if(fov <= 0 || fov >= PI) {
- htrdr_log_err(htrdr, "invalid horizontal camera field of view `%g'\n", fov);
- res = RES_BAD_ARG;
- goto error;
- }
-
- if(proj_ratio <= 0) {
- htrdr_log_err(htrdr, "invalid projection ratio `%g'\n", proj_ratio);
- res = RES_BAD_ARG;
- goto error;
- }
-
- if(d3_normalize(z, d3_sub(z, target, position)) <= 0
- || d3_normalize(x, d3_cross(x, z, up)) <= 0
- || d3_normalize(y, d3_cross(y, z, x)) <= 0) {
- htrdr_log_err(htrdr,
- "invalid camera point of view:\n"
- " position = %g %g %g\n"
- " target = %g %g %g\n"
- " up = %g %g %g\n",
- SPLIT3(position), SPLIT3(target), SPLIT3(up));
- res = RES_BAD_ARG;
- goto error;
- }
-
- img_plane_depth = 1.0/tan(fov*0.5);
- d3_muld(cam->axis_x, x, proj_ratio);
- d3_set(cam->axis_y, y);
- d3_muld(cam->axis_z, z, img_plane_depth);
- d3_set(cam->position, position);
-
-exit:
- *out_cam = cam;
- return res;
-error:
- if(cam) {
- htrdr_camera_ref_put(cam);
- cam = NULL;
- }
- goto exit;
-}
-
-void
-htrdr_camera_ref_get(struct htrdr_camera* cam)
-{
- ASSERT(cam);
- ref_get(&cam->ref);
-}
-
-void
-htrdr_camera_ref_put(struct htrdr_camera* cam)
-{
- ASSERT(cam);
- ref_put(&cam->ref, camera_release);
-}
-
-void
-htrdr_camera_ray
- (const struct htrdr_camera* cam,
- const double sample[2],
- double ray_org[3],
- double ray_dir[3])
-{
- double x[3], y[3], len;
- (void)len;
- ASSERT(cam && sample && ray_org && ray_dir);
- ASSERT(sample[0] >= 0 || sample[0] < 1);
- ASSERT(sample[1] >= 0 || sample[1] < 1);
- d3_muld(x, cam->axis_x, sample[0]*2-1);
- d3_muld(y, cam->axis_y, sample[1]*2-1);
- d3_add(ray_dir, d3_add(ray_dir, x, y), cam->axis_z);
- len = d3_normalize(ray_dir, ray_dir);
- ASSERT(len >= 1.e-6);
- d3_set(ray_org, cam->position);
-}
-
diff --git a/src/core/htrdr_camera.h b/src/core/htrdr_camera.h
@@ -1,58 +0,0 @@
-/* Copyright (C) 2018, 2019, 2020, 2021 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2018, 2019, 2021 CNRS
- * Copyright (C) 2018, 2019 Université Paul Sabatier
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef HTRDR_CAMERA_H
-#define HTRDR_CAMERA_H
-
-#include "core/htrdr.h"
-#include <rsys/rsys.h>
-
-/* Forward declarations */
-struct htrdr;
-struct htrdr_camera;
-
-BEGIN_DECLS
-
-HTRDR_CORE_API res_T
-htrdr_camera_create
- (struct htrdr* htrdr,
- const double position[3],
- const double target[3],
- const double up[3],
- const double proj_ratio, /* Width / Height */
- const double fov, /* In radian */
- struct htrdr_camera** cam);
-
-HTRDR_CORE_API void
-htrdr_camera_ref_get
- (struct htrdr_camera* cam);
-
-HTRDR_CORE_API void
-htrdr_camera_ref_put
- (struct htrdr_camera* cam);
-
-HTRDR_CORE_API void
-htrdr_camera_ray
- (const struct htrdr_camera* cam,
- const double sample[2], /* In [0, 1[ */
- double ray_org[3],
- double ray_dir[3]);
-
-END_DECLS
-
-#endif /* HTRDR_CAMERA_H */
-
diff --git a/src/core/htrdr_draw_map.c b/src/core/htrdr_draw_map.c
@@ -42,7 +42,7 @@
#define RNG_SEQUENCE_SIZE 10000
#define TILE_MCODE_NULL UINT32_MAX
-#define TILE_SIZE 32 /* Definition in X & Y of a tile */
+#define TILE_SIZE 8 /* Definition in X & Y of a tile */
STATIC_ASSERT(IS_POW2(TILE_SIZE), TILE_SIZE_must_be_a_power_of_2);
/* Tile of row ordered image pixels */
diff --git a/src/core/htrdr_sensor.h b/src/core/htrdr_sensor.h
@@ -20,7 +20,7 @@
/* Forward declarations */
struct htrdr;
-struct htrdr_camera;
+struct scam;
struct htrdr_rectangle;
struct ssp_rng;
@@ -30,7 +30,7 @@ enum htrdr_sensor_type {
};
struct htrdr_sensor {
- struct htrdr_camera* camera;
+ struct scam* camera;
struct htrdr_rectangle* rectangle;
enum htrdr_sensor_type type;
};