1use std::ops::Mul;
4
5use bytemuck::{Pod, Zeroable};
6use serde::{Deserialize, Serialize};
7
8use super::{Vec3, Vec4};
9
10#[repr(C, align(16))]
12#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
13#[serde(from = "[f32; 4]", into = "[f32; 4]")]
14pub struct Quat {
15 pub x: f32,
17 pub y: f32,
19 pub z: f32,
21 pub w: f32,
23}
24
25impl Quat {
26 pub const IDENTITY: Self = Self::from_xyzw(0.0, 0.0, 0.0, 1.0);
28 #[must_use]
30 #[inline]
31 pub const fn from_xyzw(x: f32, y: f32, z: f32, w: f32) -> Self {
32 Self { x, y, z, w }
33 }
34 #[must_use]
36 #[inline]
37 pub const fn from_array(value: [f32; 4]) -> Self {
38 Self::from_xyzw(value[0], value[1], value[2], value[3])
39 }
40 #[must_use]
42 #[inline]
43 pub const fn to_array(self) -> [f32; 4] {
44 [self.x, self.y, self.z, self.w]
45 }
46 #[must_use]
48 #[inline]
49 pub fn from_rotation_x(angle: f32) -> Self {
50 glam::Quat::from_rotation_x(angle).into()
51 }
52 #[must_use]
54 #[inline]
55 pub fn from_rotation_y(angle: f32) -> Self {
56 glam::Quat::from_rotation_y(angle).into()
57 }
58 #[must_use]
60 #[inline]
61 pub fn from_rotation_z(angle: f32) -> Self {
62 glam::Quat::from_rotation_z(angle).into()
63 }
64 #[must_use]
66 #[inline]
67 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
68 glam::Quat::from_axis_angle(axis.into(), angle).into()
69 }
70 #[must_use]
72 #[inline]
73 pub fn from_rotation_arc(from: Vec3, to: Vec3) -> Self {
74 glam::Quat::from_rotation_arc(from.into(), to.into()).into()
75 }
76 #[must_use]
78 #[inline]
79 pub fn from_mat3(matrix: &Mat3) -> Self {
80 glam::Quat::from_mat3(&(*matrix).into()).into()
81 }
82 #[must_use]
84 #[inline]
85 pub fn slerp(self, rhs: Self, amount: f32) -> Self {
86 glam::Quat::from(self).slerp(rhs.into(), amount).into()
87 }
88 #[must_use]
90 #[inline]
91 pub fn is_finite(self) -> bool {
92 glam::Quat::from(self).is_finite()
93 }
94 #[must_use]
96 #[inline]
97 pub fn length_squared(self) -> f32 {
98 glam::Quat::from(self).length_squared()
99 }
100 #[must_use]
102 #[inline]
103 pub fn normalize(self) -> Self {
104 glam::Quat::from(self).normalize().into()
105 }
106}
107
108impl Default for Quat {
109 #[inline]
110 fn default() -> Self {
111 Self::IDENTITY
112 }
113}
114impl From<[f32; 4]> for Quat {
115 #[inline]
116 fn from(value: [f32; 4]) -> Self {
117 Self::from_array(value)
118 }
119}
120impl From<Quat> for [f32; 4] {
121 #[inline]
122 fn from(value: Quat) -> Self {
123 value.to_array()
124 }
125}
126impl From<glam::Quat> for Quat {
127 #[inline]
128 fn from(value: glam::Quat) -> Self {
129 value.to_array().into()
130 }
131}
132impl From<Quat> for glam::Quat {
133 #[inline]
134 fn from(value: Quat) -> Self {
135 Self::from_array(value.to_array())
136 }
137}
138impl Mul for Quat {
139 type Output = Self;
140 #[inline]
141 fn mul(self, rhs: Self) -> Self {
142 (glam::Quat::from(self) * glam::Quat::from(rhs)).into()
143 }
144}
145impl Mul<Vec3> for Quat {
146 type Output = Vec3;
147 #[inline]
148 fn mul(self, rhs: Vec3) -> Vec3 {
149 (glam::Quat::from(self) * glam::Vec3::from(rhs)).into()
150 }
151}
152
153#[repr(C)]
155#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
156pub struct Mat3 {
157 pub x_axis: Vec3,
159 pub y_axis: Vec3,
161 pub z_axis: Vec3,
163}
164
165impl Mat3 {
166 pub const IDENTITY: Self = Self::from_cols(Vec3::X, Vec3::Y, Vec3::Z);
168 #[must_use]
170 #[inline]
171 pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
172 Self {
173 x_axis,
174 y_axis,
175 z_axis,
176 }
177 }
178 #[must_use]
180 #[inline]
181 pub fn from_mat4(value: Mat4) -> Self {
182 glam::Mat3::from_mat4(value.into()).into()
183 }
184 #[must_use]
186 #[inline]
187 pub fn from_quat(value: Quat) -> Self {
188 glam::Mat3::from_quat(value.into()).into()
189 }
190 #[must_use]
192 #[inline]
193 pub fn inverse(self) -> Self {
194 glam::Mat3::from(self).inverse().into()
195 }
196 #[must_use]
198 #[inline]
199 pub fn transpose(self) -> Self {
200 glam::Mat3::from(self).transpose().into()
201 }
202 #[must_use]
204 #[inline]
205 pub fn determinant(self) -> f32 {
206 glam::Mat3::from(self).determinant()
207 }
208 #[must_use]
210 #[inline]
211 pub fn is_finite(self) -> bool {
212 glam::Mat3::from(self).is_finite()
213 }
214}
215
216impl From<glam::Mat3> for Mat3 {
217 #[inline]
218 fn from(value: glam::Mat3) -> Self {
219 Self::from_cols(
220 value.x_axis.into(),
221 value.y_axis.into(),
222 value.z_axis.into(),
223 )
224 }
225}
226impl From<Mat3> for glam::Mat3 {
227 #[inline]
228 fn from(value: Mat3) -> Self {
229 Self::from_cols(
230 value.x_axis.into(),
231 value.y_axis.into(),
232 value.z_axis.into(),
233 )
234 }
235}
236impl Mul for Mat3 {
237 type Output = Self;
238 #[inline]
239 fn mul(self, rhs: Self) -> Self {
240 (glam::Mat3::from(self) * glam::Mat3::from(rhs)).into()
241 }
242}
243impl Mul<Vec3> for Mat3 {
244 type Output = Vec3;
245 #[inline]
246 fn mul(self, rhs: Vec3) -> Vec3 {
247 (glam::Mat3::from(self) * glam::Vec3::from(rhs)).into()
248 }
249}
250
251#[repr(C, align(16))]
253#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
254pub struct Mat4 {
255 pub x_axis: Vec4,
257 pub y_axis: Vec4,
259 pub z_axis: Vec4,
261 pub w_axis: Vec4,
263}
264
265impl Mat4 {
266 pub const IDENTITY: Self = Self::from_cols(
268 Vec4::new(1.0, 0.0, 0.0, 0.0),
269 Vec4::new(0.0, 1.0, 0.0, 0.0),
270 Vec4::new(0.0, 0.0, 1.0, 0.0),
271 Vec4::new(0.0, 0.0, 0.0, 1.0),
272 );
273 pub const ZERO: Self = Self::from_cols(Vec4::ZERO, Vec4::ZERO, Vec4::ZERO, Vec4::ZERO);
275 #[must_use]
277 #[inline]
278 pub const fn from_cols(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Self {
279 Self {
280 x_axis,
281 y_axis,
282 z_axis,
283 w_axis,
284 }
285 }
286 #[must_use]
288 #[inline]
289 pub fn from_cols_array(value: &[f32; 16]) -> Self {
290 glam::Mat4::from_cols_array(value).into()
291 }
292 #[must_use]
294 #[inline]
295 pub fn to_cols_array(self) -> [f32; 16] {
296 glam::Mat4::from(self).to_cols_array()
297 }
298 #[must_use]
300 #[inline]
301 pub fn to_cols_array_2d(self) -> [[f32; 4]; 4] {
302 glam::Mat4::from(self).to_cols_array_2d()
303 }
304 #[must_use]
306 #[inline]
307 pub fn from_translation(value: Vec3) -> Self {
308 glam::Mat4::from_translation(value.into()).into()
309 }
310 #[must_use]
312 #[inline]
313 pub fn from_rotation_y(angle: f32) -> Self {
314 glam::Mat4::from_rotation_y(angle).into()
315 }
316 #[must_use]
318 #[inline]
319 pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
320 glam::Mat4::from_scale_rotation_translation(
321 scale.into(),
322 rotation.into(),
323 translation.into(),
324 )
325 .into()
326 }
327 #[must_use]
329 #[inline]
330 pub fn transform_point3(self, point: Vec3) -> Vec3 {
331 glam::Mat4::from(self).transform_point3(point.into()).into()
332 }
333 #[must_use]
335 #[inline]
336 pub fn transform_vector3(self, vector: Vec3) -> Vec3 {
337 glam::Mat4::from(self)
338 .transform_vector3(vector.into())
339 .into()
340 }
341 #[must_use]
343 #[inline]
344 pub fn inverse(self) -> Self {
345 glam::Mat4::from(self).inverse().into()
346 }
347 #[must_use]
349 #[inline]
350 pub fn determinant(self) -> f32 {
351 glam::Mat4::from(self).determinant()
352 }
353 #[must_use]
355 #[inline]
356 pub fn is_finite(self) -> bool {
357 glam::Mat4::from(self).is_finite()
358 }
359 #[must_use]
361 #[inline]
362 pub fn row(self, index: usize) -> Vec4 {
363 glam::Mat4::from(self).row(index).into()
364 }
365}
366
367impl Default for Mat4 {
368 #[inline]
369 fn default() -> Self {
370 Self::IDENTITY
371 }
372}
373impl From<glam::Mat4> for Mat4 {
374 #[inline]
375 fn from(value: glam::Mat4) -> Self {
376 Self::from_cols(
377 value.x_axis.into(),
378 value.y_axis.into(),
379 value.z_axis.into(),
380 value.w_axis.into(),
381 )
382 }
383}
384impl From<Mat4> for glam::Mat4 {
385 #[inline]
386 fn from(value: Mat4) -> Self {
387 Self::from_cols(
388 value.x_axis.into(),
389 value.y_axis.into(),
390 value.z_axis.into(),
391 value.w_axis.into(),
392 )
393 }
394}
395impl Mul for Mat4 {
396 type Output = Self;
397 #[inline]
398 fn mul(self, rhs: Self) -> Self {
399 (glam::Mat4::from(self) * glam::Mat4::from(rhs)).into()
400 }
401}
402impl Mul<Vec4> for Mat4 {
403 type Output = Vec4;
404 #[inline]
405 fn mul(self, rhs: Vec4) -> Vec4 {
406 (glam::Mat4::from(self) * glam::Vec4::from(rhs)).into()
407 }
408}