From 363f15fb00549c5d123ae086bc5a10840e9c9794 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Fri, 23 Jul 2021 21:56:55 -0700 Subject: [PATCH] camera: implement builder pattern on Camera and add it to prelude. --- rtchallenge/src/camera.rs | 50 ++++++++++++++++++++++++++++++++++++++- rtchallenge/src/lib.rs | 1 + 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/rtchallenge/src/camera.rs b/rtchallenge/src/camera.rs index 2813182..b0342f1 100644 --- a/rtchallenge/src/camera.rs +++ b/rtchallenge/src/camera.rs @@ -7,6 +7,7 @@ use std::{ thread, }; +use derive_builder::Builder; use rand::Rng; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use serde::Deserialize; @@ -42,21 +43,68 @@ impl FromStr for RenderStrategy { } } -#[derive(Clone, Default)] +#[derive(Builder, Clone, Debug, Default)] +#[builder(setter(skip), build_fn(skip))] pub struct Camera { + #[builder(setter(skip = "false"))] hsize: usize, + #[builder(setter(skip = "false"))] vsize: usize, + #[builder(setter(skip = "false"))] field_of_view: Float, + #[builder(setter(skip = "false"))] transform: Matrix4x4, inverse_transform: Matrix4x4, pixel_size: Float, half_width: Float, half_height: Float, + #[builder(setter(skip = "false"))] pub render_strategy: RenderStrategy, /// 0 renders from the center of the pixel, 1 or higher is random sampling of the pixel. + #[builder(setter(skip = "false"))] pub samples_per_pixel: usize, } +impl CameraBuilder { + pub fn build(&self) -> Result { + let hsize = match self.hsize { + Some(ref value) => Clone::clone(value), + None => { + return Err(Into::into(::derive_builder::UninitializedFieldError::from( + "hsize", + ))) + } + }; + let vsize = match self.vsize { + Some(ref value) => Clone::clone(value), + None => { + return Err(Into::into(::derive_builder::UninitializedFieldError::from( + "vsize", + ))) + } + }; + let field_of_view = match self.field_of_view { + Some(ref value) => Clone::clone(value), + None => { + return Err(Into::into(::derive_builder::UninitializedFieldError::from( + "field_of_view", + ))) + } + }; + let mut c = Camera::new(hsize, vsize, field_of_view); + if let Some(transform) = self.transform { + c.set_transform(transform); + } + if let Some(render_strategy) = self.render_strategy { + c.render_strategy = render_strategy; + } + if let Some(samples_per_pixel) = self.samples_per_pixel { + c.samples_per_pixel = samples_per_pixel; + } + Ok(c) + } +} + enum Request { Line { width: usize, y: usize }, } diff --git a/rtchallenge/src/lib.rs b/rtchallenge/src/lib.rs index f8cf121..96058bb 100644 --- a/rtchallenge/src/lib.rs +++ b/rtchallenge/src/lib.rs @@ -40,6 +40,7 @@ pub use float::Float; pub mod prelude { pub use crate::{ + camera::{Camera, CameraBuilder}, lights::{PointLight, PointLightBuilder}, materials::{Material, MaterialBuilder}, matrices::{identity, rotation_x, rotation_y, rotation_z, scaling, shearing, translation},