use cgmath::{vec2, vec3, InnerSpace, Vector3}; use super::view::View; pub struct Ray { pub origin: Vector3, pub direction: Vector3, pub inv_direction: Vector3, pub signs: Vector3, } impl Ray { pub fn new(origin: Vector3, direction: Vector3) -> Ray { let inv_direction = 1.0 / direction; let x = (inv_direction.x < 0.0) as usize; let y = (inv_direction.y < 0.0) as usize; let z = (inv_direction.z < 0.0) as usize; Ray { origin, direction, inv_direction, signs: Vector3::new(x, y, z), } } pub fn primary_ray(x: f32, y: f32, dim_x: f32, dim_y: f32, view: &View) -> Ray { let aspect_ratio = dim_x / dim_y; let uv = vec2((x + 0.5) / dim_x, (y + 0.5) / dim_y); let (up, right) = view.axises(); let trans = 2.0 * uv - vec2(1.0, 1.0); let raw_dir = view.look_at + right * trans.x + up * trans.y; let dir = vec3( raw_dir.x * aspect_ratio, raw_dir.y, raw_dir.z * aspect_ratio, ) .normalize(); return Self::new(view.position, dir); } }