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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
use crate::ray::Ray;
use crate::utils::random_in_unit_disk;
use cgmath::prelude::*;
use cgmath::{vec3, Vector3};
use rand::prelude::*;
pub struct Camera {
origin: Vector3<f64>,
lower_left_corner: Vector3<f64>,
horizontal: Vector3<f64>,
vertical: Vector3<f64>,
u: Vector3<f64>,
v: Vector3<f64>,
w: Vector3<f64>,
lens_radius: f64,
time0: f64,
time1: f64,
}
impl Camera {
pub fn new(
lookfrom: &Vector3<f64>,
lookat: &Vector3<f64>,
vup: &Vector3<f64>,
vfov: f64,
aspect: f64,
aperture: f64,
focus_dist: f64,
time0: f64,
time1: f64,
) -> Camera {
let lens_radius = aperture / 2.0;
let half_height = (vfov / 2.0).tan();
let half_width = aspect * half_height;
let w = (lookfrom - lookat).normalize();
let u = vup.cross(w).normalize();
let v = w.cross(u);
Camera {
origin: *lookfrom,
lower_left_corner: lookfrom
- half_width * focus_dist * u
- half_height * focus_dist * v
- focus_dist * w,
horizontal: 2.0 * half_width * focus_dist * u,
vertical: 2.0 * half_height * focus_dist * v,
lens_radius,
u,
v,
w,
time0,
time1,
}
}
pub fn get_ray(&self, rng: &mut ThreadRng, s: f64, t: f64) -> Ray {
let rd = self.lens_radius * random_in_unit_disk(rng);
let offset = self.u * rd.x + self.v * rd.y;
Ray::new(
self.origin + offset,
self.lower_left_corner + s * self.horizontal + t * self.vertical - self.origin - offset,
rng.gen_range(self.time0, self.time1),
)
}
}
|