summaryrefslogtreecommitdiff
path: root/src/camera.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera.rs')
-rw-r--r--src/camera.rs124
1 files changed, 70 insertions, 54 deletions
diff --git a/src/camera.rs b/src/camera.rs
index 587e75c..1b96575 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -26,78 +26,94 @@ pub struct Camera {
impl Default for Camera {
fn default() -> Self {
- let aspect_ratio = ASPECT_RATIO;
+ Self::new(
+ ASPECT_RATIO,
+ IMG_WIDTH,
+ VFOV,
+ LOOK_FROM,
+ LOOK_AT,
+ VUP,
+ SAMPLES_PER_PIXEL,
+ FOCUS_DIST,
+ DEFOCUS_ANGLE,
+ MAX_DEPTH
+ )
+ }
+}
- let image_width = IMG_WIDTH;
- let image_height = get_image_height(image_width, aspect_ratio);
+impl Camera {
+ pub fn new(
+ aspect_ratio: f32,
+ image_width: usize,
+ vfov: f32,
+ look_from: Point3,
+ look_at: Point3,
+ vup: Vec3,
+ samples_per_pixel: usize,
+ focus_dist: f32,
+ defocus_angle: f32,
+ max_depth: usize,
+ ) -> Self {
+ let mut new_camera = Self {
+ aspect_ratio,
+ image_width,
+ image_height: 1,
+ center: Point3::new(0.0, 0.0, 0.0),
+ pixel_upper_left: Point3::new(0.0, 0.0, 0.0),
+ delta_pixel_u: Vec3::new(0.0, 0.0, 0.0),
+ delta_pixel_v: Vec3::new(0.0, 0.0, 0.0),
+ samples_per_pixel,
+ pixel_samples_scale: 1.0,
+ max_depth,
+ vfov,
+ look_from,
+ look_at,
+ vup,
+ defocus_angle,
+ focus_dist,
+ defocus_disk_u: Vec3::new(0.0, 0.0, 0.0),
+ defocus_disk_v: Vec3::new(0.0, 0.0, 0.0),
+ };
- let vfov = VFOV;
- let look_from = LOOK_FROM;
- let look_at = LOOK_AT;
- let vup = VUP;
+ new_camera.compute_dependent_fields();
+ new_camera
+ }
- let center = look_from;
- // let focal_length = look_from.sub(&look_at).mag();
- let theta = deg2rad(vfov);
- let h = (theta / 2.0).tan();
+ fn compute_dependent_fields(&mut self) {
+ self.image_height = get_image_height(self.image_width, self.aspect_ratio);
+ self.center = self.look_from;
- let w = look_from.sub(&look_at).unit();
- let u = vup.cross_prod(&w).unit();
- let v = w.cross_prod(&u).unit();
+ self.pixel_samples_scale = 1.0 / self.samples_per_pixel as f32;
- let samples_per_pixel = SAMPLES_PER_PIXEL;
- let pixel_samples_scale = 1.0 / samples_per_pixel as f32;
+ let theta = deg2rad(self.vfov);
+ let h = (theta / 2.0).tan();
- let focus_dist = FOCUS_DIST;
- let defocus_angle = DEFOCUS_ANGLE;
+ let w = self.look_from.sub(&self.look_at).unit();
+ let u = self.vup.cross_prod(&w).unit();
+ let v = w.cross_prod(&u).unit();
- let viewport_height = 2.0 * h * focus_dist;
- let viewport_width = viewport_height * (image_width as f32 / image_height as f32);
+ let viewport_height = 2.0 * h * self.focus_dist;
+ let viewport_width = viewport_height * (self.image_width as f32 / self.image_height as f32);
let viewport_u = u.scalar_mul(viewport_width);
let viewport_v = v.scalar_mul(-1.0).scalar_mul(viewport_height);
- let delta_pixel_u = viewport_u.scalar_mul(1.0 / image_width as f32);
- let delta_pixel_v = viewport_v.scalar_mul(1.0 / image_height as f32);
+ self.delta_pixel_u = viewport_u.scalar_mul(1.0 / self.image_width as f32);
+ self.delta_pixel_v = viewport_v.scalar_mul(1.0 / self.image_height as f32);
- let viewport_upper_left = center
- .sub(&w.scalar_mul(focus_dist))
+ let viewport_upper_left = self.center
+ .sub(&w.scalar_mul(self.focus_dist))
.sub(&viewport_u.scalar_mul(0.5))
.sub(&viewport_v.scalar_mul(0.5));
- let pixel_upper_left = viewport_upper_left.add(
- &delta_pixel_u.add(&delta_pixel_v).scalar_mul(0.5)
+ self.pixel_upper_left = viewport_upper_left.add(
+ &self.delta_pixel_u.add(&self.delta_pixel_v).scalar_mul(0.5)
);
- let defocus_radius = focus_dist * deg2rad(defocus_angle / 2.0).tan();
- let defocus_disk_u = u.scalar_mul(defocus_radius);
- let defocus_disk_v = v.scalar_mul(defocus_radius);
-
- let max_depth = MAX_DEPTH;
-
- Self {
- aspect_ratio,
- image_width,
- image_height,
- center,
- pixel_upper_left,
- delta_pixel_u,
- delta_pixel_v,
- samples_per_pixel,
- pixel_samples_scale,
- max_depth,
- vfov,
- look_from,
- look_at,
- vup,
- defocus_angle,
- focus_dist,
- defocus_disk_u,
- defocus_disk_v,
- }
+ let defocus_radius = self.focus_dist * deg2rad(self.defocus_angle / 2.0).tan();
+ self.defocus_disk_u = u.scalar_mul(defocus_radius);
+ self.defocus_disk_v = v.scalar_mul(defocus_radius);
}
-}
-impl Camera {
fn get_ray(&self, i: usize, j: usize) -> Ray {
let offset = sample_square();
let pixel_sample = self.pixel_upper_left