diff options
Diffstat (limited to 'racer-tracer/src/camera.rs')
| -rw-r--r-- | racer-tracer/src/camera.rs | 98 |
1 files changed, 65 insertions, 33 deletions
diff --git a/racer-tracer/src/camera.rs b/racer-tracer/src/camera.rs index 1ac2396..438c18d 100644 --- a/racer-tracer/src/camera.rs +++ b/racer-tracer/src/camera.rs @@ -1,5 +1,4 @@ -use glam::{f32::Vec3 as FVec3, Quat}; - +use crate::config::CameraConfig; use crate::image::Image; use crate::ray::Ray; use crate::util::{degrees_to_radians, random_in_unit_disk}; @@ -19,6 +18,7 @@ pub struct Camera { pub scene_up: Vec3, pub lens_radius: f64, pub focus_distance: f64, + pub aspect_ratio: f64, } impl Camera { @@ -56,9 +56,36 @@ impl Camera { scene_up, lens_radius: aperture * 0.5, focus_distance, + aspect_ratio: image.aspect_ratio, } } + pub fn set_pos(&mut self, pos: Vec3) { + self.origin = pos; + self.update_corner(); + } + + pub fn set_look_at(&mut self, look_at: Vec3) { + self.forward = (self.origin - look_at).unit_vector(); + self.update_directions(); + } + + pub fn set_fov(&mut self, vfov: f64) { + let h = (degrees_to_radians(vfov) / 2.0).tan(); + self.viewport_height = 2.0 * h; + self.viewport_width = self.aspect_ratio * self.viewport_height; + self.update_viewport(); + } + + pub fn set_aperture(&mut self, aperture: f64) { + self.lens_radius = aperture * 0.5; + } + + pub fn set_focus_distance(&mut self, focus_distance: f64) { + self.focus_distance = focus_distance; + self.update_viewport(); + } + pub fn get_ray(&self, u: f64, v: f64) -> Ray { let ray_direction = self.lens_radius * random_in_unit_disk(); let offset = self.right * ray_direction.x() + self.up * ray_direction.y(); @@ -78,48 +105,53 @@ impl Camera { self.update_corner() } - fn update_corner(&mut self) { - self.upper_left_corner = self.origin + self.vertical / 2.0 - - self.horizontal / 2.0 - - self.focus_distance * self.forward; + pub fn rotate(&mut self, right_move: f64, up_move: f64) { + self.forward.rotate(up_move, &self.right); + self.forward.rotate(right_move, &self.scene_up); + self.update_directions(); + self.update_corner(); + } + + pub fn rotate_up(&mut self, degrees: f64) { + self.forward.rotate(degrees, &self.right); + self.update_directions(); + } + + pub fn rotate_right(&mut self, degrees: f64) { + self.forward.rotate(degrees, &self.scene_up); + self.update_directions(); } fn update_directions(&mut self) { self.forward.unit_vector(); self.right = self.scene_up.cross(&self.forward).unit_vector(); self.up = self.forward.cross(&self.right); - self.horizontal = self.focus_distance * self.viewport_width * self.right; - self.vertical = self.focus_distance * self.viewport_height * self.up; + self.update_viewport(); } - pub fn rotate(&mut self, up: f64, right: f64) { - self.forward = (Quat::from_axis_angle(self.right.into(), right as f32) - * Quat::from_axis_angle(self.scene_up.into(), up as f32) - * FVec3::from(self.forward)) - .into(); - - self.forward.unit_vector(); - self.update_directions(); - self.update_corner(); + fn update_viewport(&mut self) { + self.horizontal = self.focus_distance * self.viewport_width * self.right; + self.vertical = self.focus_distance * self.viewport_height * self.up; + self.update_corner() } - pub fn rotate_up(&mut self, go: f64) { - self.forward = (Quat::from_axis_angle(self.right.into(), go as f32) - * FVec3::from(self.forward)) - .into(); - - self.forward.unit_vector(); - self.update_directions(); - self.update_corner(); + fn update_corner(&mut self) { + self.upper_left_corner = self.origin + self.vertical / 2.0 + - self.horizontal / 2.0 + - self.focus_distance * self.forward; } +} - pub fn rotate_right(&mut self, go: f64) { - self.forward = (Quat::from_axis_angle(self.scene_up.into(), -go as f32) - * FVec3::from(self.forward)) - .into(); - - self.forward.unit_vector(); - self.update_directions(); - self.update_corner(); +impl From<(&Image, &CameraConfig)> for Camera { + fn from((image, c): (&Image, &CameraConfig)) -> Self { + Self::new( + c.pos, + c.look_at, + Vec3::new(0.0, 1.0, 0.0), + c.vfov, + image, + c.aperture, + c.focus_distance, + ) } } |
