2019-03-20 14:56:29 +00:00
|
|
|
use cgmath::{vec2, vec3, InnerSpace, Vector3};
|
|
|
|
|
|
|
|
use super::view::View;
|
|
|
|
|
|
|
|
pub struct Ray {
|
|
|
|
pub origin: Vector3<f32>,
|
|
|
|
pub direction: Vector3<f32>,
|
|
|
|
pub inv_direction: Vector3<f32>,
|
|
|
|
pub signs: Vector3<usize>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Ray {
|
|
|
|
pub fn new(origin: Vector3<f32>, direction: Vector3<f32>) -> 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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-20 16:15:07 +00:00
|
|
|
pub fn primary_ray(x: f32, y: f32, dim_x: f32, dim_y: f32, view: &View) -> Ray {
|
|
|
|
let aspect_ratio = dim_x / dim_y;
|
2019-03-20 14:56:29 +00:00
|
|
|
|
2019-03-20 16:15:07 +00:00
|
|
|
let uv = vec2((x + 0.5) / dim_x, (y + 0.5) / dim_y);
|
2019-03-20 14:56:29 +00:00
|
|
|
|
|
|
|
let (up, right) = view.axises();
|
|
|
|
|
|
|
|
let trans = 2.0 * uv - vec2(1.0, 1.0);
|
2019-03-20 16:15:07 +00:00
|
|
|
let raw_dir = view.look_at + right * trans.x + up * trans.y;
|
2019-03-20 14:56:29 +00:00
|
|
|
|
2019-03-20 16:15:07 +00:00
|
|
|
let dir = vec3(
|
|
|
|
raw_dir.x * aspect_ratio,
|
|
|
|
raw_dir.y,
|
|
|
|
raw_dir.z * aspect_ratio,
|
|
|
|
)
|
|
|
|
.normalize();
|
|
|
|
|
|
|
|
return Self::new(view.position, dir);
|
2019-03-20 14:56:29 +00:00
|
|
|
}
|
|
|
|
}
|