84 lines
2.2 KiB
Rust
84 lines
2.2 KiB
Rust
use std::f32::consts::PI;
|
|
|
|
use rand::{self, Rng};
|
|
|
|
use crate::{
|
|
ray::Ray,
|
|
vec3::{cross, Vec3},
|
|
};
|
|
|
|
fn random_in_unit_disk() -> Vec3 {
|
|
let mut rng = rand::thread_rng();
|
|
let v = Vec3::new(1., 1., 0.);
|
|
loop {
|
|
let p = 2. * Vec3::new(rng.gen(), rng.gen(), 0.) - v;
|
|
if p.squared_length() < 1. {
|
|
return p;
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Camera {
|
|
origin: Vec3,
|
|
lower_left_corner: Vec3,
|
|
horizontal: Vec3,
|
|
vertical: Vec3,
|
|
u: Vec3,
|
|
v: Vec3,
|
|
lens_radius: f32,
|
|
time_min: f32,
|
|
time_max: f32,
|
|
}
|
|
|
|
impl Camera {
|
|
// Parameters match the example C++ code.
|
|
#[allow(clippy::too_many_arguments)]
|
|
// vfov is top to bottom in degrees
|
|
pub fn new(
|
|
lookfrom: Vec3,
|
|
lookat: Vec3,
|
|
vup: Vec3,
|
|
vfov: f32,
|
|
aspect: f32,
|
|
aperture: f32,
|
|
focus_dist: f32,
|
|
time_min: f32,
|
|
time_max: f32,
|
|
) -> Camera {
|
|
let theta = vfov * PI / 180.;
|
|
let half_height = (theta / 2.).tan();
|
|
let half_width = aspect * half_height;
|
|
let origin = lookfrom;
|
|
let w = (lookfrom - lookat).unit_vector();
|
|
let u = cross(vup, w).unit_vector();
|
|
let v = cross(w, u);
|
|
Camera {
|
|
lower_left_corner: origin
|
|
- half_width * focus_dist * u
|
|
- half_height * focus_dist * v
|
|
- focus_dist * w,
|
|
horizontal: 2. * half_width * focus_dist * u,
|
|
vertical: 2. * half_height * focus_dist * v,
|
|
origin,
|
|
u: cross(vup, w).unit_vector(),
|
|
v: cross(w, u),
|
|
lens_radius: aperture / 2.,
|
|
time_min,
|
|
time_max,
|
|
}
|
|
}
|
|
|
|
pub fn get_ray(&self, u: f32, v: f32) -> Ray {
|
|
let mut rng = rand::thread_rng();
|
|
let rd = self.lens_radius * random_in_unit_disk();
|
|
let offset = self.u * rd.x + self.v * rd.y;
|
|
let time = self.time_min + rng.gen::<f32>() * (self.time_max - self.time_min);
|
|
Ray::new(
|
|
self.origin + offset,
|
|
self.lower_left_corner + self.horizontal * u + self.vertical * v - self.origin - offset,
|
|
time,
|
|
)
|
|
}
|
|
}
|