1use nalgebra::{Matrix2, Matrix3, Matrix4, Vector2, Vector3, Vector4};
2
3#[cfg(not(feature = "f64"))]
4pub type Fl = f32;
6#[cfg(not(feature = "f64"))]
7pub use std::f32 as std_fl;
8#[cfg(feature = "f64")]
9pub type Fl = f64;
11#[cfg(feature = "f64")]
12pub use std::f64 as std_fl;
13
14pub trait IntoFl {
16 fn into_fl(self) -> Fl;
18}
19
20macro_rules! impl_into_fl {
21 ($ty:ident) => {
22 impl IntoFl for $ty {
23 fn into_fl(self) -> Fl {
24 self as Fl
25 }
26 }
27 };
28}
29
30impl_into_fl!(f32);
31impl_into_fl!(f64);
32impl_into_fl!(u8);
33impl_into_fl!(i8);
34impl_into_fl!(u16);
35impl_into_fl!(i16);
36impl_into_fl!(u32);
37impl_into_fl!(i32);
38impl_into_fl!(u64);
39impl_into_fl!(i64);
40impl_into_fl!(u128);
41impl_into_fl!(i128);
42impl_into_fl!(usize);
43impl_into_fl!(isize);
44
45#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
46pub struct Vec2(pub Vector2<Fl>);
48#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
49pub struct Vec3(pub Vector3<Fl>);
51#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
52pub struct Vec4(pub Vector4<Fl>);
54#[derive(Debug, Clone, PartialEq, PartialOrd)]
55pub struct Mat2(pub Matrix2<Fl>);
57#[derive(Debug, Clone, PartialEq, PartialOrd)]
58pub struct Mat3(pub Matrix3<Fl>);
60#[derive(Debug, Clone, PartialEq, PartialOrd)]
61pub struct Mat4(pub Matrix4<Fl>);
63
64macro_rules! impl_vec_n {
65 ( $vec:ident, $inner:ident; $( $name:ident: $ty_name:ident ),* ) => {
66 impl $vec {
67 #[inline(always)]
68 pub fn new( $($name: impl IntoFl,)* ) -> Self {
70 Self($inner::new( $($name.into_fl(),)* ))
71 }
72 $(
73 #[inline(always)]
74 pub fn $name(&self) -> Fl {
76 self.0.$name
77 }
78 )*
79 }
80 impl<$($ty_name: IntoFl,)*> From<($($ty_name,)*)> for $vec {
81 #[inline(always)]
82 fn from(($($name,)*): ($($ty_name,)*)) -> Self {
84 Self::new($($name,)*)
85 }
86 }
87
88 impl ::std::ops::Add<$vec> for $vec {
89 type Output = $vec;
90
91 #[inline(always)]
92 fn add(self, rhs: Self) -> Self::Output {
94 Self::new($(self.$name() + rhs.$name(),)*)
95 }
96 }
97
98 impl ::std::ops::Sub<$vec> for $vec {
99 type Output = $vec;
100
101 #[inline(always)]
102 fn sub(self, rhs: Self) -> Self::Output {
104 Self::new($(self.$name() - rhs.$name(),)*)
105 }
106 }
107
108 impl ::std::ops::Mul<$vec> for $vec {
109 type Output = $vec;
110
111 #[inline(always)]
112 fn mul(self, rhs: Self) -> Self::Output {
114 Self::new($(self.$name() * rhs.$name(),)*)
115 }
116 }
117
118 impl ::std::ops::Mul<Fl> for $vec {
119 type Output = $vec;
120
121 #[inline(always)]
122 fn mul(self, rhs: Fl) -> Self::Output {
124 Self(self.0 * rhs)
125 }
126 }
127
128 impl ::std::ops::Div<$vec> for $vec {
129 type Output = $vec;
130
131 #[inline(always)]
132 fn div(self, rhs: Self) -> Self::Output {
134 Self::new($(self.$name() / rhs.$name(),)*)
135 }
136 }
137
138 impl ::std::ops::Div<Fl> for $vec {
139 type Output = $vec;
140
141 #[inline(always)]
142 fn div(self, rhs: Fl) -> Self::Output {
144 Self(self.0 / rhs)
145 }
146 }
147 };
148}
149
150impl_vec_n!(Vec2, Vector2; x: T, y: U);
151impl_vec_n!(Vec3, Vector3; x: T, y: U, z: V);
152impl_vec_n!(Vec4, Vector4; x: T, y: U, z: V, w: W);
153
154impl Mat4 {
155 pub fn ident() -> Self {
157 Mat4(Matrix4::identity())
158 }
159}
160
161impl std::ops::Mul<Vec3> for &Mat4 {
162 type Output = Vec3;
163
164 fn mul(self, rhs: Vec3) -> Self::Output {
165 Vec3((self.0 * Vector4::new(rhs.0.x, rhs.0.y, rhs.0.z, 1.0)).xyz())
166 }
167}
168
169impl std::ops::Mul<Vec4> for &Mat4 {
170 type Output = Vec4;
171
172 fn mul(self, rhs: Vec4) -> Self::Output {
173 Vec4(self.0 * rhs.0)
174 }
175}
176
177impl Mat3 {
178 pub fn ident() -> Self {
180 Mat3(Matrix3::identity())
181 }
182}
183
184impl std::ops::Mul<Vec2> for &Mat3 {
185 type Output = Vec2;
186
187 fn mul(self, rhs: Vec2) -> Self::Output {
188 Vec2((self.0 * Vector3::new(rhs.0.x, rhs.0.y, 1.0)).xy())
189 }
190}
191
192impl std::ops::Mul<Vec3> for &Mat3 {
193 type Output = Vec3;
194
195 fn mul(self, rhs: Vec3) -> Self::Output {
196 Vec3(self.0 * rhs.0)
197 }
198}
199
200impl Mat2 {
201 pub fn ident() -> Self {
203 Mat2(Matrix2::identity())
204 }
205 pub fn new(x1: impl IntoFl, y1: impl IntoFl, x2: impl IntoFl, y2: impl IntoFl) -> Self {
207 Mat2(Matrix2::new(
208 x1.into_fl(),
209 y1.into_fl(),
210 x2.into_fl(),
211 y2.into_fl(),
212 ))
213 }
214}
215
216impl Vec2 {
217 #[inline]
218 pub fn rotated(&self, rotation: Fl) -> Self {
220 let (s, c) = (rotation.sin(), rotation.cos());
221 Self::new(self.0.x * c + self.0.y * s, self.0.y * c - self.0.x * s)
222 }
223 pub fn tangent(&self) -> Self {
225 Self::new(self.0.y, -self.0.x)
226 }
227 pub fn length(&self) -> Fl {
229 (self.0.x.powi(2) + self.0.y.powi(2)).sqrt()
230 }
231 pub fn normalize_or(&self, other: Vec2) -> Self {
233 if self.length() <= 0.000001 {
234 other
235 } else {
236 *self / self.length()
237 }
238 }
239}
240
241impl std::ops::Mul<Vec2> for &Mat2 {
242 type Output = Vec2;
243
244 fn mul(self, rhs: Vec2) -> Self::Output {
245 Vec2(self.0 * rhs.0)
246 }
247}
248
249pub mod prelude {
251 pub use super::Fl;
252 pub use super::Mat2;
253 pub use super::Mat3;
254 pub use super::Mat4;
255 pub use super::Vec2;
256 pub use super::Vec3;
257 pub use super::Vec4;
258}