use nalgebra::{Point3, Unit, Vector3};
use crate::rt::Ray;
pub struct Orientation {
pub pos: Point3<f64>,
pub forward: Unit<Vector3<f64>>,
pub right: Unit<Vector3<f64>>,
pub up: Unit<Vector3<f64>>,
}
impl Orientation {
#[inline]
#[must_use]
pub fn new(ray: Ray) -> Self {
let (pos, forward) = ray.destruct();
let right = if forward.z.abs() <= 0.9 {
Unit::new_normalize(forward.cross(&Vector3::z_axis())) } else {
Unit::new_normalize(forward.cross(&Vector3::x_axis())) };
let up = Unit::new_normalize(right.cross(&forward));
Self {
pos,
forward,
right,
up,
}
}
#[inline]
#[must_use]
pub fn new_tar(pos: Point3<f64>, tar: &Point3<f64>) -> Self {
Self::new(Ray::new(pos, Unit::new_normalize(tar - pos)))
}
#[inline]
#[must_use]
pub fn back(&self) -> Unit<Vector3<f64>> {
-self.forward
}
#[inline]
#[must_use]
pub fn left(&self) -> Unit<Vector3<f64>> {
-self.right
}
#[inline]
#[must_use]
pub fn down(&self) -> Unit<Vector3<f64>> {
-self.up
}
#[inline]
#[must_use]
pub fn forward_ray(&self) -> Ray {
Ray::new(self.pos, self.forward)
}
#[inline]
#[must_use]
pub fn backward_ray(&self) -> Ray {
Ray::new(self.pos, -self.forward)
}
#[inline]
#[must_use]
pub fn up_ray(&self) -> Ray {
Ray::new(self.pos, self.up)
}
#[inline]
#[must_use]
pub fn down_ray(&self) -> Ray {
Ray::new(self.pos, -self.up)
}
#[inline]
#[must_use]
pub fn right_ray(&self) -> Ray {
Ray::new(self.pos, self.right)
}
#[inline]
#[must_use]
pub fn left_ray(&self) -> Ray {
Ray::new(self.pos, -self.right)
}
}