1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
use crate::{ Vector, Real, Ray, random_in_unit_disk }; pub struct Camera { pub ratio : Real, pub vxsize: Real, pub vysize: Real, pub lrad : Real, ori : Vector, hor : Vector, ver : Vector, lol : Vector, u : Vector, v : Vector } impl Camera { pub fn new(ratio: Real, vfov: Real, lrad: Real, fdist: Real, lookfrom: Vector, lookat: Vector, vup: Vector) -> Self { let h = (vfov / 2.0).tan(); let (vxsize, vysize) = (2.0 * h * ratio, 2.0 * h); let w = (lookfrom - lookat).normalize(); let u = vup.cross(&w).normalize(); let v = w.cross(&u); let ori = lookfrom; let hor = vxsize * u * fdist; let ver = vysize * v * fdist; let lol = ori - hor / 2.0 - ver / 2.0 - fdist * w; Self { ratio, vxsize, vysize, lrad, ori, hor, ver, lol, u, v } } pub fn get_ray(&self, (s, t): (Real, Real)) -> Ray { let rd = self.lrad * random_in_unit_disk(); let offset = self.u * rd.x + self.v * rd.y; Ray::new(self.ori + offset, self.lol + s * self.hor + t * self.ver - self.ori - offset) } }