camera: add basic Camera object.

This commit is contained in:
Bill Thiede 2021-07-17 21:22:07 -07:00
parent 125c96c25f
commit 39f7f77b74
2 changed files with 74 additions and 0 deletions

73
rtchallenge/src/camera.rs Normal file
View File

@ -0,0 +1,73 @@
use crate::matrices::Matrix4x4;
pub struct Camera {
hsize: usize,
vsize: usize,
field_of_view: f32,
transform: Matrix4x4,
pixel_size: f32,
half_width: f32,
half_height: f32,
}
impl Camera {
/// Create a camera with a canvas of pixel hsize (height) and vsize (width)
/// with the given field of view (in radians).
///
/// # Examples
/// ```
/// use std::f32::consts::PI;
///
/// use rtchallenge::{camera::Camera, matrices::Matrix4x4};
///
/// let hsize = 160;
/// let vsize = 120;
/// let field_of_view = PI / 2.;
/// let c = Camera::new(hsize, vsize, field_of_view);
/// assert_eq!(c.hsize(), 160);
/// assert_eq!(c.vsize(), 120);
/// assert_eq!(c.transform(), Matrix4x4::identity());
///
/// // Pixel size for a horizontal canvas.
/// let c = Camera::new(200, 150, PI / 2.);
/// assert_eq!(c.pixel_size(), 0.01);
///
/// // Pixel size for a horizontal canvas.
/// let c = Camera::new(150, 200, PI / 2.);
/// assert_eq!(c.pixel_size(), 0.01);
/// ```
pub fn new(hsize: usize, vsize: usize, field_of_view: f32) -> Camera {
let half_view = (field_of_view / 2.).tan();
let aspect = hsize as f32 / vsize as f32;
let (half_width, half_height) = if aspect >= 1. {
(half_view, half_view / aspect)
} else {
(half_view * aspect, half_view)
};
let pixel_size = 2. * half_width / hsize as f32;
Camera {
hsize,
vsize,
field_of_view,
transform: Matrix4x4::identity(),
pixel_size,
half_height,
half_width,
}
}
pub fn hsize(&self) -> usize {
self.hsize
}
pub fn vsize(&self) -> usize {
self.vsize
}
pub fn field_of_view(&self) -> f32 {
self.field_of_view
}
pub fn transform(&self) -> Matrix4x4 {
self.transform
}
pub fn pixel_size(&self) -> f32 {
self.pixel_size
}
}

View File

@ -1,3 +1,4 @@
pub mod camera;
pub mod canvas;
pub mod intersections;
pub mod lights;