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:
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);
+}