diff options
Diffstat (limited to 'src/camera.rs')
-rw-r--r-- | src/camera.rs | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/src/camera.rs b/src/camera.rs index 8090bde..7564c12 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,25 +1,44 @@ +use cgmath::prelude::*; use cgmath::{Vector3, vec3}; +use rand::prelude::*; use crate::ray::Ray; +use crate::utils::random_in_unit_disk; pub struct Camera { origin: Vector3<f64>, lower_left_corner: Vector3<f64>, horizontal: Vector3<f64>, - vertical: Vector3<f64> + vertical: Vector3<f64>, + u: Vector3<f64>, + v: Vector3<f64>, + w: Vector3<f64>, + lens_radius: f64 } impl Camera { - pub fn new() -> Camera { + pub fn new(lookfrom: &Vector3<f64>, lookat: &Vector3<f64>, vup: &Vector3<f64>, + vfov: f64, aspect: f64, aperture: f64, focus_dist: f64) -> Camera { + let lens_radius = aperture / 2.0; + let half_height = (vfov / 2.0).tan(); + let half_width = aspect * half_height; + let w = (lookfrom - lookat).normalize(); + let u = vup.cross(w).normalize(); + let v = w.cross(u); Camera { - origin: vec3(0.0, 0.0, 0.0), - lower_left_corner: vec3(-2.0, -1.0, -1.0), - horizontal: vec3(4.0, 0.0, 0.0), - vertical: vec3(0.0, 2.0, 0.0) + origin: *lookfrom, + lower_left_corner: lookfrom - half_width * focus_dist * u + - half_height * focus_dist * v - focus_dist * w, + horizontal: 2.0 * half_width * focus_dist * u, + vertical: 2.0 * half_height * focus_dist * v, + lens_radius, + u, v, w } } - pub fn get_ray(&self, u: f64, v: f64) -> Ray { - Ray::new(self.origin, - self.lower_left_corner + u * self.horizontal + v * self.vertical) + pub fn get_ray(&self, rng: &mut ThreadRng, s: f64, t: f64) -> Ray { + let rd = self.lens_radius * random_in_unit_disk(rng); + let offset = self.u * rd.x + self.v * rd.y; + Ray::new(self.origin + offset, + self.lower_left_corner + s * self.horizontal + t * self.vertical - self.origin - offset) } } |