use alloc::vec::Vec; use cgmath::{Matrix4, Vector3, Vector4, num_traits::Num}; pub struct Ray { pub(crate) origin: Vector3, pub(crate) direction: Vector3, } pub fn construct_primary_rays( (width, height): (usize, usize), (pixel_x_coord, pixel_y_coord): (usize, usize), cam_to_world_matrix: &Matrix4, focal_length: f32, rays_per_pixel: usize, ) -> Vec { let mut rays: Vec = Vec::with_capacity(rays_per_pixel); //generate all rays for this pixel and add them to the rays vector for _ in 0..rays_per_pixel { rays.push(generate_single_primary_ray( (width, height), cam_to_world_matrix, focal_length, pixel_x_coord, pixel_y_coord, //no noise 0.0f, 0.0f, )); } rays } fn generate_single_primary_ray( (buffer_width, buffer_height): (usize, usize), cam_to_world_transform: &Matrix4, focal_length: f32, u: usize, v: usize, u_offset: f32, v_offset: f32, ) -> Ray { //calculate the ray direction and translate it to world space let direction_camera_space: Vector4 = Vector4::new( u as f32 - (buffer_width as f32 / 2.0) + u_offset, v as f32 - (buffer_height as f32 / 2.0) + v_offset, focal_length, 0.0, ); let direction_world_space = cam_to_world_transform * direction_camera_space.normalize(); Ray { origin: cam_to_world_transform.w.truncate(), direction: direction_world_space.truncate().normalize(), } }