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