summaryrefslogtreecommitdiff
path: root/racer-tracer/src/camera.rs
diff options
context:
space:
mode:
Diffstat (limited to 'racer-tracer/src/camera.rs')
-rw-r--r--racer-tracer/src/camera.rs98
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,
+ )
}
}