61 lines
1.6 KiB
Rust
61 lines
1.6 KiB
Rust
use super::{Point3, Ray, Vec3};
|
|
|
|
pub struct Camera {
|
|
origin: Point3,
|
|
lower_left_corner: Point3,
|
|
horizontal: Vec3,
|
|
vertical: Vec3,
|
|
u: Vec3,
|
|
v: Vec3,
|
|
w: Vec3,
|
|
lens_radius: f64,
|
|
}
|
|
|
|
impl Camera {
|
|
pub fn new(
|
|
lookfrom: Point3,
|
|
lookat: Point3,
|
|
vup: Vec3,
|
|
vfov: f64, // vertical field of view in degrees
|
|
aspect_ratio: f64,
|
|
aperture: f64,
|
|
focus_dist: f64,
|
|
) -> Self {
|
|
let theta = vfov.to_radians();
|
|
let h = (theta / 2.0).tan();
|
|
let viewport_height = 2.0 * h;
|
|
let viewport_width = aspect_ratio * viewport_height;
|
|
|
|
let w = Vec3::unit_vector(lookfrom - lookat);
|
|
let u = Vec3::unit_vector(Vec3::cross(vup, w));
|
|
let v = Vec3::cross(w, u);
|
|
|
|
let origin = lookfrom;
|
|
let horizontal = focus_dist * viewport_width * u;
|
|
let vertical = focus_dist * viewport_height * v;
|
|
let lower_left_corner = origin - horizontal / 2.0 - vertical / 2.0 - focus_dist * w;
|
|
|
|
let lens_radius = aperture / 2.0;
|
|
|
|
return Camera {
|
|
origin,
|
|
horizontal,
|
|
vertical,
|
|
lower_left_corner,
|
|
u,
|
|
v,
|
|
w,
|
|
lens_radius,
|
|
};
|
|
}
|
|
|
|
pub fn get_ray(&self, u: f64, v: f64) -> Ray {
|
|
let rd = self.lens_radius * Vec3::random_in_unit_disk();
|
|
let offset = rd.x() * self.u + rd.y() * self.v;
|
|
|
|
return Ray::new(
|
|
self.origin + offset,
|
|
self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin - offset,
|
|
);
|
|
}
|
|
}
|