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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use super::Vector;
use core::ops::{Index, MulAssign};
use generic_array::{arr, arr_impl, typenum::U3, GenericArray};
macro_rules! impl_3d_vector {
($vector:ident, $component:tt, $doc:expr) => {
#[doc=$doc]
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct $vector {
pub x: $component,
pub y: $component,
pub z: $component,
}
impl $vector {
pub fn new(x: $component, y: $component, z: $component) -> Self {
$vector { x, y, z }
}
}
impl Vector for $vector {
type Component = $component;
type Axes = U3;
const MIN: $component = core::$component::MIN;
const MAX: $component = core::$component::MAX;
fn from_iter<I>(into_iter: I) -> Self
where
I: IntoIterator<Item = Self::Component>
{
let mut iter = into_iter.into_iter();
let x = iter.next().expect("no x-axis component in slice");
let y = iter.next().expect("no y-axis component in slice");
let z = iter.next().expect("no z-axis component in slice");
debug_assert!(iter.next().is_none(), "too many items in 3-axis component slice");
Self::new(x, y, z)
}
fn get(self, i: usize) -> Option<Self::Component> {
if i <= 2 {
Some(self[i])
} else {
None
}
}
fn to_array(self) -> GenericArray<$component, U3> {
arr![$component; self.x, self.y, self.z]
}
}
impl From<($component, $component, $component)> for $vector {
fn from(vector: ($component, $component, $component)) -> Self {
$vector::new(vector.0, vector.1, vector.2)
}
}
impl Index<usize> for $vector {
type Output = $component;
fn index(&self, i: usize) -> &$component {
match i {
0 => &self.x,
1 => &self.y,
2 => &self.z,
_ => panic!("index out of range")
}
}
}
impl MulAssign<f32> for $vector {
#[allow(trivial_numeric_casts)]
fn mul_assign(&mut self, n: f32) {
self.x = (f32::from(self.x) * n) as $component;
self.y = (f32::from(self.y) * n) as $component;
self.z = (f32::from(self.z) * n) as $component;
}
}
}
}
impl_3d_vector!(I8x3, i8, "3-dimensional XYZ vector of `i8` values");
impl_3d_vector!(I16x3, i16, "3-dimensional XYZ vector of `i16` values");
impl_3d_vector!(U8x3, u8, "3-dimensional XYZ vector of `u8` values");
impl_3d_vector!(U16x3, u16, "3-dimensional XYZ vector of `u16` values");
impl_3d_vector!(F32x3, f32, "3-dimensional XYZ vector of `f32` values");
impl From<I8x3> for F32x3 {
fn from(vector: I8x3) -> F32x3 {
F32x3::new(vector.x.into(), vector.y.into(), vector.z.into())
}
}
impl From<I16x3> for F32x3 {
fn from(vector: I16x3) -> F32x3 {
F32x3::new(vector.x.into(), vector.y.into(), vector.z.into())
}
}
impl From<U8x3> for F32x3 {
fn from(vector: U8x3) -> F32x3 {
F32x3::new(vector.x.into(), vector.y.into(), vector.z.into())
}
}
impl From<U16x3> for F32x3 {
fn from(vector: U16x3) -> F32x3 {
F32x3::new(vector.x.into(), vector.y.into(), vector.z.into())
}
}