1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use crate::{
num::{DefaultFloat, Float},
vec::{Vec3, Vector},
};
use std::{
array::LengthAtMost32,
marker::PhantomData,
ops::{Add, Mul, Neg},
};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Ray<T = DefaultFloat, V = Vec3<T>> {
pub pos: V,
pub dir: V,
phantom: PhantomData<T>,
}
impl<T, V> Ray<T, V> {
pub fn new(pos: V, dir: V) -> Self {
Ray {
pos,
dir,
phantom: PhantomData,
}
}
}
impl<T: Float, V> Ray<T, V>
where
V: Add<Output = V> + Mul<T, Output = V> + Copy,
{
pub fn at(&self, t: T) -> V { self.pos + self.dir * t }
pub fn step(&mut self, t: T) { self.pos = self.pos + (self.dir * t) }
}
impl<T: Float, const N: usize> Ray<T, Vector<T, N>>
where
[T; N]: LengthAtMost32,
{
pub fn set_length(&mut self, t: T) { self.dir = self.dir.norm() * t; }
}
impl<T, V> Ray<T, V>
where
V: Neg<Output = V> + Copy,
{
pub fn flip(&self) -> Self { Ray::new(self.pos, -self.dir) }
}