star-camera

Camera models
git clone git://git.meso-star.fr/star-camera.git
Log | Files | Refs | README | LICENSE

commit d4c87487761880a1037e984ed7fe4180090059a2
parent 0d482412d2db4d86d212c302f10fe219f8f37ec7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu,  1 Jul 2021 12:50:31 +0200

Implement the scam_generate_ray function

Diffstat:
Msrc/scam.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/scam.h | 21+++++++++++++++++++++
Msrc/scam_c.h | 7++++++-
Msrc/scam_pinhole.c | 24++++++++++++++++++++++++
4 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/src/scam.c b/src/scam.c @@ -22,6 +22,30 @@ /******************************************************************************* * Helper functions ******************************************************************************/ +static INLINE int +check_sample + (const struct scam* cam, + const struct scam_sample* sample) +{ + ASSERT(cam); + if(!sample) return 0; + + if(sample->film[0] < 0 || sample->film[1] >= 1) { + log_err(cam, + "Invalid camera film sample (%g, %g). It must be in [0, 1[^2.\n", + SPLIT2(sample->film)); + return 0; + } + + if(sample->lens[0] < 0 || sample->lens[1] >= 1) { + log_err(cam, + "Invalid camera lens sample (%g, %g). It must be in [0, 1[^2.\n", + SPLIT2(sample->lens)); + return 0; + } + return 1; +} + static void release_scam(ref_T* ref) { @@ -35,6 +59,32 @@ release_scam(ref_T* ref) * Exported functions ******************************************************************************/ res_T +scam_generate_ray + (const struct scam* cam, + const struct scam_sample* sample, + struct scam_ray* ray) +{ + res_T res = RES_OK; + + if(!cam || !ray || !check_sample(cam, sample)) { + res = RES_BAD_ARG; + goto error; + } + + switch(cam->type) { + case SCAM_PINHOLE: + pinhole_generate_ray(cam, sample, ray); + break; + default: FATAL("Unreachable code.\n"); break; + } + +exit: + return res; +error: + goto exit; +} + +res_T scam_ref_get(struct scam* cam) { if(!cam) return RES_BAD_ARG; diff --git a/src/scam.h b/src/scam.h @@ -42,6 +42,21 @@ enum scam_type { SCAM_NONE = SCAM_TYPES_COUNT__ }; +/* Samples used to generate a camera ray */ +struct scam_sample { + double film[2]; /* Samples on the image plane in [0, 1[^2 */ + double lens[2]; /* Samples on the lens */ +}; +#define SCAM_SAMPLE_NULL__ {{0,0},{0,0}} +static const struct scam_sample SCAM_SAMPLE_NULL = SCAM_SAMPLE_NULL__; + +struct scam_ray { + double org[3]; + double dir[3]; +}; +#define SCAM_RAY_NULL__ {{0,0,0},{0,0,0}} +static const struct scam_ray SCAM_RAY_NULL = SCAM_RAY_NULL__; + struct scam_pinhole_args { double position[3]; /* Focal point */ double target[3]; /* Targeted point. target-position = image plane normal */ @@ -80,6 +95,12 @@ scam_create_pinhole struct scam** camera); SCAM_API res_T +scam_generate_ray + (const struct scam* cam, + const struct scam_sample* sample, + struct scam_ray* ray); + +SCAM_API res_T scam_ref_get (struct scam* camera); diff --git a/src/scam_c.h b/src/scam_c.h @@ -45,7 +45,6 @@ struct scam { ref_T ref; }; - extern LOCAL_SYM res_T camera_create (struct logger* logger, /* NULL <=> use builtin logger */ @@ -54,4 +53,10 @@ camera_create const enum scam_type type, struct scam** scam); +extern LOCAL_SYM void +pinhole_generate_ray + (const struct scam* cam, + const struct scam_sample* sample, + struct scam_ray* ray); + #endif /* SCAM_C_H */ diff --git a/src/scam_pinhole.c b/src/scam_pinhole.c @@ -108,3 +108,27 @@ error: goto exit; } +/******************************************************************************* + * Local function + ******************************************************************************/ +void +pinhole_generate_ray + (const struct scam* cam, + const struct scam_sample* sample, + struct scam_ray* ray) +{ + double x[3], y[3], len; + (void)len; + + ASSERT(cam && sample && ray); + ASSERT(cam->type == SCAM_PINHOLE); + ASSERT(0 <= sample->film[0] && sample->film[0] < 1); + ASSERT(0 <= sample->film[1] && sample->film[1] < 1); + + d3_muld(x, cam->param.pinhole.axis_x, sample->film[0]*2-1); + d3_muld(y, cam->param.pinhole.axis_y, sample->film[1]*2-1); + d3_add(ray->dir, d3_add(ray->dir, x, y), cam->param.pinhole.axis_z); + len = d3_normalize(ray->dir, ray->dir); + ASSERT(len >= 1.e-6); + d3_set(ray->org, cam->param.pinhole.position); +}