del_canvas_core/
cam3.rs

1use num_traits::AsPrimitive;
2
3pub struct Camera3<T> {
4    pub w: usize,
5    pub h: usize,
6    o: nalgebra::Vector3<T>,
7    d: nalgebra::Vector3<T>,
8    cx: nalgebra::Vector3<T>,
9    cy: nalgebra::Vector3<T>,
10}
11
12impl<T> Camera3<T>
13where
14    T: nalgebra::RealField + 'static + Copy,
15    f64: AsPrimitive<T>,
16    usize: AsPrimitive<T>,
17{
18    pub fn new(w: usize, h: usize, o: nalgebra::Vector3<T>, d: nalgebra::Vector3<T>) -> Self {
19        let d = d.normalize();
20        let cx =
21            nalgebra::Vector3::<T>::new(w.as_() * 0.5135.as_() / h.as_(), T::zero(), T::zero());
22        let cy = cx.cross(&d).normalize() * 0.5135.as_();
23        Camera3 { w, h, o, d, cx, cy }
24    }
25
26    pub fn ray(&self, x0: T, y0: T) -> (nalgebra::Vector3<T>, nalgebra::Vector3<T>) {
27        let d = self.cx * (x0 / self.w.as_() - 0.5.as_())
28            + self.cy * (y0 / self.h.as_() - 0.5.as_())
29            + self.d;
30        (self.o + d * 140.as_(), d.normalize())
31    }
32}
33
34pub fn ray3_homogeneous(
35    pix_coord: (usize, usize),
36    image_size: &(usize, usize),
37    transform_ndc_to_world: &[f32; 16],
38) -> ([f32; 3], [f32; 3]) {
39    let x0 = 2. * (pix_coord.0 as f32 + 0.5f32) / (image_size.0 as f32) - 1.;
40    let y0 = 1. - 2. * (pix_coord.1 as f32 + 0.5f32) / (image_size.1 as f32);
41    let ray_org =
42        del_geo_core::mat4_col_major::transform_homogeneous(transform_ndc_to_world, &[x0, y0, 1.])
43            .unwrap();
44    let ray_dir = del_geo_core::vec3::sub(
45        &del_geo_core::mat4_col_major::transform_homogeneous(
46            transform_ndc_to_world,
47            &[x0, y0, -1.],
48        )
49        .unwrap(),
50        &del_geo_core::mat4_col_major::transform_homogeneous(transform_ndc_to_world, &[x0, y0, 1.])
51            .unwrap(),
52    );
53    (ray_org, ray_dir)
54}