stereokit_rust/
maths.rs

1use crate::{
2    material::Cull,
3    mesh::{Mesh, VindT, mesh_ray_intersect},
4    model::{Model, model_ray_intersect},
5};
6use std::{
7    fmt::Display,
8    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
9};
10
11/// Native code use this as bool
12pub type Bool32T = i32;
13
14/// Blends (Linear Interpolation) between two scalars, based on a 'blend' value, where 0 is a, and 1 is b. Doesn't clamp
15/// percent for you.
16/// <https://stereokit.net/Pages/StereoKit/SKMath/Lerp.html>
17/// * `a` - First item in the blend, or '0.0' blend.
18/// * `b` - Second item in the blend, or '1.0' blend.
19/// * `t` - A blend value between 0 and 1. Can be outside   this range, it'll just interpolate outside of the a, b range.
20///
21/// Returns an unclamped blend of a and b.
22/// see also [`crate::util::Color128::lerp`]
23pub fn lerp(a: f32, b: f32, t: f32) -> f32 {
24    a + (b - a) * t
25}
26
27/// Calculates the minimum angle 'distance' between two angles. This covers wraparound cases like: the minimum distance
28/// between 10 and 350 is 20.
29/// <https://stereokit.net/Pages/StereoKit/SKMath/AngleDist.html>
30/// * `a` - First angle, in degrees.
31/// * `b` - Second angle, in degrees.
32///   
33/// returns : Degrees 0-180, the minimum angle between a and b.
34pub fn angle_dist(a: f32, b: f32) -> f32 {
35    let delta = (b - a + 180.0) % 360.0 - 180.0;
36    (if delta < -180.0 { delta + 360.0 } else { delta }).abs()
37}
38
39pub mod units {
40    /// Converts centimeters to meters. There are 100cm in 1m. In StereoKit 1 unit is also 1 meter,
41    /// so `25 * Units.cm2m == 0.25`, 25 centimeters is .25 meters/units.
42    pub const CM2M: f32 = 0.01;
43    /// Converts millimeters to meters. There are 1000mm in 1m. In StereoKit 1 unit is 1 meter,
44    /// so `250 * Units.mm2m == 0.25`, 250 millimeters is .25 meters/units.
45    pub const MM2M: f32 = 0.001;
46    ///Converts meters to centimeters. There are 100cm in 1m, so this just multiplies by 100.
47    pub const M2CM: f32 = 100.0;
48    ///Converts meters to millimeters. There are 1000mm in 1m, so this just multiplies by 1000.
49    pub const M2MM: f32 = 1000.0;
50
51    /// Converts centimeters to meters. There are 100cm in 1m. In StereoKit 1 unit is also 1 meter,
52    /// so `25 * U.cm == 0.25`, 25 centimeters is .25 meters/units.
53    pub const CM: f32 = 0.01;
54    /// Converts millimeters to meters. There are 1000mm in 1m. In StereoKit 1 unit is 1 meter,
55    /// so `250 * Units.mm2m == 0.25`, 250 millimeters is .25 meters/units.
56    pub const MM: f32 = 0.001;
57    /// StereoKit's default unit is meters, but sometimes it's nice to be explicit!
58    pub const M: f32 = 1.0;
59    /// Converts meters to kilometers. There are 1000m in 1km, so this just multiplies by 1000.
60    pub const KM: f32 = 1000.0;
61}
62
63/// A vector with 2 components: x and y. This can represent a point in 2D space, a directional vector, or any other sort
64/// of value with 2 dimensions to it!
65/// <https://stereokit.net/Pages/StereoKit/Vec2.html>
66///
67/// see also [`glam::Vec2`]
68/// ### Examples
69/// ```
70/// use stereokit_rust::maths::Vec2;
71///
72/// let vec2        = Vec2::new(1.0, 2.0);
73/// let vec2a       = Vec2 { x: 1.0, y: 2.0 };
74/// let vec2b       = Vec2::X + Vec2::Y * 2.0;
75/// let vec3c: Vec2 = [1.0, 2.0].into();
76///
77/// assert_eq!(vec2, vec2a);
78/// assert_eq!(vec2a + vec2b,                   Vec2 { x: 2.0, y: 4.0 });
79/// assert_eq!(vec3c,                           Vec2 { x: 1.0, y: 2.0 });
80/// assert_eq!(vec2a.length_sq(),               5.0);
81/// assert_eq!(Vec2::Y.angle(),                 90.0);
82/// assert_eq!(vec2a.magnitude(),               (5.0f32).sqrt());
83/// assert!   (vec2a.get_normalized().length() - 1.0 < f32::EPSILON);
84/// assert_eq!(Vec2::angle_between(Vec2::X, Vec2::Y), 90.0);
85/// assert_eq!(Vec2::dot(Vec2::X, Vec2::Y), 0.0);
86/// ```
87#[derive(Debug, Default, Copy, Clone)]
88#[repr(C)]
89pub struct Vec2 {
90    pub x: f32,
91    pub y: f32,
92}
93
94impl From<glam::Vec2> for Vec2 {
95    fn from(val: glam::Vec2) -> Self {
96        Vec2 { x: val.x, y: val.y }
97    }
98}
99
100impl From<Vec2> for glam::Vec2 {
101    fn from(val: Vec2) -> Self {
102        Self::new(val.x, val.y)
103    }
104}
105
106impl From<[f32; 2]> for Vec2 {
107    fn from(val: [f32; 2]) -> Self {
108        Vec2 { x: val[0], y: val[1] }
109    }
110}
111
112///  Warning: Equality with a precision of 0.1 millimeter
113impl PartialEq for Vec2 {
114    ///  Warning: Equality with a precision of 0.1 millimeter
115    /// ```
116    /// use stereokit_rust::maths::Vec2;
117    /// assert_eq!(
118    ///              Vec2 { x: 0.045863353, y: 0.030000005 } ,
119    ///              Vec2 { x: 0.045863353, y: 0.030000005 } );
120    /// ```
121    /// ```
122    /// use stereokit_rust::maths::Vec2;
123    /// assert_ne!(
124    ///              Vec2 { x: 10.045863353, y: 0.030000005 } ,
125    ///              Vec2 { x: 0.045863353, y: 0.030000005 } );
126    /// ```
127    fn eq(&self, other: &Self) -> bool {
128        ((self.x - other.x).abs() < 0.0001) && ((self.y - other.y).abs() < 0.0001)
129    }
130}
131
132impl Vec2 {
133    /// A Vec2 with all components at zero, this is the same as new Vec2(0,0).
134    /// <https://stereokit.net/Pages/StereoKit/Vec2/Zero.html>
135    pub const ZERO: Self = Self::new(0.0, 0.0);
136
137    /// A Vec2 with all components at one, this is the same as new Vec2(1,1).
138    /// <https://stereokit.net/Pages/StereoKit/Vec2/One.html>
139    pub const ONE: Self = Self::new(1.0, 1.0);
140
141    /// A normalized Vector that points down the X axis, this is the same as new Vec2(1,0).
142    /// <https://stereokit.net/Pages/StereoKit/Vec2/UnitX.html>
143    pub const X: Self = Self::new(1.0, 0.0);
144
145    /// A normalized Vector that points down the Y axis, this is the same as new Vec2(0,1).
146    /// <https://stereokit.net/Pages/StereoKit/Vec2/UnitY.html>
147    pub const Y: Self = Self::new(0.0, 1.0);
148
149    /// A normalized Vector that points up the X axis, this is the same as new Vec2(-1,0).
150    pub const NEG_X: Self = Self::new(-1.0, 0.0);
151
152    /// A normalized Vector that points up the Y axis, this is the same as new Vec2(0,-1).
153    pub const NEG_Y: Self = Self::new(0.0, -1.0);
154
155    /// A basic constructor, just copies the values in!
156    /// <https://stereokit.net/Pages/StereoKit/Vec2/Vec2.html>
157    #[inline]
158    pub const fn new(x: f32, y: f32) -> Self {
159        Self { x, y }
160    }
161
162    /// Returns the counter-clockwise degrees from `[1,0]`. Resulting value is between 0 and 360. Vector does not need
163    /// to be normalized.
164    /// <https://stereokit.net/Pages/StereoKit/Vec2/Angle.html>
165    ///
166    /// ### Examples
167    /// ```
168    /// use stereokit_rust::maths::Vec2;
169    ///
170    /// let vec2 = Vec2::new(1.0, 1.0);
171    /// assert_eq!(vec2.angle(), 45.0);
172    ///
173    /// let vec2 = Vec2::new(0.0, 1.0);
174    /// assert_eq!(vec2.angle(), 90.0);
175    ///
176    /// let vec2 = Vec2::new(-1.0, 1.0);
177    /// assert_eq!(vec2.angle(), 135.0);
178    ///
179    /// let vec2 = Vec2::new(-1.0, 0.0);
180    /// assert_eq!(vec2.angle(), 180.0);
181    ///
182    /// let vec2 = Vec2::new(-1.0, -1.0);
183    /// assert_eq!(vec2.angle(), 225.0);
184    /// ```
185    #[inline]
186    pub fn angle(&self) -> f32 {
187        let mut result = self.y.atan2(self.x).to_degrees();
188        if result < 0.0 {
189            result += 360.0
190        };
191        result
192    }
193
194    /// Checks if a point is within a certain radius of this one. This is an easily readable shorthand of the squared
195    /// distance check.
196    /// <https://stereokit.net/Pages/StereoKit/Vec2/InRadius.html>
197    /// * `point` - The point to check against.
198    /// * `radius` - The distance to check within.
199    ///
200    /// Returns true if the points are within radius of each other, false not.
201    /// ### Examples
202    /// ```
203    /// use stereokit_rust::maths::Vec2;
204    ///
205    /// let vec2 = Vec2::new(1.0, 1.0);
206    /// let vec2_in = Vec2::new(1.1, 1.1);
207    /// let vec2_out = Vec2::new(2.0, 2.0);
208    /// assert!(vec2.in_radius(vec2_in, 0.2));
209    /// assert!(!vec2.in_radius(vec2_out, 0.2));
210    /// ```
211    #[inline]
212    pub fn in_radius(&self, point: Self, radius: f32) -> bool {
213        Self::distance(*self, point) <= radius
214    }
215
216    /// Turns this vector into a normalized vector (vector with a length of 1) from the current vector. Will not work
217    /// properly if the vector has a length of zero. Vec2::get_normalized is faster.
218    /// <https://stereokit.net/Pages/StereoKit/Vec2/Normalize.html>
219    ///
220    /// ### Examples
221    /// ```
222    /// use stereokit_rust::maths::Vec2;
223    ///
224    /// let mut vec2 = Vec2::new(1.0, 1.0);
225    /// assert!((vec2.length() - 1.4142135).abs() < f32::EPSILON);
226    ///
227    /// vec2.normalize();
228    /// assert!((vec2.length() - 1.0).abs() < f32::EPSILON);
229    /// ```
230    #[inline]
231    pub fn normalize(&mut self) {
232        let n = *self * (self.length().recip());
233        self.x = n.x;
234        self.y = n.y;
235    }
236
237    /// This is the length of the vector! Or the distance from the origin to this point. Uses f32::sqrt, so it’s not
238    /// dirt cheap or anything.
239    /// <https://stereokit.net/Pages/StereoKit/Vec2/Length.html>
240    ///
241    /// ### Examples
242    /// ```
243    /// use stereokit_rust::maths::Vec2;
244    ///
245    /// let vec2 = Vec2::new(1.0, 1.0);
246    /// assert_eq!(vec2.length(), (2.0f32).sqrt());
247    /// ```
248    #[inline]
249    pub fn length(&self) -> f32 {
250        Self::dot(*self, *self).sqrt()
251    }
252
253    /// This is the squared length/magnitude of the vector! It skips the Sqrt call, and just gives you the squared
254    /// version for speedy calculations that can work with it squared.
255    /// <https://stereokit.net/Pages/StereoKit/Vec2/LengthSq.html>
256    ///
257    /// ### Examples
258    /// ```
259    /// use stereokit_rust::maths::Vec2;
260    ///
261    /// let vec2 = Vec2::new(1.0, 1.0);
262    /// assert_eq!(vec2.length_sq(), 2.0);
263    /// ```
264    #[inline]
265    pub fn length_sq(&self) -> f32 {
266        Self::dot(*self, *self)
267    }
268
269    /// Magnitude is the length of the vector! Or the distance from the origin to this point. Uses f32::sqrt, so it’s
270    /// not dirt cheap or anything.
271    /// <https://stereokit.net/Pages/StereoKit/Vec2/Magnitude.html>
272    ///
273    /// ### Examples
274    /// ```
275    /// use stereokit_rust::maths::Vec2;
276    ///
277    /// let vec2 = Vec2::new(1.0, 1.0);
278    /// assert_eq!(vec2.length(), vec2.magnitude());
279    /// ```
280    #[inline]
281    pub fn magnitude(&self) -> f32 {
282        self.length()
283    }
284
285    /// This is the squared magnitude of the vector! It skips the Sqrt call, and just gives you the squared version for
286    /// speedy calculations that can work with it squared. Vec2::length_squared is faster
287    /// <https://stereokit.net/Pages/StereoKit/Vec2/MagnitudeSq.html>
288    ///
289    /// ### Examples
290    /// ```
291    /// use stereokit_rust::maths::Vec2;
292    ///
293    /// let vec2 = Vec2::new(1.0, 1.0);
294    /// assert_eq!(vec2.length_sq(), vec2.magnitude_sq());
295    /// ```
296    #[inline]
297    pub fn magnitude_sq(&self) -> f32 {
298        self.length_sq()
299    }
300
301    /// Creates a normalized vector (vector with a length of 1) from the current vector. Will not work properly if the
302    /// vector has a length of zero.
303    /// <https://stereokit.net/Pages/StereoKit/Vec2/Normalized.html>
304    ///
305    /// ### Examples
306    /// ```
307    /// use stereokit_rust::maths::Vec2;
308    ///
309    /// let vec2 = Vec2::new(1.0, 1.0);
310    /// assert!((vec2.get_normalized().length() - 1.0).abs() < f32::EPSILON);
311    /// ```
312    #[inline]
313    pub fn get_normalized(&self) -> Self {
314        *self * (self.length().recip())
315    }
316
317    /// Promotes this Vec2 to a Vec3, using 0 for the Y axis.
318    /// <https://stereokit.net/Pages/StereoKit/Vec2/X0Y.html>
319    ///
320    /// ### Examples
321    /// ```
322    /// use stereokit_rust::maths::{Vec2, Vec3};
323    ///
324    /// let vec2 = Vec2::new(1.0, 1.0);
325    /// assert_eq!(vec2.x0y(), Vec3::new(1.0, 0.0, 1.0));
326    /// ```
327    #[inline]
328    pub fn x0y(&self) -> Vec3 {
329        Vec3 { x: self.x, y: 0.0, z: self.y }
330    }
331
332    /// Promotes this Vec2 to a Vec3, using 0 for the Z axis.
333    /// <https://stereokit.net/Pages/StereoKit/Vec2/XY0.html>
334    ///
335    /// ### Examples
336    /// ```
337    /// use stereokit_rust::maths::{Vec2, Vec3};
338    ///
339    /// let vec2 = Vec2::new(1.0, 1.0);
340    /// assert_eq!(vec2.xy0(), Vec3::new(1.0, 1.0, 0.0));
341    /// ```
342    #[inline]
343    pub fn xy0(&self) -> Vec3 {
344        Vec3 { x: self.x, y: self.y, z: 0.0 }
345    }
346
347    /// A transpose swizzle property, returns (y,x)
348    /// <https://stereokit.net/Pages/StereoKit/Vec2/YX.html>
349    ///
350    /// ### Examples
351    /// ```
352    /// use stereokit_rust::maths::{Vec2, Vec3};
353    ///
354    /// let vec2 = Vec2::new(1.1, 1.2);
355    /// assert_eq!(vec2.yx(), Vec2::new(1.2, 1.1));
356    /// ```
357    #[inline]
358    pub fn yx(&self) -> Self {
359        Self { x: self.y, y: self.x }
360    }
361
362    /// Calculates a signed angle between two vectors in degrees! Sign will be positive if B is counter-clockwise (left)
363    /// of A, and negative if B is clockwise (right) of A. Vectors do not need to be normalized. NOTE: Since this will
364    /// return a positive or negative angle, order of parameters matters!
365    /// <https://stereokit.net/Pages/StereoKit/Vec2/AngleBetween.html>
366    /// * `a` - The first, initial vector, A. Does not need to be normalized.
367    /// * `b` - The second, final vector, B. Does not need to be normalized.
368    ///
369    /// Returns a signed angle between two vectors in degrees! Sign will be positive if B is counter-clockwise (left)
370    /// of A, and negative if B is clockwise (right) of A.
371    /// ### Examples
372    /// ```
373    /// use stereokit_rust::maths::Vec2;
374    ///
375    /// let vec2_a = Vec2::new(1.0, 0.0);
376    /// let vec2_b = Vec2::new(0.0, 1.0);
377    /// assert_eq!(Vec2::angle_between(vec2_a, vec2_b), 90.0);
378    ///
379    /// let vec2_a = Vec2::new(1.0, 0.0);
380    /// let vec2_b = Vec2::new(0.0, -1.0);
381    /// assert_eq!(Vec2::angle_between(vec2_a, vec2_b), 90.0);
382    ///
383    /// let vec2_a = Vec2::new(1.0, 0.0);
384    /// let vec2_b = Vec2::new(-1.0, 0.0);
385    /// assert_eq!(Vec2::angle_between(vec2_a, vec2_b), 180.0);
386    ///
387    /// let vec2_a = Vec2::new(1.0, 0.0);
388    /// let vec2_b = Vec2::new(1.0, 0.0);
389    /// assert_eq!(Vec2::angle_between(vec2_a, vec2_b), 0.0);
390    /// ```
391    #[inline]
392    pub fn angle_between(a: Self, b: Self) -> f32 {
393        (Self::dot(a, b) / (a.length_sq() * b.length_sq()).sqrt()).acos().to_degrees()
394    }
395
396    /// Creates a normalized delta vector that points out from an origin point to a target point!
397    /// <https://stereokit.net/Pages/StereoKit/Vec2/Direction.html>
398    /// * `to` - The target point.
399    /// * `from` - And the origin point!
400    ///
401    /// Returns direction from one point to another.
402    /// ### Examples
403    /// ```
404    /// use stereokit_rust::maths::Vec2;
405    ///
406    /// let vec2_a = Vec2::new(1.0, 0.0);
407    /// let vec2_b = Vec2::new(0.0, 1.0);
408    /// assert_eq!(Vec2::direction(vec2_b, vec2_a), Vec2::new(-0.70710677, 0.70710677));
409    /// ```
410    #[inline]
411    pub fn direction(to: Self, from: Self) -> Self {
412        (to - from).get_normalized()
413    }
414
415    /// Calculates the distance between two points in space! Make sure they’re in the same coordinate space! Uses a Sqrt,
416    /// so it’s not blazing fast, prefer DistanceSq when possible.
417    /// <https://stereokit.net/Pages/StereoKit/Vec2/Distance.html>
418    /// * `a` - The first point.
419    /// * `b` - And the second point.
420    ///
421    /// Returns distance between the two points.
422    /// ### Examples
423    /// ```
424    /// use stereokit_rust::maths::Vec2;
425    ///
426    /// let vec2_a = Vec2::new(1.0, 0.0);
427    /// let vec2_b = Vec2::new(0.0, 1.0);
428    /// assert_eq!(Vec2::distance(vec2_a, vec2_b), (2.0f32).sqrt());
429    /// ```
430    #[inline]
431    pub fn distance(a: Self, b: Self) -> f32 {
432        (a - b).length()
433    }
434
435    /// Calculates the distance between two points in space, but leaves them squared! Make sure they’re in the same
436    /// coordinate space! This is a fast function :)
437    /// <https://stereokit.net/Pages/StereoKit/Vec2/DistanceSq.html>
438    /// - `a` - The first point.
439    /// - `b` - The second point.
440    ///
441    /// Returns distance between the two points, but squared.
442    /// ### Examples
443    /// ```
444    /// use stereokit_rust::maths::Vec2;
445    ///
446    /// let vec2_a = Vec2::new(1.0, 0.0);
447    /// let vec2_b = Vec2::new(0.0, 1.0);
448    /// assert_eq!(Vec2::distance_sq(vec2_a, vec2_b), 2.0);
449    /// ```
450    #[inline]
451    pub fn distance_sq(a: Self, b: Self) -> f32 {
452        (a - b).length_sq()
453    }
454
455    /// The dot product is an extremely useful operation! One major use is to determine how similar two vectors are.
456    /// If the vectors are Unit vectors (magnitude/length of 1), then the result will be 1 if the vectors are the same,
457    /// -1 if they’re opposite, and a gradient in-between with 0 being perpendicular.
458    /// <https://stereokit.net/Pages/StereoKit/Vec2/Dot.html>
459    /// * `a` - The first vector.
460    /// * `b` - The second vector.
461    ///
462    /// Returns the dot product!
463    /// ### Examples
464    /// ```
465    /// use stereokit_rust::maths::Vec2;
466    ///
467    /// let vec2_a = Vec2::new(1.0, 0.0);
468    /// let vec2_b = Vec2::new(0.0, 1.0);
469    /// assert_eq!(Vec2::dot(vec2_a, vec2_b), 0.0);
470    ///
471    /// let vec2_a = Vec2::new(1.0, 0.0);
472    /// let vec2_b = Vec2::new(1.0, 0.0);
473    /// assert_eq!(Vec2::dot(vec2_a, vec2_b), 1.0);
474    ///
475    /// let vec2_a = Vec2::new(1.0, 0.0);
476    /// let vec2_b = Vec2::new(-1.0, 0.0);
477    /// assert_eq!(Vec2::dot(vec2_a, vec2_b), -1.0);
478    /// ```
479    #[inline]
480    pub fn dot(a: Self, b: Self) -> f32 {
481        (a.x * b.x) + (a.y * b.y)
482    }
483
484    /// Creates a vector pointing in the direction of the angle, with a length of 1. Angles are counter-clockwise, and
485    /// start from (1,0), so an angle of 90 will be (0,1).
486    /// <https://stereokit.net/Pages/StereoKit/Vec2/FromAngle.html>
487    /// * `degrees` - Counter-clockwise angle from(1,0) in degrees.
488    ///
489    /// Returns a unit vector (length of 1), pointing towards degrees.
490    /// ### Examples
491    /// ```
492    /// use stereokit_rust::maths::Vec2;
493    ///
494    /// let vec2 = Vec2::from_angles(0.0);
495    /// assert_eq!(vec2, Vec2::new(1.0, 0.0));
496    ///
497    /// let vec2 = Vec2::from_angles(90.0);
498    /// assert_eq!(vec2, Vec2::new(0.0, 1.0));
499    ///
500    /// let vec2 = Vec2::from_angles(180.0);
501    /// assert_eq!(vec2, Vec2::new(-1.0, 0.0));
502    ///
503    /// let vec2 = Vec2::from_angles(270.0);
504    /// assert_eq!(vec2, Vec2::new(0.0, -1.0));
505    /// ```
506    #[inline]
507    pub fn from_angles(degree: f32) -> Self {
508        Self { x: degree.to_radians().cos(), y: degree.to_radians().sin() }
509    }
510
511    /// Blends (Linear Interpolation) between two vectors, based on a ‘blend’ value, where 0 is a, and 1 is b.
512    /// Doesn’t clamp percent for you.
513    /// <https://stereokit.net/Pages/StereoKit/Vec2/Lerp.html>
514    /// * `a` - The first vector to blend, or '0.0' blend.
515    /// * `b` - The second vector to blend, or '1.0' blend.
516    /// * `blend` - A value between 0 and 1. Can be outside this range, it’ll just interpolate outside of the a, b range.
517    ///
518    /// Returns an unclamped blend of a and b.
519    /// ### Examples
520    /// ```
521    /// use stereokit_rust::maths::Vec2;
522    ///
523    /// let vec2_a = Vec2::new(1.0, 0.0);
524    /// let vec2_b = Vec2::new(0.0, 1.0);
525    /// assert_eq!(Vec2::lerp(vec2_a, vec2_b, 0.5), Vec2::new(0.5, 0.5));
526    /// ```
527    #[inline]
528    pub fn lerp(a: Self, b: Self, blend: f32) -> Self {
529        a + ((b - a) * blend)
530    }
531
532    /// Returns a vector where each element is the maximum value for each corresponding pair.
533    /// <https://stereokit.net/Pages/StereoKit/Vec2/Max.html>
534    /// * `a` - Order isn't important here.
535    /// * `b` - Order isn't important here.
536    ///
537    /// Returns the maximum value for each corresponding vector pair.
538    /// ### Examples
539    /// ```
540    /// use stereokit_rust::maths::Vec2;
541    ///
542    /// let vec2_a = Vec2::new(1.0, 0.5);
543    /// let vec2_b = Vec2::new(0.9, 1.2);
544    /// assert_eq!(Vec2::max(vec2_a, vec2_b), Vec2::new(1.0, 1.2));
545    /// ```
546    #[inline]
547    pub fn max(a: Self, b: Self) -> Self {
548        Self { x: f32::max(a.x, b.x), y: f32::max(a.y, b.y) }
549    }
550
551    /// Returns a vector where each element is the minimum value for each corresponding pair.
552    /// <https://stereokit.net/Pages/StereoKit/Vec2/Min.html>
553    /// * `a` - Order isn't important here.
554    /// * `b` - Order isn't important here.
555    ///
556    /// Returns the minimum value for each corresponding vector pair.
557    /// ### Examples
558    /// ```
559    /// use stereokit_rust::maths::Vec2;
560    ///
561    /// let vec2_a = Vec2::new(1.0, 0.2);
562    /// let vec2_b = Vec2::new(0.1, 1.0);
563    /// assert_eq!(Vec2::min(vec2_a, vec2_b), Vec2::new(0.1, 0.2));
564    /// ```
565    #[inline]
566    pub fn min(a: Self, b: Self) -> Self {
567        Self { x: f32::min(a.x, b.x), y: f32::min(a.y, b.y) }
568    }
569
570    /// Absolute value of each component, this may be usefull in some case
571    ///
572    /// ### Examples
573    /// ```
574    /// use stereokit_rust::maths::Vec2;
575    ///
576    /// let vec2 = Vec2::new(-1.4, 1.2);
577    /// assert_eq!(vec2.abs(), Vec2::new(1.4, 1.2));
578    /// ```
579    #[inline]
580    pub fn abs(&self) -> Self {
581        Self { x: self.x.abs(), y: self.y.abs() }
582    }
583}
584
585impl Display for Vec2 {
586    /// Mostly for debug purposes, this is a decent way to log or inspect the vector in debug mode. Looks like “[x, y]”
587    /// <https://stereokit.net/Pages/StereoKit/Vec2/ToString.html>
588    ///
589    /// ### Examples
590    /// ```
591    /// use stereokit_rust::maths::Vec2;
592    ///
593    /// let vec2 = Vec2::new(1.0, 1.0);
594    /// assert_eq!(vec2.to_string(), "[x:1, y:1]");
595    /// ```
596    #[inline]
597    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
598        write!(f, "[x:{}, y:{}]", self.x, self.y)
599    }
600}
601/// A component-wise vector division.
602/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Division.html>
603impl Div<Vec2> for Vec2 {
604    type Output = Self;
605
606    /// ### Examples
607    /// ```
608    /// use stereokit_rust::maths::Vec2;
609    ///
610    /// let vec2_a = Vec2::new(1.0, 2.0);
611    /// let vec2_b = Vec2::new(2.0, 4.0);
612    /// assert_eq!(vec2_a / vec2_b, Vec2::new(0.5, 0.5));
613    /// ```
614    #[inline]
615    fn div(self, rhs: Self) -> Self::Output {
616        Self { x: self.x.div(rhs.x), y: self.y.div(rhs.y) }
617    }
618}
619
620/// A component-wise vector division.
621/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Division.html>
622impl DivAssign<Vec2> for Vec2 {
623    /// ### Examples
624    /// ```
625    /// use stereokit_rust::maths::Vec2;
626    ///
627    /// let mut vec2_a = Vec2::new(1.0, 2.0);
628    /// let vec2_b = Vec2::new(2.0, 4.0);
629    /// vec2_a /= vec2_b;
630    /// assert_eq!(vec2_a, Vec2::new(0.5, 0.5));
631    /// ```
632    #[inline]
633    fn div_assign(&mut self, rhs: Self) {
634        self.x.div_assign(rhs.x);
635        self.y.div_assign(rhs.y);
636    }
637}
638
639/// A component-wise vector division.
640/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Division.html>
641impl Div<f32> for Vec2 {
642    type Output = Self;
643
644    /// ### Examples
645    /// ```
646    /// use stereokit_rust::maths::Vec2;
647    ///
648    /// let vec2_a = Vec2::new(1.0, 2.0);
649    /// assert_eq!(vec2_a / 2.0, Vec2::new(0.5, 1.0));
650    /// ```
651    #[inline]
652    fn div(self, rhs: f32) -> Self::Output {
653        Self { x: self.x.div(rhs), y: self.y.div(rhs) }
654    }
655}
656
657/// A component-wise vector division.
658/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Division.html>
659impl DivAssign<f32> for Vec2 {
660    /// ### Examples
661    /// ```
662    /// use stereokit_rust::maths::Vec2;
663    ///
664    /// let mut vec2_a = Vec2::new(1.0, 2.0);
665    /// vec2_a /= 2.0;
666    /// assert_eq!(vec2_a, Vec2::new(0.5, 1.0));
667    /// ```
668    #[inline]
669    fn div_assign(&mut self, rhs: f32) {
670        self.x.div_assign(rhs);
671        self.y.div_assign(rhs);
672    }
673}
674
675/// A component-wise vector division.
676/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Division.html>
677impl Div<Vec2> for f32 {
678    type Output = Vec2;
679
680    /// ### Examples
681    /// ```
682    /// use stereokit_rust::maths::Vec2;
683    ///
684    /// let vec2_a = Vec2::new(1.0, 2.0);
685    /// assert_eq!(2.0 / vec2_a, Vec2::new(2.0, 1.0));
686    /// ```
687    #[inline]
688    fn div(self, rhs: Vec2) -> Self::Output {
689        Vec2 { x: self.div(rhs.x), y: self.div(rhs.y) }
690    }
691}
692
693/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot product! Commutative.
694/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Multiply.html>
695impl Mul<Vec2> for Vec2 {
696    type Output = Self;
697
698    /// ### Examples
699    /// ```
700    /// use stereokit_rust::maths::Vec2;
701    ///
702    /// let vec2_a = Vec2::new(1.0, 2.0);
703    /// let vec2_b = Vec2::new(2.0, 4.0);
704    /// assert_eq!(vec2_a * vec2_b, Vec2::new(2.0, 8.0));
705    /// ```
706    #[inline]
707    fn mul(self, rhs: Self) -> Self::Output {
708        Self { x: self.x.mul(rhs.x), y: self.y.mul(rhs.y) }
709    }
710}
711
712/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot product! Commutative.
713/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Multiply.html>
714impl MulAssign<Vec2> for Vec2 {
715    /// ### Examples
716    /// ```
717    /// use stereokit_rust::maths::Vec2;
718    ///
719    /// let vec2_a = Vec2::new(1.0, 2.0);
720    /// let mut vec2_b = Vec2::new(2.0, 4.0);
721    /// vec2_b *= vec2_a;
722    /// assert_eq!(vec2_b, Vec2::new(2.0, 8.0));
723    /// ```
724    #[inline]
725    fn mul_assign(&mut self, rhs: Self) {
726        self.x.mul_assign(rhs.x);
727        self.y.mul_assign(rhs.y);
728    }
729}
730
731/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot product! Commutative.
732/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Multiply.html>
733impl Mul<f32> for Vec2 {
734    type Output = Self;
735
736    /// ### Examples
737    /// ```
738    /// use stereokit_rust::maths::Vec2;
739    ///
740    /// let vec2_a = Vec2::new(1.0, 2.0);
741    /// assert_eq!(vec2_a * 2.0, Vec2::new(2.0, 4.0));
742    /// ```
743    #[inline]
744    fn mul(self, rhs: f32) -> Self::Output {
745        Self { x: self.x.mul(rhs), y: self.y.mul(rhs) }
746    }
747}
748
749/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot product! Commutative.
750/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Multiply.html>
751impl MulAssign<f32> for Vec2 {
752    /// ### Examples
753    /// ```
754    /// use stereokit_rust::maths::Vec2;
755    ///
756    /// let mut vec2_a = Vec2::new(1.0, 2.0);
757    /// vec2_a *= 2.0;
758    /// assert_eq!(vec2_a, Vec2::new(2.0, 4.0));
759    ///```
760    #[inline]
761    fn mul_assign(&mut self, rhs: f32) {
762        self.x.mul_assign(rhs);
763        self.y.mul_assign(rhs);
764    }
765}
766
767/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot product! Commutative.
768/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Multiply.html>
769impl Mul<Vec2> for f32 {
770    type Output = Vec2;
771
772    /// ### Examples
773    /// ```
774    /// use stereokit_rust::maths::Vec2;
775    ///
776    /// let vec2_a = Vec2::new(1.0, 2.0);
777    /// assert_eq!(2.0 * vec2_a, Vec2::new(2.0, 4.0));
778    /// ```
779    #[inline]
780    fn mul(self, rhs: Vec2) -> Self::Output {
781        Vec2 { x: self.mul(rhs.x), y: self.mul(rhs.y) }
782    }
783}
784
785/// Adds matching components together. Commutative.
786/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Addition.html>
787impl Add<Vec2> for Vec2 {
788    type Output = Self;
789
790    /// ### Examples
791    /// ```
792    /// use stereokit_rust::maths::Vec2;
793    ///
794    /// let vec2_a = Vec2::new(1.0, 2.0);
795    /// let vec2_b = Vec2::new(2.0, 4.0);
796    /// assert_eq!(vec2_a + vec2_b, Vec2::new(3.0, 6.0));
797    /// ```
798    #[inline]
799    fn add(self, rhs: Self) -> Self::Output {
800        Self { x: self.x.add(rhs.x), y: self.y.add(rhs.y) }
801    }
802}
803
804/// Adds matching components together. Commutative.
805/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Addition.html>
806impl AddAssign<Vec2> for Vec2 {
807    /// ### Examples
808    /// ```
809    /// use stereokit_rust::maths::Vec2;
810    ///
811    /// let mut vec2_a = Vec2::new(1.0, 2.0);
812    /// let vec2_b = Vec2::new(2.0, 4.0);
813    /// vec2_a += vec2_b;
814    /// assert_eq!(vec2_a, Vec2::new(3.0, 6.0));
815    /// ```
816    #[inline]
817    fn add_assign(&mut self, rhs: Self) {
818        self.x.add_assign(rhs.x);
819        self.y.add_assign(rhs.y);
820    }
821}
822
823/// Subtracts matching components from eachother. Not commutative.
824/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Subtraction.html>
825impl Sub<Vec2> for Vec2 {
826    type Output = Self;
827
828    /// ### Examples
829    /// ```
830    /// use stereokit_rust::maths::Vec2;
831    ///
832    /// let vec2_a = Vec2::new(1.0, 2.0);
833    /// let vec2_b = Vec2::new(2.0, 4.0);
834    /// assert_eq!(vec2_a - vec2_b, Vec2::new(-1.0, -2.0));
835    /// ```
836    #[inline]
837    fn sub(self, rhs: Self) -> Self::Output {
838        Self { x: self.x.sub(rhs.x), y: self.y.sub(rhs.y) }
839    }
840}
841
842/// Subtracts matching components from eachother. Not commutative.
843/// <https://stereokit.net/Pages/StereoKit/Vec2/op_Subtraction.html>
844impl SubAssign<Vec2> for Vec2 {
845    /// ### Examples
846    /// ```
847    /// use stereokit_rust::maths::Vec2;
848    ///
849    /// let mut vec2_a = Vec2::new(1.0, 2.0);
850    /// let vec2_b = Vec2::new(2.0, 4.0);
851    /// vec2_a -= vec2_b;
852    /// assert_eq!(vec2_a, Vec2::new(-1.0, -2.0));
853    /// ```
854    #[inline]
855    fn sub_assign(&mut self, rhs: Vec2) {
856        self.x.sub_assign(rhs.x);
857        self.y.sub_assign(rhs.y);
858    }
859}
860
861/// Vector negation, returns a vector where each component has been negated.
862/// <https://stereokit.net/Pages/StereoKit/Vec2/op_UnaryNegation.html>
863impl Neg for Vec2 {
864    type Output = Self;
865    /// ### Examples
866    /// ```
867    /// use stereokit_rust::maths::Vec2;
868    ///
869    /// let vec2_a = Vec2::new(1.0, 2.0);
870    /// assert_eq!(-vec2_a, Vec2::new(-1.0, -2.0));
871    /// ```
872    #[inline]
873    fn neg(self) -> Self::Output {
874        self * -1.0
875    }
876}
877
878/// A vector with 3 components: x, y, z. This can represent a point in space, a directional vector, or any other sort of
879/// value with 3 dimensions to it!
880///
881/// StereoKit uses a right-handed coordinate system, where +x is to the right, +y is upwards, and -z is forward.
882/// <https://stereokit.net/Pages/StereoKit/Vec3.html>
883///
884/// see also [`glam::Vec3`]
885/// ### Examples
886/// ```
887/// use stereokit_rust::maths::Vec3;
888///
889/// let vec3        = Vec3::new(1.0, 2.0, 3.0);
890/// let vec3a       = Vec3 { x: 1.0, y: 2.0, z:3.0 };
891/// let vec3b       = Vec3::X + Vec3::Y * 2.0;
892/// let vec3c: Vec3 = [1.0, 2.0, 3.0].into();
893///
894/// assert_eq!(vec3, vec3a);
895/// assert_eq!(vec3a + vec3b,                   Vec3 { x: 2.0, y: 4.0, z: 3.0 });
896/// assert_eq!(vec3c,                           Vec3 { x: 1.0, y: 2.0, z: 3.0 });
897/// assert_eq!(vec3a.length_sq(),               14.0);
898/// assert_eq!(vec3a.magnitude(),               (14.0f32).sqrt());
899/// assert!   (vec3a.get_normalized().length() - 1.0 < f32::EPSILON);
900/// assert_eq!(Vec3::angle_between(Vec3::X, Vec3::Y), 90.0);
901/// assert_eq!(Vec3::dot(Vec3::X, Vec3::Y), 0.0);
902/// ```
903#[derive(Debug, Default, Copy, Clone)]
904#[repr(C)]
905pub struct Vec3 {
906    pub x: f32,
907    pub y: f32,
908    pub z: f32,
909}
910
911impl From<glam::Vec3> for Vec3 {
912    fn from(val: glam::Vec3) -> Self {
913        Vec3 { x: val.x, y: val.y, z: val.z }
914    }
915}
916
917impl From<Vec3> for glam::Vec3 {
918    fn from(val: Vec3) -> Self {
919        Self::new(val.x, val.y, val.z)
920    }
921}
922
923impl From<[f32; 3]> for Vec3 {
924    fn from(val: [f32; 3]) -> Self {
925        Vec3 { x: val[0], y: val[1], z: val[2] }
926    }
927}
928
929impl From<Vec3> for [f32; 3] {
930    fn from(val: Vec3) -> Self {
931        [val.x, val.y, val.z]
932    }
933}
934
935///  Warning: Equality with a precision of 0.1 millimeter
936impl PartialEq for Vec3 {
937    ///  Warning: Equality with a precision of 0.1 millimeter
938    /// ### Example
939    /// ```
940    /// use stereokit_rust::maths::Vec3;
941    /// assert_eq!(
942    ///              Vec3 { x: 0.045863353, y: 0.030000005, z: 0.0 } ,
943    ///              Vec3 { x: 0.045863353, y: 0.030000005, z: 0.0 } );
944    /// ```
945    /// ```
946    /// use stereokit_rust::maths::Vec3;
947    /// assert_ne!(
948    ///              Vec3 { x: 10.045863353, y: 0.030000005, z: 0.0 } ,
949    ///              Vec3 { x: 0.045863353, y: 0.030000005, z: 0.0 } );
950    /// ```
951    fn eq(&self, other: &Self) -> bool {
952        ((self.x - other.x).abs() < 0.0001)
953            && ((self.y - other.y).abs() < 0.0001)
954            && ((self.z - other.z).abs() < 0.0001)
955    }
956}
957
958unsafe extern "C" {
959    pub fn vec3_cross(a: *const Vec3, b: *const Vec3) -> Vec3;
960}
961
962impl Vec3 {
963    /// StereoKit uses a right-handed coordinate system, which means that forward is looking down the -Z axis! This
964    /// value is the same as new Vec3(0,0,-1). This is NOT the same as UnitZ!
965    /// <https://stereokit.net/Pages/StereoKit/Vec3/Forward.html>
966    pub const FORWARD: Self = Self::NEG_Z;
967
968    /// Shorthand for a vector where all values are 1! Same as new Vec3(1,1,1).
969    /// <https://stereokit.net/Pages/StereoKit/Vec3/One.html>
970    pub const ONE: Self = Self::new(1.0, 1.0, 1.0);
971
972    /// Shorthand for a vector where all values are -1! Same as new Vec3(-1,-1,-1).
973    pub const NEG_ONE: Self = Self::new(-1.0, -1.0, -1.0);
974
975    /// When looking forward, this is the direction to the right! In StereoKit, this is the same as new Vec3(1,0,0)
976    /// <https://stereokit.net/Pages/StereoKit/Vec3/Right.html>
977    pub const RIGHT: Self = Self::X;
978
979    /// A normalized Vector that points down the X axis, this is the same as new Vec3(1,0,0).
980    /// <https://stereokit.net/Pages/StereoKit/Vec3/UnitX.html>
981    pub const X: Self = Self::new(1.0, 0.0, 0.0);
982
983    /// A normalized Vector that points down the Y axis, this is the same as new Vec3(0,1,0).
984    /// <https://stereokit.net/Pages/StereoKit/Vec3/UnitY.html>
985    pub const Y: Self = Self::new(0.0, 1.0, 0.0);
986
987    /// A normalized Vector that points down the Z axis, this is the same as new Vec3(0,0,1).
988    /// This is NOT the same as Forward!
989    /// <https://stereokit.net/Pages/StereoKit/Vec3/UnitZ.html>
990    pub const Z: Self = Self::new(0.0, 0.0, 1.0);
991
992    ///  A normalized Vector that points up the Z axis, this is the same as new Vec3(0,0,-1).
993    pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0);
994
995    /// A normalized Vector that points up the Y axis, this is the same as new Vec3(0,-1,0).
996    pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0);
997
998    /// A normalized Vector that points up the Z axis, this is the same as new Vec3(0,0,-1).
999    /// This is the same as Forward!
1000    pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0);
1001
1002    /// A vector representing the up axis. In StereoKit, this is the same as new Vec3(0,1,0).
1003    /// <https://stereokit.net/Pages/StereoKit/Vec3/Up.html>
1004    pub const UP: Self = Self::Y;
1005
1006    /// Shorthand for a vector where all values are 0! Same as new Vec3(0,0,0).
1007    /// <https://stereokit.net/Pages/StereoKit/Vec3/Zero.html>
1008    pub const ZERO: Vec3 = Self::new(0.0, 0.0, 0.0);
1009
1010    /// Creates a vector from x, y, and z values! StereoKit uses a right-handed metric coordinate system, where +x is to
1011    /// the right, +y is upwards, and -z is forward.
1012    /// <https://stereokit.net/Pages/StereoKit/Vec3/Vec3.html>
1013    #[inline]
1014    pub const fn new(x: f32, y: f32, z: f32) -> Self {
1015        Self { x, y, z }
1016    }
1017
1018    /// Checks if a point is within a certain radius of this one. This is an easily readable shorthand of the squared
1019    /// distance check.
1020    /// <https://stereokit.net/Pages/StereoKit/Vec3/InRadius.html>
1021    /// * `point`- The point to check against.
1022    /// * `radius` - The radius to check within.
1023    ///
1024    /// Returns true if the points are within radius of each other, false not.
1025    /// ### Examples
1026    /// ```
1027    /// use stereokit_rust::maths::Vec3;
1028    ///
1029    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1030    /// let vec3_b = Vec3::new(2.0, 4.0, 6.0);
1031    /// assert_eq!(vec3_a.in_radius(vec3_b, 5.0), true);
1032    /// assert_eq!(vec3_a.in_radius(vec3_b, 2.0), false);
1033    /// ```
1034    #[inline]
1035    pub fn in_radius(&self, point: Self, radius: f32) -> bool {
1036        Self::distance(*self, point) <= radius
1037    }
1038
1039    /// Turns this vector into a normalized vector (vector with a length of 1) from the current vector. Will not work
1040    /// properly if the vector has a length of zero. Vec3::get_normalized is faster.
1041    /// <https://stereokit.net/Pages/StereoKit/Vec3/Normalize.html>
1042    ///
1043    /// ### Examples
1044    /// ```
1045    /// use stereokit_rust::maths::Vec3;
1046    ///
1047    /// let mut vec3_a = Vec3::new(1.0, 2.0, 3.0);
1048    /// vec3_a.normalize();
1049    /// assert_eq!(vec3_a, Vec3::new(0.26726124, 0.5345225, 0.8017837));
1050    /// ```
1051    #[inline]
1052    pub fn normalize(&mut self) {
1053        let n = *self * (self.length().recip());
1054        self.x = n.x;
1055        self.y = n.y;
1056        self.z = n.z;
1057    }
1058
1059    /// This is the length, or magnitude of the vector! The distance from the origin to this point.
1060    /// Uses f32::sqrt, so it’s not dirt cheap or anything.
1061    /// <https://stereokit.net/Pages/StereoKit/Vec3/Length.html>
1062    ///
1063    /// ### Examples
1064    /// ```
1065    /// use stereokit_rust::maths::Vec3;
1066    ///
1067    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1068    /// assert_eq!(vec3_a.length(), 3.7416575);
1069    /// ```
1070    #[inline]
1071    pub fn length(&self) -> f32 {
1072        Self::dot(*self, *self).sqrt()
1073    }
1074
1075    /// This is the squared length of the vector! It skips the Sqrt call, and just gives you the squared version for
1076    /// speedy calculations that can work with it squared.
1077    /// <https://stereokit.net/Pages/StereoKit/Vec3/LengthSq.html>
1078    ///
1079    /// ### Examples
1080    /// ```
1081    /// use stereokit_rust::maths::Vec3;
1082    ///
1083    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1084    /// assert_eq!(vec3_a.length_sq(), 14.0);
1085    /// ```
1086    #[inline]
1087    pub fn length_sq(&self) -> f32 {
1088        Self::dot(*self, *self)
1089    }
1090
1091    /// Magnitude is the length of the vector! The distance from the origin to this point. Uses f32::sqrt, so it’s not
1092    /// dirt cheap or anything.
1093    /// <https://stereokit.net/Pages/StereoKit/Vec3/Magnitude.html>
1094    ///
1095    /// ### Examples
1096    /// ```
1097    /// use stereokit_rust::maths::Vec3;
1098    ///
1099    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1100    /// assert_eq!(vec3_a.length(), 3.7416575);
1101    /// ```
1102    #[inline]
1103    pub fn magnitude(&self) -> f32 {
1104        self.length()
1105    }
1106
1107    /// This is the squared magnitude of the vector! It skips the Sqrt call, and just gives you the squared version for
1108    /// speedy calculations that can work with it squared.
1109    /// <https://stereokit.net/Pages/StereoKit/Vec3/MagnitudeSq.html>
1110    ///
1111    /// ### Examples
1112    /// ```
1113    /// use stereokit_rust::maths::Vec3;
1114    ///
1115    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1116    /// assert_eq!(vec3_a.magnitude_squared(), 14.0);
1117    /// ```
1118    #[inline]
1119    pub fn magnitude_squared(&self) -> f32 {
1120        self.length_sq()
1121    }
1122
1123    /// Creates a normalized vector (vector with a length of 1) from the current vector. Will not work properly if the
1124    /// vector has a length of zero.
1125    /// <https://stereokit.net/Pages/StereoKit/Vec3/Normalized.html>
1126    ///
1127    /// ### Examples
1128    /// ```
1129    /// use stereokit_rust::maths::Vec3;
1130    ///
1131    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1132    /// assert_eq!(vec3_a.get_normalized(), Vec3::new(0.26726124, 0.5345225, 0.8017837));
1133    /// ```
1134    #[inline]
1135    pub fn get_normalized(&self) -> Self {
1136        *self * (self.length().recip())
1137    }
1138
1139    /// This returns a Vec3 that has been flattened to 0 on the Y axis. No other changes are made.
1140    /// <https://stereokit.net/Pages/StereoKit/Vec3/X0Z.html>
1141    ///
1142    /// ### Examples
1143    /// ```
1144    /// use stereokit_rust::maths::Vec3;
1145    ///
1146    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1147    /// assert_eq!(vec3_a.x0z(), Vec3::new(1.0, 0.0, 3.0));
1148    /// ```
1149    #[inline]
1150    pub fn x0z(&self) -> Self {
1151        Self { x: self.x, y: 0.0, z: self.z }
1152    }
1153
1154    /// This returns a Vec3 that has been flattened to 0 on the Z axis. No other changes are made.
1155    /// <https://stereokit.net/Pages/StereoKit/Vec3/XY0.html>
1156    ///
1157    /// ### Examples
1158    /// ```
1159    /// use stereokit_rust::maths::Vec3;
1160    ///
1161    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1162    /// assert_eq!(vec3_a.xy0(), Vec3::new(1.0, 2.0, 0.0));
1163    /// ```
1164    #[inline]
1165    pub fn xy0(&self) -> Self {
1166        Self { x: self.x, y: self.y, z: 0.0 }
1167    }
1168
1169    /// This returns a Vec3 that has been set to 1 on the Z axis. No other changes are made
1170    /// <https://stereokit.net/Pages/StereoKit/Vec3/XY1.html>
1171    ///
1172    /// ### Examples
1173    /// ```
1174    /// use stereokit_rust::maths::Vec3;
1175    ///
1176    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1177    /// assert_eq!(vec3_a.xy1(), Vec3::new(1.0, 2.0, 1.0));
1178    /// ```
1179    #[inline]
1180    pub fn xy1(&self) -> Self {
1181        Self { x: self.x, y: self.y, z: 1.0 }
1182    }
1183
1184    /// This extracts the Vec2 from the X and Y axes.
1185    /// <https://stereokit.net/Pages/StereoKit/Vec3.html>
1186    ///
1187    /// ### Examples
1188    /// ```
1189    /// use stereokit_rust::maths::{Vec2, Vec3};
1190    ///
1191    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1192    /// assert_eq!(vec3_a.xy(), Vec2::new(1.0, 2.0));
1193    /// ```
1194    #[inline]
1195    pub fn xy(&self) -> Vec2 {
1196        Vec2::new(self.x, self.y)
1197    }
1198
1199    /// This extracts the Vec2 from the Y and Z axes.
1200    /// <https://stereokit.net/Pages/StereoKit/Vec3/YZ.html>
1201    ///
1202    /// ### Examples
1203    /// ```
1204    /// use stereokit_rust::maths::{Vec2, Vec3};
1205    ///
1206    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1207    /// assert_eq!(vec3_a.yz(), Vec2::new(2.0, 3.0));
1208    /// ```
1209    #[inline]
1210    pub fn yz(&self) -> Vec2 {
1211        Vec2::new(self.y, self.z)
1212    }
1213
1214    /// This extracts the Vec2 from the X and Z axes.
1215    /// <https://stereokit.net/Pages/StereoKit/Vec3.html>
1216    ///
1217    /// ### Examples
1218    /// ```
1219    /// use stereokit_rust::maths::{Vec2, Vec3};
1220    ///
1221    /// let vec3_a = Vec3::new(1.0, 2.0, 3.0);
1222    /// assert_eq!(vec3_a.xz(), Vec2::new(1.0, 3.0));
1223    /// ```
1224    #[inline]
1225    pub fn xz(&self) -> Vec2 {
1226        Vec2::new(self.x, self.z)
1227    }
1228
1229    /// Calculates the angle between two vectors in degrees! Vectors do not need to be normalized, and the result will
1230    /// always be positive.
1231    /// <https://stereokit.net/Pages/StereoKit/Vec3/AngleBetween.html>
1232    /// * `a` - The first, initial vector, A. Does not need to be normalized.
1233    /// * `b` - The second vector, B, that we're finding the angle to. Does not need to be normalized.
1234    ///
1235    /// Returns a positive angle between two vectors in degrees!
1236    /// ### Examples
1237    /// ```
1238    /// use stereokit_rust::maths::Vec3;
1239    ///
1240    /// let vec3_b = Vec3::new(0.0, 1.0, 0.0);
1241    /// assert_eq!(Vec3::angle_between(Vec3::X, vec3_b), 90.0);
1242    ///
1243    /// let vec3_c = Vec3::new(-1.0, 0.0, 0.0);
1244    /// assert_eq!(Vec3::angle_between(Vec3::X, vec3_c), 180.0);
1245    ///
1246    /// let vec3_d = Vec3::new(1.0, 0.0, 1.0);
1247    /// assert_eq!(Vec3::angle_between(Vec3::X, vec3_d), 45.0);
1248    /// ```
1249    #[inline]
1250    pub fn angle_between(a: Self, b: Self) -> f32 {
1251        (Self::dot(a, b) / (a.length_sq() * b.length_sq()).sqrt()).acos().to_degrees()
1252    }
1253
1254    /// Creates a vector that points out at the given 2D angle! This creates the vector on the XY plane, and allows you
1255    /// to specify a constant z value.
1256    /// <https://stereokit.net/Pages/StereoKit/Vec3/AngleXY.html>
1257    /// * `angle_deg` - The angle in degrees, starting from the (1,0) at 0, and continuing to (0,1) at 90, etc.
1258    /// * `z` - The constant Z value for this vector.
1259    ///
1260    /// Returns a vector pointing at the given angle! If z is zero, this will be a normalized vector (vector with
1261    /// a length of 1).
1262    /// ### Examples
1263    /// ```
1264    /// use stereokit_rust::maths::Vec3;
1265    ///
1266    /// let angle = 45.0;
1267    /// let z = 0.0;
1268    /// let vector = Vec3::angle_xy(angle, z);
1269    /// assert_eq!(vector, Vec3::new(0.70710677, 0.70710677, 0.0));
1270    /// ```
1271    #[inline]
1272    pub fn angle_xy(angle_deg: f32, z: f32) -> Vec3 {
1273        Self { x: angle_deg.to_radians().cos(), y: angle_deg.to_radians().sin(), z }
1274    }
1275
1276    /// Creates a vector that points out at the given 2D angle! This creates the vector on the XZ plane, and allows you
1277    /// to specify a constant y value.
1278    /// <https://stereokit.net/Pages/StereoKit/Vec3/AngleXZ.html>
1279    /// * `angle_deg` - The angle in degrees, starting from the (1,0) at 0, and continuing to (0,1) at 90, etc.
1280    /// * `y` - The constant Y value for this vector.
1281    ///
1282    /// Returns A Vector pointing at the given angle! If y is zero, this will be a normalized vector (vector with a
1283    /// length of 1).
1284    /// ### Examples
1285    /// ```
1286    /// use stereokit_rust::maths::Vec3;
1287    /// let vec = Vec3::angle_xz(90.0, 0.0);
1288    /// assert_eq!(vec, Vec3::new(0.0, 0.0, 1.0));
1289    /// ```
1290    #[inline]
1291    pub fn angle_xz(angle_deg: f32, y: f32) -> Self {
1292        Self { x: angle_deg.to_radians().cos(), y, z: angle_deg.to_radians().sin() }
1293    }
1294
1295    /// The cross product of two vectors!
1296    /// <https://stereokit.net/Pages/StereoKit/Vec3/Cross.html>
1297    /// * `a` - The first vector.
1298    /// * `b` - The second vector.
1299    ///
1300    /// Returns is **not** a unit vector, even if both ‘a’ and ‘b’ are unit vectors.
1301    /// see also [`vec3_cross`]
1302    /// ### Examples
1303    ///```
1304    /// use stereokit_rust::maths::Vec3;
1305    ///
1306    /// // Test case 1: Basic cross product
1307    /// let a = Vec3::new(1.0, 0.0, 0.0);
1308    /// let b = Vec3::new(0.0, 1.0, 0.0);
1309    /// let result = Vec3::cross(a, b);
1310    /// assert_eq!(result, Vec3::new(0.0, 0.0, 1.0));
1311    ///
1312    /// // Test case 2: Cross product in different direction
1313    /// let a = Vec3::new(0.0, 1.0, 0.0);
1314    /// let b = Vec3::new(1.0, 0.0, 0.0);
1315    /// let result = Vec3::cross(a, b);
1316    /// assert_eq!(result, Vec3::new(0.0, 0.0, -1.0));
1317    ///
1318    /// // Test case 3: Cross product with non-unit vectors
1319    /// let a = Vec3::new(2.0, 0.0, 0.0);
1320    /// let b = Vec3::new(0.0, 3.0, 0.0);
1321    /// let result = Vec3::cross(a, b);
1322    /// assert_eq!(result, Vec3::new(0.0, 0.0, 6.0));
1323    ///
1324    /// // Test case 4: Cross product of parallel vectors
1325    /// let a = Vec3::new(1.0, 0.0, 0.0);
1326    /// let b = Vec3::new(2.0, 0.0, 0.0);
1327    /// let result = Vec3::cross(a, b);
1328    /// assert_eq!(result, Vec3::ZERO);
1329    ///
1330    /// // Test case 5: cross product of orthogonal vector
1331    /// let a = Vec3::new(1.0, 2.0, 3.0);
1332    /// let b = Vec3::new(4.0, 5.0, 6.0);
1333    /// let result = Vec3::cross(a,b);
1334    /// assert_eq!(result, Vec3::new(-3.0, 6.0, -3.0));
1335    ///
1336    /// // Test case 6: cross product of orthogonal vector
1337    /// let a = Vec3::new(4.0, 5.0, 6.0);
1338    /// let b = Vec3::new(1.0, 2.0, 3.0);
1339    /// let result = Vec3::cross(a,b);
1340    /// assert_eq!(result, Vec3::new(3.0, -6.0, 3.0));
1341    /// ```
1342    #[inline]
1343    pub fn cross(a: Self, b: Self) -> Self {
1344        unsafe { vec3_cross(&a, &b) }
1345    }
1346
1347    /// Creates a normalized delta vector that points out from an origin point to a target point!
1348    /// <https://stereokit.net/Pages/StereoKit/Vec3/Direction.html>
1349    /// * `to` - The target point.
1350    /// * `from` - The origin point.
1351    ///
1352    /// Returns direction from one point to another.
1353    /// ### Examples
1354    /// ```
1355    /// use stereokit_rust::maths::Vec3;
1356    ///
1357    /// let a = Vec3::new(1.0, 2.0, 3.0);
1358    /// let b = Vec3::new(4.0, 5.0, 6.0);
1359    /// let direction = Vec3::direction(a, b);
1360    /// assert_eq!(direction, Vec3 { x: -0.57735026, y: -0.57735026, z: -0.57735026 });
1361    /// ```
1362    #[inline]
1363    pub fn direction(to: Self, from: Self) -> Self {
1364        (to - from).get_normalized()
1365    }
1366
1367    /// Calculates the distance between two points in space! Make sure they’re in the same coordinate space! Uses a
1368    /// Sqrt, so it’s not blazing fast, prefer DistanceSq when possible.
1369    /// <https://stereokit.net/Pages/StereoKit/Vec3/Distance.html>
1370    /// * `a` - The first point.
1371    /// * `b` - The second point.
1372    ///
1373    /// Returns the distance between the two points.
1374    /// ### Examples
1375    /// ```
1376    /// use stereokit_rust::maths::Vec3;
1377    ///
1378    /// let a = Vec3 { x: 1.0, y: 2.0, z: 3.0 };
1379    /// let b = Vec3 { x: 4.0, y: 5.0, z: 6.0 };
1380    /// let distance = Vec3::distance(a, b);
1381    /// assert_eq!(distance, 5.196152);
1382    /// ```
1383    #[inline]
1384    pub fn distance(a: Self, b: Self) -> f32 {
1385        (a - b).length()
1386    }
1387
1388    /// Calculates the distance between two points in space, but leaves them squared! Make sure they’re in the same
1389    /// coordinate space! This is a fast function :)
1390    /// <https://stereokit.net/Pages/StereoKit/Vec3/DistanceSq.html>
1391    /// * `a` - The first point.
1392    /// * `b` - The second point.
1393    ///
1394    /// Returns the distance between the two points, but squared.
1395    /// ### Examples
1396    /// ```
1397    /// use stereokit_rust::maths::Vec3;
1398    ///
1399    /// let a = Vec3::new(1.0, 2.0, 3.0);
1400    /// let b = Vec3::new(4.0, 5.0, 6.0);
1401    /// let distance = Vec3::distance_sq(a, b);
1402    /// assert_eq!(distance, 27.0);
1403    /// ```
1404    #[inline]
1405    pub fn distance_sq(a: Self, b: Self) -> f32 {
1406        (a - b).length_sq()
1407    }
1408
1409    /// The dot product is an extremely useful operation! One major use is to determine how similar two vectors are. If
1410    /// the vectors are Unit vectors (magnitude/length of 1), then the result will be 1 if the vectors are the same, -1
1411    /// if they’re opposite, and a gradient in-between with 0 being perpendicular.  See [Freya Holmer’s excellent
1412    /// visualization of this concept](<https://twitter.com/FreyaHolmer/status/1200807790580768768>)
1413    /// <https://stereokit.net/Pages/StereoKit/Vec3/Dot.html>
1414    /// * `a` - The first vector.
1415    /// * `b` - The second vector.
1416    ///
1417    /// Returns the dot product of the two vectors.
1418    /// ### Examples
1419    /// ```
1420    /// use stereokit_rust::maths::Vec3;
1421    ///
1422    /// let a = Vec3::new(1.0, 0.0, 1.0);
1423    /// let b = Vec3::new(1.0, 1.0, 0.0);
1424    /// let dot_product = Vec3::dot(a, b);
1425    /// assert_eq!(dot_product, 1.0);
1426    /// ```
1427    #[inline]
1428    pub fn dot(a: Self, b: Self) -> f32 {
1429        (a.x * b.x) + (a.y * b.y) + (a.z * b.z)
1430    }
1431
1432    /// Blends (Linear Interpolation) between two vectors, based on a ‘blend’ value, where 0 is a, and 1 is b. Doesn’t
1433    /// clamp percent for you.
1434    /// <https://stereokit.net/Pages/StereoKit/Vec3/Lerp.html>
1435    /// * `a` - First item in the blend, or '0.0' blend.
1436    /// * `b` - Second item in the blend, or '1.0' blend.
1437    /// * `blend` - The blend value between 0 and 1. Can be outside this range, it’ll just interpolate outside of the a,
1438    ///   b range.
1439    ///
1440    /// Returns a blend value between 0 and 1. Can be outside this range, it’ll just interpolate outside of the a, b
1441    /// range.
1442    /// ### Examples
1443    /// ```
1444    /// use stereokit_rust::maths::Vec3;
1445    ///
1446    /// let a = Vec3::new(1.0, 2.0, 3.0);
1447    /// let b = Vec3::new(4.0, 5.0, 6.0);
1448    /// let blend = 0.25;
1449    /// let result = Vec3::lerp(a, b, blend);
1450    /// assert_eq!(result, Vec3::new(1.75, 2.75, 3.75));
1451    /// ```
1452    #[inline]
1453    pub fn lerp(a: Self, b: Self, blend: f32) -> Self {
1454        a + ((b - a) * blend)
1455    }
1456
1457    /// Returns a vector where each element is the maximum value for each corresponding pair.
1458    /// <https://stereokit.net/Pages/StereoKit/Vec3/Max.html>
1459    /// * `a` - Order isn't important here.
1460    /// * `b` - Order isn't important here.
1461    ///
1462    /// Returns the maximum value for each corresponding vector pair.
1463    /// ### Examples
1464    /// ```
1465    /// use stereokit_rust::maths::Vec3;
1466    ///
1467    /// let a = Vec3::new(1.0, 6.0, 3.0);
1468    /// let b = Vec3::new(4.0, 5.0, 6.0);
1469    /// let result = Vec3::max(a, b);
1470    /// assert_eq!(result, Vec3::new(4.0, 6.0, 6.0));
1471    /// ```
1472    #[inline]
1473    pub fn max(a: Self, b: Self) -> Self {
1474        Self { x: f32::max(a.x, b.x), y: f32::max(a.y, b.y), z: f32::max(a.z, b.z) }
1475    }
1476
1477    /// Returns a vector where each element is the minimum value for each corresponding pair.
1478    /// <https://stereokit.net/Pages/StereoKit/Vec3/Min.html>
1479    /// * `a` - Order isn't important here.
1480    /// * `b` - Order isn't important here.
1481    ///
1482    /// Returns the minimum value for each corresponding vector pair.
1483    /// ### Examples
1484    /// ```
1485    /// use stereokit_rust::maths::Vec3;
1486    ///
1487    /// let a = Vec3::new(1.0, 2.0, 3.0);
1488    /// let b = Vec3::new(4.0, 1.0, 6.0);
1489    /// let result = Vec3::min(a, b);
1490    /// assert_eq!(result, Vec3::new(1.0, 1.0, 3.0));
1491    /// ```
1492    #[inline]
1493    pub fn min(a: Self, b: Self) -> Self {
1494        Self { x: f32::min(a.x, b.x), y: f32::min(a.y, b.y), z: f32::min(a.z, b.z) }
1495    }
1496
1497    /// Exactly the same as Vec3.Cross, but has some naming mnemonics for getting the order right when trying to find a
1498    /// perpendicular vector using the cross product. This’ll also make it more obvious to read if that’s what you’re
1499    /// actually going for when crossing vectors!
1500    /// If you consider a forward vector and an up vector, then the direction to the right is pretty trivial to imagine
1501    /// in relation to those vectors!
1502    /// <https://stereokit.net/Pages/StereoKit/Vec3/PerpendicularRight.html>
1503    /// * `forward` - What way are you facing?
1504    /// * `up` - Which direction is up?
1505    ///
1506    /// Returns your direction to the right! Result is -not- a unit vector, even if both ‘forward’ and ‘up’ are unit
1507    /// vectors.
1508    /// ### Examples
1509    /// ```
1510    /// use stereokit_rust::maths::Vec3;
1511    ///
1512    /// let forward = Vec3::new(0.0, 0.0, -1.0);
1513    /// let up = Vec3::new(0.0, 1.0, 0.0);
1514    /// let right = Vec3::perpendicular_right(forward, up);
1515    /// assert_eq!(right, Vec3::new(1.0, 0.0, 0.0));
1516    ///
1517    /// // The same with constants:
1518    /// let forward = Vec3::FORWARD;
1519    /// let up = Vec3::UP;
1520    /// let right = Vec3::perpendicular_right(forward, up);
1521    /// assert_eq!(right, Vec3::RIGHT);
1522    /// ```
1523    #[inline]
1524    pub fn perpendicular_right(forward: Self, up: Self) -> Self {
1525        Self::cross(forward, up)
1526    }
1527
1528    /// Returns a vector where each element is the absolute value of the corresponding element.
1529    /// <https://stereokit.net/Pages/StereoKit/Vec3/Abs.html>
1530    ///
1531    /// ### Examples
1532    /// ```
1533    /// use stereokit_rust::maths::Vec3;
1534    ///
1535    /// let v = Vec3::new(-1.0, 2.0, -3.0);
1536    /// assert_eq!(v.abs(), Vec3::new(1.0, 2.0, 3.0));
1537    /// ```
1538    #[inline]
1539    pub fn abs(&self) -> Self {
1540        Self { x: self.x.abs(), y: self.y.abs(), z: self.z.abs() }
1541    }
1542
1543    /// get an array
1544    ///
1545    /// ### Examples
1546    /// ```
1547    /// use stereokit_rust::maths::Vec3;
1548    ///
1549    /// let v = Vec3::new(1.0, 2.0, 3.0);
1550    /// assert_eq!(v.to_array(), [1.0, 2.0, 3.0]);
1551    ///```
1552    #[inline]
1553    pub const fn to_array(&self) -> [f32; 3] {
1554        [self.x, self.y, self.z]
1555    }
1556}
1557
1558impl Display for Vec3 {
1559    /// Mostly for debug purposes, this is a decent way to log or inspect the vector in debug mode.
1560    /// Looks like “[x, y, z]”
1561    /// <https://stereokit.net/Pages/StereoKit/Vec3/ToString.html>
1562    /// ### Examples
1563    /// ```
1564    /// use stereokit_rust::maths::Vec3;
1565    ///
1566    /// let v = Vec3::new(1.0, 2.0, 3.0);
1567    /// assert_eq!(v.to_string(), "[x:1, y:2, z:3]");
1568    /// ```
1569    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1570        write!(f, "[x:{}, y:{}, z:{}]", self.x, self.y, self.z)
1571    }
1572}
1573/// A component-wise vector division.
1574/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Division.html>
1575impl Div<Vec3> for Vec3 {
1576    type Output = Self;
1577
1578    /// ### Examples
1579    /// ```
1580    /// use stereokit_rust::maths::Vec3;
1581    ///
1582    /// let v = Vec3::new(1.0, 2.0, 3.0) / Vec3::new(2.0, 2.0, 2.0);
1583    /// assert_eq!(v, Vec3::new(0.5, 1.0, 1.5));
1584    /// ```
1585    #[inline]
1586    fn div(self, rhs: Self) -> Self::Output {
1587        Self { x: self.x.div(rhs.x), y: self.y.div(rhs.y), z: self.z.div(rhs.z) }
1588    }
1589}
1590
1591/// A component-wise vector division.
1592/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Division.html>
1593impl DivAssign<Vec3> for Vec3 {
1594    /// ### Examples
1595    /// ```
1596    /// use stereokit_rust::maths::Vec3;
1597    ///
1598    /// let mut v = Vec3::new(1.0, 2.0, 3.0);
1599    /// v /= Vec3::new(2.0, 2.0, 2.0);
1600    /// assert_eq!(v, Vec3::new(0.5, 1.0, 1.5));
1601    /// ```
1602    #[inline]
1603    fn div_assign(&mut self, rhs: Self) {
1604        self.x.div_assign(rhs.x);
1605        self.y.div_assign(rhs.y);
1606        self.z.div_assign(rhs.z);
1607    }
1608}
1609
1610/// A component-wise vector division.
1611/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Division.html>
1612impl Div<f32> for Vec3 {
1613    type Output = Self;
1614
1615    /// ## Examples
1616    /// ```
1617    /// use stereokit_rust::maths::Vec3;
1618    ///
1619    /// let v = Vec3::new(1.0, 2.0, 3.0);
1620    /// let v = v / 2.0;
1621    /// assert_eq!(v, Vec3::new(0.5, 1.0, 1.5));
1622    /// ```
1623    #[inline]
1624    fn div(self, rhs: f32) -> Self::Output {
1625        Self { x: self.x.div(rhs), y: self.y.div(rhs), z: self.z.div(rhs) }
1626    }
1627}
1628
1629/// A component-wise vector division.
1630/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Division.html>
1631impl DivAssign<f32> for Vec3 {
1632    /// ### Examples
1633    /// ```
1634    /// use stereokit_rust::maths::Vec3;
1635    ///
1636    /// let mut v = Vec3::new(1.0, 2.0, 3.0);
1637    /// v /= 2.0;
1638    /// assert_eq!(v, Vec3::new(0.5, 1.0, 1.5));
1639    /// ```
1640    #[inline]
1641    fn div_assign(&mut self, rhs: f32) {
1642        self.x.div_assign(rhs);
1643        self.y.div_assign(rhs);
1644        self.z.div_assign(rhs);
1645    }
1646}
1647
1648/// A component-wise vector division.
1649/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Division.html>
1650impl Div<Vec3> for f32 {
1651    type Output = Vec3;
1652
1653    /// ### Examples
1654    /// ```
1655    /// use stereokit_rust::maths::Vec3;
1656    ///
1657    /// let v = Vec3::new(1.0, 2.0, 3.0);
1658    /// let v = v / Vec3::new(2.0, 2.0, 2.0);
1659    /// assert_eq!(v, Vec3::new(0.5, 1.0, 1.5));
1660    /// ```
1661    #[inline]
1662    fn div(self, rhs: Vec3) -> Self::Output {
1663        Vec3 { x: self.div(rhs.x), y: self.div(rhs.y), z: self.div(rhs.z) }
1664    }
1665}
1666
1667/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
1668/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Multiply.html>
1669impl Mul<Vec3> for Vec3 {
1670    type Output = Self;
1671
1672    /// ### Examples
1673    /// ```
1674    /// use stereokit_rust::maths::Vec3;
1675    ///
1676    /// let a = Vec3::new(1.0, 2.0, 3.0);
1677    /// let b = Vec3::new(4.0, 5.0, 6.0);
1678    /// let c = a * b;
1679    /// assert_eq!(c, Vec3::new(4.0, 10.0, 18.0));
1680    /// ```
1681    #[inline]
1682    fn mul(self, rhs: Self) -> Self::Output {
1683        Self { x: self.x.mul(rhs.x), y: self.y.mul(rhs.y), z: self.z.mul(rhs.z) }
1684    }
1685}
1686
1687/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
1688/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Multiply.html>
1689impl MulAssign<Vec3> for Vec3 {
1690    /// ### Examples
1691    /// ```
1692    /// use stereokit_rust::maths::Vec3;
1693    ///
1694    /// let mut a = Vec3::new(1.0, 2.0, 3.0);
1695    /// let b = Vec3::new(4.0, 5.0, 6.0);
1696    /// a *= b;
1697    /// assert_eq!(a, Vec3::new(4.0, 10.0, 18.0));
1698    /// ```
1699    #[inline]
1700    fn mul_assign(&mut self, rhs: Self) {
1701        self.x.mul_assign(rhs.x);
1702        self.y.mul_assign(rhs.y);
1703        self.z.mul_assign(rhs.z);
1704    }
1705}
1706
1707/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
1708/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Multiply.html>
1709impl Mul<f32> for Vec3 {
1710    type Output = Self;
1711
1712    /// ### Examples
1713    /// ```
1714    /// use stereokit_rust::maths::Vec3;
1715    ///
1716    /// let a = Vec3::new(1.0, 2.0, 3.0);
1717    /// let b = a * 2.0;
1718    /// assert_eq!(b, Vec3::new(2.0, 4.0, 6.0));
1719    /// ```
1720    #[inline]
1721    fn mul(self, rhs: f32) -> Self::Output {
1722        Self { x: self.x.mul(rhs), y: self.y.mul(rhs), z: self.z.mul(rhs) }
1723    }
1724}
1725
1726/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
1727/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Multiply.html>
1728impl MulAssign<f32> for Vec3 {
1729    /// ### Examples
1730    /// ```
1731    /// use stereokit_rust::maths::Vec3;
1732    ///
1733    /// let mut a = Vec3::new(1.0, 2.0, 3.0);
1734    /// a *= 2.0;
1735    /// assert_eq!(a, Vec3::new(2.0, 4.0, 6.0));
1736    /// ```
1737    #[inline]
1738    fn mul_assign(&mut self, rhs: f32) {
1739        self.x.mul_assign(rhs);
1740        self.y.mul_assign(rhs);
1741        self.z.mul_assign(rhs);
1742    }
1743}
1744
1745/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
1746/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Multiply.html>
1747impl Mul<Vec3> for f32 {
1748    type Output = Vec3;
1749
1750    /// ### Examples
1751    /// ```
1752    /// use stereokit_rust::maths::Vec3;
1753    ///
1754    /// let a = 2.0 * Vec3::new(1.0, 2.0, 3.0);
1755    /// let b = Vec3::new(2.0, 4.0, 6.0);
1756    /// assert_eq!(a, b);
1757    /// ```
1758    #[inline]
1759    fn mul(self, rhs: Vec3) -> Self::Output {
1760        Vec3 { x: self.mul(rhs.x), y: self.mul(rhs.y), z: self.mul(rhs.z) }
1761    }
1762}
1763
1764/// Adds matching components together. Commutative.
1765/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Addition.html>
1766impl Add<Vec3> for Vec3 {
1767    type Output = Self;
1768
1769    /// ### Examples
1770    /// ```
1771    /// use stereokit_rust::maths::Vec3;
1772    ///
1773    /// let a = Vec3::new(1.0, 2.0, 3.0);
1774    /// let b = Vec3::new(4.0, 5.0, 6.0);
1775    /// let c = a + b;
1776    /// assert_eq!(c, Vec3::new(5.0, 7.0, 9.0));
1777    /// ```
1778    #[inline]
1779    fn add(self, rhs: Self) -> Self::Output {
1780        Self { x: self.x.add(rhs.x), y: self.y.add(rhs.y), z: self.z.add(rhs.z) }
1781    }
1782}
1783
1784/// Adds matching components together. Commutative.
1785/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Addition.html>
1786impl AddAssign<Vec3> for Vec3 {
1787    /// ### Examples
1788    /// ```
1789    /// use stereokit_rust::maths::Vec3;
1790    ///
1791    /// let mut a = Vec3::new(1.0, 2.0, 3.0);
1792    /// let b = Vec3::new(4.0, 5.0, 6.0);
1793    /// a += b;
1794    /// assert_eq!(a, Vec3::new(5.0, 7.0, 9.0));
1795    /// ```
1796    #[inline]
1797    fn add_assign(&mut self, rhs: Self) {
1798        self.x.add_assign(rhs.x);
1799        self.y.add_assign(rhs.y);
1800        self.z.add_assign(rhs.z);
1801    }
1802}
1803
1804impl Sub<Vec3> for Vec3 {
1805    type Output = Self;
1806
1807    /// ## Examples
1808    /// ```
1809    /// use stereokit_rust::maths::Vec3;
1810    ///
1811    /// let a = Vec3::new(1.0, 2.0, 3.0);
1812    /// let b = Vec3::new(4.0, 5.0, 6.0);
1813    /// let c = a - b;
1814    /// assert_eq!(c, Vec3::new(-3.0, -3.0, -3.0));
1815    /// ```
1816    #[inline]
1817    fn sub(self, rhs: Self) -> Self::Output {
1818        Self { x: self.x.sub(rhs.x), y: self.y.sub(rhs.y), z: self.z.sub(rhs.z) }
1819    }
1820}
1821
1822/// Subtracts matching components from eachother. Not commutative.
1823/// <https://stereokit.net/Pages/StereoKit/Vec3/op_Subtraction.html>
1824impl SubAssign<Vec3> for Vec3 {
1825    /// ### Examples
1826    /// ```
1827    /// use stereokit_rust::maths::Vec3;
1828    ///
1829    /// let mut a = Vec3::new(1.0, 3.0, 1.0);
1830    /// let b = Vec3::new(0.5, 0.5, 0.5);
1831    /// a -= b;
1832    /// assert_eq!(a, Vec3::new(0.5, 2.5, 0.5));
1833    /// ```
1834    #[inline]
1835    fn sub_assign(&mut self, rhs: Vec3) {
1836        self.x.sub_assign(rhs.x);
1837        self.y.sub_assign(rhs.y);
1838        self.z.sub_assign(rhs.z);
1839    }
1840}
1841
1842/// Vector negation, returns a vector where each component has been negated.
1843/// <https://stereokit.net/Pages/StereoKit/Vec3/op_UnaryNegation.html>
1844impl Neg for Vec3 {
1845    type Output = Self;
1846
1847    /// ### Examples
1848    /// ```
1849    /// use stereokit_rust::maths::Vec3;
1850    ///
1851    /// let a = Vec3::new(1.0, 2.0, 3.0);
1852    /// let b = -a;
1853    /// assert_eq!(b, Vec3::new(-1.0, -2.0, -3.0));
1854    /// ```
1855    #[inline]
1856    fn neg(self) -> Self::Output {
1857        self * -1.0
1858    }
1859}
1860
1861/// A vector with 4 components: x, y, z, and w. Can be useful for things like shaders, where the registers are aligned
1862/// to 4 float vectors.
1863///
1864/// This is a wrapper on System.Numerics.Vector4, so it’s SIMD optimized, and can be cast to and from implicitly.
1865/// <https://stereokit.net/Pages/StereoKit/Vec4.html>
1866///
1867/// see also [`glam::Vec4`]
1868/// ### Examples
1869/// ```
1870/// use stereokit_rust::maths::Vec4;
1871///
1872/// let vec4        = Vec4::new(1.0, 2.0, 3.0, 4.0);
1873/// let vec4a       = Vec4 { x: 1.0, y: 2.0, z:3.0, w:4.0 };
1874/// let vec4b       = Vec4::X + Vec4::Y * 2.0;
1875/// let vec4c: Vec4 = [1.0, 2.0, 3.0, 4.0].into();
1876///
1877/// assert_eq!(vec4, vec4a);
1878/// assert_eq!(vec4a + vec4b,                   Vec4 { x: 2.0, y: 4.0, z: 3.0, w: 4.0 });
1879/// assert_eq!(vec4c,                           Vec4 { x: 1.0, y: 2.0, z: 3.0, w: 4.0 });
1880/// assert_eq!(vec4a.length_sq(),               30.0);
1881/// assert_eq!(Vec4::dot(Vec4::X, Vec4::Y),     0.0);
1882/// ```
1883#[derive(Debug, Default, Copy, Clone)]
1884#[repr(C)]
1885pub struct Vec4 {
1886    pub x: f32,
1887    pub y: f32,
1888    pub z: f32,
1889    pub w: f32,
1890}
1891impl From<glam::Vec4> for Vec4 {
1892    fn from(value: glam::Vec4) -> Self {
1893        Self { x: value.x, y: value.y, z: value.z, w: value.w }
1894    }
1895}
1896impl From<[f32; 4]> for Vec4 {
1897    fn from(val: [f32; 4]) -> Self {
1898        Vec4 { x: val[0], y: val[1], z: val[2], w: val[3] }
1899    }
1900}
1901
1902impl From<Vec4> for glam::Vec4 {
1903    fn from(value: Vec4) -> Self {
1904        Self::new(value.x, value.y, value.z, value.w)
1905    }
1906}
1907
1908///  Warning: Equality with a precision of 0.1 millimeter
1909impl PartialEq for Vec4 {
1910    ///  Warning: Equality with a precision of 0.1 millimeter
1911    fn eq(&self, other: &Self) -> bool {
1912        ((self.x - other.x).abs() < 0.0001)
1913            && ((self.y - other.y).abs() < 0.0001)
1914            && ((self.z - other.z).abs() < 0.0001)
1915            && ((self.w - other.w).abs() < 0.0001)
1916    }
1917}
1918
1919impl Vec4 {
1920    /// all components to 0
1921    pub const ZERO: Vec4 = Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
1922
1923    /// all components to 1
1924    pub const ONE: Vec4 = Vec4 { x: 1.0, y: 1.0, z: 1.0, w: 1.0 };
1925
1926    /// A normalized Vector that points down the X axis, this is the same as new Vec4(1,0,0,0).
1927    /// <https://stereokit.net/Pages/StereoKit/Vec4/UnitX.html>    
1928    pub const X: Vec4 = Vec4 { x: 1.0, y: 0.0, z: 0.0, w: 0.0 };
1929
1930    /// A normalized Vector that points down the Y axis, this is the same as new Vec4(0,1,0,0).
1931    /// <https://stereokit.net/Pages/StereoKit/Vec4/UnitY.html>    
1932    pub const Y: Vec4 = Vec4 { x: 0.0, y: 1.0, z: 0.0, w: 0.0 };
1933
1934    /// A normalized Vector that points down the Z axis, this is the same as new Vec4(0,0,1,0).
1935    /// <https://stereokit.net/Pages/StereoKit/Vec4/UnitZ.html>    
1936    pub const Z: Vec4 = Vec4 { x: 0.0, y: 0.0, z: 1.0, w: 0.0 };
1937
1938    /// A normalized Vector that points down the W axis, this is the same as new Vec4(0,0,0,1).
1939    /// <https://stereokit.net/Pages/StereoKit/Vec4/UnitW.html>
1940    pub const W: Vec4 = Vec4 { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };
1941
1942    /// A normalized Vector that points up the X axis, this is the same as new Vec4(1,0,0,0).
1943    pub const NEG_X: Vec4 = Vec4 { x: -1.0, y: 0.0, z: 0.0, w: 0.0 };
1944
1945    /// A normalized Vector that points up the Y axis, this is the same as new Vec4(0,1,0,0).
1946    pub const NEG_Y: Vec4 = Vec4 { x: 0.0, y: -1.0, z: 0.0, w: 0.0 };
1947
1948    /// A normalized Vector that points up the Z axis, this is the same as new Vec4(0,0,1,0).
1949    pub const NEG_Z: Vec4 = Vec4 { x: 0.0, y: 0.0, z: -1.0, w: 0.0 };
1950
1951    /// A normalized Vector that points up the W axis, this is the same as new Vec4(0,0,0,1).
1952    pub const NEG_W: Vec4 = Vec4 { x: 0.0, y: 0.0, z: 0.0, w: -1.0 };
1953
1954    /// <https://stereokit.net/Pages/StereoKit/Vec4/Vec4.html>
1955    #[inline]
1956    pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
1957        Self { x, y, z, w }
1958    }
1959
1960    /// This extracts the Vec2 from the X and Y axes.
1961    /// <https://stereokit.net/Pages/StereoKit/Vec4/XY.html>
1962    ///
1963    /// ### Examples
1964    /// ```
1965    /// use stereokit_rust::maths::{Vec2, Vec4};
1966    ///
1967    /// let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
1968    /// let xy = v.xy();
1969    /// assert_eq!(xy, Vec2::new(1.0, 2.0));
1970    /// ```
1971    #[inline]
1972    pub fn xy(&self) -> Vec2 {
1973        Vec2::new(self.x, self.y)
1974    }
1975
1976    /// This extracts the Vec2 from the Y and Z axes.
1977    /// <https://stereokit.net/Pages/StereoKit/Vec4/YZ.html>
1978    ///
1979    /// ### Examples
1980    /// ```
1981    /// use stereokit_rust::maths::{Vec2, Vec4};
1982    ///
1983    /// let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
1984    /// let yz = v.yz();
1985    /// assert_eq!(yz, Vec2::new(2.0, 3.0));
1986    /// ```
1987    #[inline]
1988    pub fn yz(&self) -> Vec2 {
1989        Vec2::new(self.y, self.z)
1990    }
1991
1992    /// This extracts the Vec2 from the X and Z axes.
1993    /// <https://stereokit.net/Pages/StereoKit/Vec4/XZ.html>
1994    ///
1995    /// ### Examples
1996    /// ```
1997    /// use stereokit_rust::maths::{Vec2, Vec4};
1998    ///
1999    /// let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
2000    /// let xz = v.xz();
2001    /// assert_eq!(xz, Vec2::new(1.0, 3.0));
2002    /// ```
2003    #[inline]
2004    pub fn xz(&self) -> Vec2 {
2005        Vec2::new(self.x, self.z)
2006    }
2007
2008    /// This extracts the Vec2 from the Z and W axes.
2009    /// <https://stereokit.net/Pages/StereoKit/Vec4/ZW.html>
2010    ///
2011    /// ### Examples
2012    /// ```
2013    /// use stereokit_rust::maths::{Vec2, Vec4};
2014    ///
2015    /// let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
2016    /// let zw = v.zw();
2017    /// assert_eq!(zw, Vec2::new(3.0, 4.0));
2018    /// ```
2019    #[inline]
2020    pub fn zw(&self) -> Vec2 {
2021        Vec2::new(self.z, self.w)
2022    }
2023
2024    /// This extracts a Vec3 from the X, Y, and Z axes.
2025    /// <https://stereokit.net/Pages/StereoKit/Vec4/XYZ.html>
2026    ///
2027    /// ### Examples
2028    /// ```
2029    /// use stereokit_rust::maths::{Vec3, Vec4};
2030    ///
2031    /// let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
2032    /// let v3 = v.xyz();
2033    /// assert_eq!(v3, Vec3::new(1.0, 2.0, 3.0));
2034    /// ```
2035    #[inline]
2036    pub fn xyz(&self) -> Vec3 {
2037        Vec3::new(self.x, self.y, self.z)
2038    }
2039
2040    /// A Vec4 and a Quat are only really different by name and purpose. So, if you need to do Quat math with your
2041    /// Vec4, or visa versa, who am I to judge?
2042    /// <https://stereokit.net/Pages/StereoKit/Vec4/Quat.html>
2043    ///
2044    /// ### Examples
2045    /// ```
2046    /// use stereokit_rust::maths::{Vec4, Quat};
2047    ///
2048    /// let vec4 = Vec4::new(1.0, 2.0, 3.0, 4.0);
2049    /// let quat = vec4.get_as_quat();
2050    /// assert_eq!(quat, Quat::new(1.0, 2.0, 3.0, 4.0));
2051    /// ```
2052    #[inline]
2053    pub fn get_as_quat(&self) -> Quat {
2054        Quat { x: self.x, y: self.y, z: self.z, w: self.w }
2055    }
2056
2057    /// This is the squared length/magnitude of the vector! It skips the Sqrt call, and just gives you the squared
2058    /// version for speedy calculations that can work with it squared.
2059    /// <https://stereokit.net/Pages/StereoKit/Vec4.html>
2060    ///
2061    /// ### Examples
2062    /// ```
2063    /// use stereokit_rust::maths::Vec4;
2064    ///
2065    /// let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
2066    /// assert_eq!(v.length_sq(), 30.0);
2067    /// ```
2068    #[inline]
2069    pub fn length_sq(&self) -> f32 {
2070        Self::dot(*self, *self)
2071    }
2072
2073    /// What’s a dot product do for 4D vectors, you might ask? Well, I’m no mathematician, so hopefully you are! I’ve
2074    /// never used it before. Whatever you’re doing with this function, it’s SIMD fast!
2075    /// <https://stereokit.net/Pages/StereoKit/Vec4/Dot.html>
2076    /// * `a` - The first vector.
2077    /// * `b` - The second vector.
2078    ///
2079    /// Returns the dot product of the two vectors.
2080    /// ### Examples
2081    /// ```
2082    /// use stereokit_rust::maths::Vec4;
2083    ///
2084    /// let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
2085    /// let b = Vec4::new(5.0, 6.0, 7.0, 8.0);
2086    /// let result = Vec4::dot(a, b);
2087    /// assert_eq!(result, 70.0);
2088    /// ```
2089    #[inline]
2090    pub fn dot(a: Self, b: Self) -> f32 {
2091        (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w)
2092    }
2093
2094    /// Blends (Linear Interpolation) between two vectors, based on a ‘blend’ value, where 0 is a, and 1 is b. Doesn’t
2095    /// clamp percent for you.
2096    /// <https://stereokit.net/Pages/StereoKit/Vec4/Lerp.html>
2097    /// * `a` - First item in the blend, or '0.0 blend.
2098    /// * `b` - Second item in the blend, or '1.0 blend.
2099    /// * `blend` - A blend value between 0 and 1. Can be outside this range, it’ll just interpolate outside of the a, b
2100    ///   range.
2101    ///
2102    /// Returns an unclamped blend of a and b.
2103    /// ### Examples
2104    /// ```
2105    /// use stereokit_rust::maths::Vec4;
2106    /// let a = Vec4::new(0.0, 0.0, 0.0, 0.0);
2107    /// let b = Vec4::new(1.0, 1.0, 1.0, 1.0);
2108    /// let result = Vec4::lerp(a, b, 0.75);
2109    /// assert_eq!(result, Vec4::new(0.75, 0.75, 0.75, 0.75));
2110    /// ```
2111    #[inline]
2112    pub fn lerp(a: Self, b: Self, blend: f32) -> Self {
2113        a + ((b - a) * blend)
2114    }
2115
2116    /// Returns a vector where each element is the maximum value for each corresponding pair.
2117    /// <https://stereokit.net/Pages/StereoKit/Vec4/Max.html>
2118    /// * `a` - Order isn't important here.
2119    /// * `b` - Order isn't important here.
2120    ///
2121    /// Returns a vector where each element is the maximum value for each corresponding pair.
2122    /// #### Examples
2123    /// ```
2124    /// use stereokit_rust::maths::Vec4;
2125    ///
2126    /// let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
2127    /// let b = Vec4::new(4.0, 3.0, 2.0, 1.0);
2128    /// let c = Vec4::max(a, b);
2129    /// assert_eq!(c, Vec4::new(4.0, 3.0, 3.0, 4.0));
2130    /// ```
2131    #[inline]
2132    pub fn max(a: Self, b: Self) -> Self {
2133        Self { x: f32::max(a.x, b.x), y: f32::max(a.y, b.y), z: f32::max(a.z, b.z), w: f32::max(a.w, b.w) }
2134    }
2135
2136    /// Returns a vector where each element is the minimum value for each corresponding pair.
2137    /// <https://stereokit.net/Pages/StereoKit/Vec4/Min.html>
2138    /// * `a` - Order isn't important here.
2139    /// * `b` - Order isn't important here.
2140    ///
2141    /// Returns a new vector with the minimum values.
2142    /// ### Examples
2143    /// ```
2144    /// use stereokit_rust::maths::Vec4;
2145    ///
2146    /// let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
2147    /// let b = Vec4::new(4.0, 3.0, 2.0, 1.0);
2148    /// let c = Vec4::min(a, b);
2149    /// assert_eq!(c, Vec4::new(1.0, 2.0, 2.0, 1.0));
2150    /// ```
2151    #[inline]
2152    pub fn min(a: Self, b: Self) -> Self {
2153        Self { x: f32::min(a.x, b.x), y: f32::min(a.y, b.y), z: f32::min(a.z, b.z), w: f32::min(a.w, b.w) }
2154    }
2155}
2156
2157impl Display for Vec4 {
2158    /// Mostly for debug purposes, this is a decent way to log or inspect the vector in debug mode. Looks
2159    /// like “[x, y, z, w]”
2160    /// <https://stereokit.net/Pages/StereoKit/Vec4/ToString.html>
2161    ///
2162    /// ### Examples
2163    /// ```
2164    /// use stereokit_rust::maths::Vec4;
2165    ///
2166    /// let v = Vec4::new(1.0, 2.2, 3.0, 4.0);
2167    /// assert_eq!(format!("{}", v), "[x:1, y:2.2, z:3, w:4]");
2168    /// ```
2169    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2170        write!(f, "[x:{}, y:{}, z:{}, w:{}]", self.x, self.y, self.z, self.w)
2171    }
2172}
2173/// A component-wise vector division.
2174/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Division.html>
2175impl Div<Vec4> for Vec4 {
2176    type Output = Self;
2177
2178    /// ### Examples
2179    /// ```
2180    /// use stereokit_rust::maths::Vec4;
2181    ///
2182    /// let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
2183    /// let b = Vec4::new(2.0, 2.0, 2.0, 2.0);
2184    /// let c = a / b;
2185    /// assert_eq!(c, Vec4::new(0.5, 1.0, 1.5, 2.0));
2186    /// ```
2187    #[inline]
2188    fn div(self, rhs: Self) -> Self::Output {
2189        Self { x: self.x.div(rhs.x), y: self.y.div(rhs.y), z: self.z.div(rhs.z), w: self.w.div(rhs.w) }
2190    }
2191}
2192
2193/// A component-wise vector division.
2194/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Division.html>
2195impl DivAssign<Vec4> for Vec4 {
2196    /// ### Examples
2197    /// ```
2198    /// use stereokit_rust::maths::*;
2199    ///
2200    /// let mut a = Vec4::new(1.0, 2.0, 3.0, 4.0);
2201    /// let b = Vec4::new(2.0, 2.0, 2.0, 2.0);
2202    /// a /= b;
2203    /// assert_eq!(a, Vec4::new(0.5, 1.0, 1.5, 2.0));
2204    /// ```
2205    #[inline]
2206    fn div_assign(&mut self, rhs: Self) {
2207        self.x.div_assign(rhs.x);
2208        self.y.div_assign(rhs.y);
2209        self.z.div_assign(rhs.z);
2210        self.w.div_assign(rhs.w);
2211    }
2212}
2213
2214/// A component-wise vector division.
2215/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Division.html>
2216impl Div<f32> for Vec4 {
2217    type Output = Self;
2218
2219    /// ### Examples
2220    /// ```
2221    /// use stereokit_rust::maths::Vec4;
2222    ///
2223    /// let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
2224    /// let b = a / 2.0;
2225    /// assert_eq!(b, Vec4::new(0.5, 1.0, 1.5, 2.0));
2226    /// ```
2227    #[inline]
2228    fn div(self, rhs: f32) -> Self::Output {
2229        Self { x: self.x.div(rhs), y: self.y.div(rhs), z: self.z.div(rhs), w: self.w.div(rhs) }
2230    }
2231}
2232
2233/// A component-wise vector division.
2234/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Division.html>
2235impl DivAssign<f32> for Vec4 {
2236    /// ### Examples
2237    /// ```
2238    /// use stereokit_rust::maths::Vec4;
2239    ///
2240    /// let mut v = Vec4::new(1.0, 2.0, 3.0, 4.0);
2241    /// v /= 2.0;
2242    /// assert_eq!(v, Vec4::new(0.5, 1.0, 1.5, 2.0));
2243    /// ```
2244    #[inline]
2245    fn div_assign(&mut self, rhs: f32) {
2246        self.x.div_assign(rhs);
2247        self.y.div_assign(rhs);
2248        self.z.div_assign(rhs);
2249        self.w.div_assign(rhs);
2250    }
2251}
2252
2253/// A component-wise vector division.
2254/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Division.html>
2255impl Div<Vec4> for f32 {
2256    type Output = Vec4;
2257
2258    /// ### Examples
2259    /// ```
2260    /// use stereokit_rust::maths::Vec4;
2261    ///
2262    /// let a = Vec4::new(1.0, 7.0, 3.0, 4.0);
2263    /// let b = a / 2.0;
2264    /// assert_eq!(b, Vec4::new(0.5, 3.5, 1.5, 2.0));
2265    /// ```
2266    #[inline]
2267    fn div(self, rhs: Vec4) -> Self::Output {
2268        Vec4 { x: self.div(rhs.x), y: self.div(rhs.y), z: self.div(rhs.z), w: self.div(rhs.w) }
2269    }
2270}
2271
2272/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
2273/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Multiply.html>
2274impl Mul<Vec4> for Vec4 {
2275    type Output = Self;
2276
2277    /// ### Examples
2278    /// ```
2279    /// use stereokit_rust::maths::Vec4;
2280    ///
2281    /// let a = Vec4::new(1.0, 2.0, 3.0, 5.0);
2282    /// let b = Vec4::new(2.0, 3.0, 4.0, 6.0);
2283    /// let c = a * b;
2284    /// assert_eq!(c, Vec4::new(2.0, 6.0, 12.0, 30.0));
2285    /// ```
2286    #[inline]
2287    fn mul(self, rhs: Self) -> Self::Output {
2288        Self { x: self.x.mul(rhs.x), y: self.y.mul(rhs.y), z: self.z.mul(rhs.z), w: self.w.mul(rhs.w) }
2289    }
2290}
2291
2292/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
2293/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Multiply.html>
2294impl MulAssign<Vec4> for Vec4 {
2295    /// ### Examples
2296    /// ```
2297    /// use stereokit_rust::maths::Vec4;
2298    ///
2299    /// let mut a = Vec4::new(1.0, 2.0, 3.0, 5.0);
2300    /// let b = Vec4::new(2.0, 3.0, 4.0, 6.0);
2301    /// a *= b;
2302    /// assert_eq!(a, Vec4::new(2.0, 6.0, 12.0, 30.0));
2303    /// ```
2304    #[inline]
2305    fn mul_assign(&mut self, rhs: Self) {
2306        self.x.mul_assign(rhs.x);
2307        self.y.mul_assign(rhs.y);
2308        self.z.mul_assign(rhs.z);
2309        self.w.mul_assign(rhs.w)
2310    }
2311}
2312
2313/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
2314/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Multiply.html>
2315impl Mul<f32> for Vec4 {
2316    type Output = Self;
2317
2318    /// ### Examples
2319    /// ```
2320    /// use stereokit_rust::maths::Vec4;
2321    ///
2322    /// let a = Vec4::new(1.0, 2.0, 3.0, 5.0);
2323    /// let b = a * 2.0;
2324    /// assert_eq!(b, Vec4::new(2.0, 4.0, 6.0, 10.0));
2325    /// ```
2326    #[inline]
2327    fn mul(self, rhs: f32) -> Self::Output {
2328        Self { x: self.x.mul(rhs), y: self.y.mul(rhs), z: self.z.mul(rhs), w: self.w.mul(rhs) }
2329    }
2330}
2331
2332/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
2333/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Multiply.html>
2334impl MulAssign<f32> for Vec4 {
2335    /// ### Examples
2336    /// ```
2337    /// use stereokit_rust::maths::Vec4;
2338    ///
2339    /// let mut a = Vec4::new(1.0, 2.0, 7.0, 5.0);
2340    /// a *= 2.0;
2341    /// assert_eq!(a, Vec4::new(2.0, 4.0, 14.0, 10.0));
2342    /// ```
2343    #[inline]
2344    fn mul_assign(&mut self, rhs: f32) {
2345        self.x.mul_assign(rhs);
2346        self.y.mul_assign(rhs);
2347        self.z.mul_assign(rhs);
2348        self.w.mul_assign(rhs);
2349    }
2350}
2351
2352/// A component-wise vector multiplication, same thing as a non-uniform scale. NOT a dot or cross product! Commutative.
2353/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Multiply.html>
2354impl Mul<Vec4> for f32 {
2355    type Output = Vec4;
2356
2357    /// ### Examples
2358    /// ```
2359    /// use stereokit_rust::maths::Vec4;
2360    ///
2361    /// let a = 2.0;
2362    /// let b = Vec4::new(2.0, 3.0, 4.0, 6.0);
2363    /// let c = a * b;
2364    /// assert_eq!(c, Vec4::new(4.0, 6.0, 8.0, 12.0));
2365    /// ```
2366    #[inline]
2367    fn mul(self, rhs: Vec4) -> Self::Output {
2368        Vec4 { x: self.mul(rhs.x), y: self.mul(rhs.y), z: self.mul(rhs.z), w: self.mul(rhs.w) }
2369    }
2370}
2371
2372/// Adds matching components together. Commutative.
2373/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Addition.html>
2374impl Add<Vec4> for Vec4 {
2375    type Output = Self;
2376
2377    /// ### Examples
2378    /// ```
2379    /// use stereokit_rust::maths::Vec4;
2380    ///
2381    /// let a = Vec4::new(1.0, 2.0, 3.0, 5.0);
2382    /// let b = Vec4::new(2.0, 3.0, 4.0, 6.0);
2383    /// let c = a + b;
2384    /// assert_eq!(c, Vec4::new(3.0, 5.0, 7.0, 11.0));
2385    /// ```
2386    #[inline]
2387    fn add(self, rhs: Self) -> Self::Output {
2388        Self { x: self.x.add(rhs.x), y: self.y.add(rhs.y), z: self.z.add(rhs.z), w: self.w.add(rhs.w) }
2389    }
2390}
2391
2392/// Adds matching components together. Commutative.
2393/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Addition.html>
2394impl AddAssign<Vec4> for Vec4 {
2395    /// ### Examples
2396    /// ```
2397    /// use stereokit_rust::maths::Vec4;
2398    ///
2399    /// let mut v1 = Vec4::new(1.0, 2.0, 3.0, 4.0);
2400    /// let v2 = Vec4::new(5.0, 6.0, 7.0, 8.0);
2401    /// v1 += v2;
2402    /// assert_eq!(v1, Vec4::new(6.0, 8.0, 10.0, 12.0));
2403    /// ```
2404    #[inline]
2405    fn add_assign(&mut self, rhs: Self) {
2406        self.x.add_assign(rhs.x);
2407        self.y.add_assign(rhs.y);
2408        self.z.add_assign(rhs.z);
2409        self.w.add_assign(rhs.w);
2410    }
2411}
2412
2413impl Sub<Vec4> for Vec4 {
2414    type Output = Self;
2415
2416    /// ### Examples
2417    /// ```
2418    /// use stereokit_rust::maths::Vec4;
2419    ///
2420    /// let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
2421    /// let b = Vec4::new(4.0, 3.0, 2.0, 1.0);
2422    /// let c = a - b;
2423    /// assert_eq!(c, Vec4::new(-3.0, -1.0, 1.0, 3.0));
2424    /// ```
2425    #[inline]
2426    fn sub(self, rhs: Self) -> Self::Output {
2427        Self { x: self.x.sub(rhs.x), y: self.y.sub(rhs.y), z: self.z.sub(rhs.z), w: self.w.sub(rhs.w) }
2428    }
2429}
2430
2431/// Subtracts matching components from eachother. Not commutative.
2432/// <https://stereokit.net/Pages/StereoKit/Vec4/op_Subtraction.html>
2433impl SubAssign<Vec4> for Vec4 {
2434    /// ### Examples
2435    /// ```
2436    /// use stereokit_rust::maths::Vec4;
2437    ///
2438    /// let mut v1 = Vec4::new(1.0, 2.0, 3.0, 4.0);
2439    /// let v2 = Vec4::new(1.0, 2.0, 3.0, 4.0);
2440    /// v1 -= v2;
2441    /// assert_eq!(v1, Vec4::new(0.0, 0.0, 0.0, 0.0));
2442    /// ```
2443    #[inline]
2444    fn sub_assign(&mut self, rhs: Vec4) {
2445        self.x.sub_assign(rhs.x);
2446        self.y.sub_assign(rhs.y);
2447        self.z.sub_assign(rhs.z);
2448        self.w.sub_assign(rhs.w);
2449    }
2450}
2451
2452/// Vector negation, returns a vector where each component has been negated.
2453/// <https://stereokit.net/Pages/StereoKit/Vec4/op_UnaryNegation.html>
2454impl Neg for Vec4 {
2455    type Output = Self;
2456
2457    /// ### Examples
2458    /// ```
2459    /// use stereokit_rust::maths::Vec4;
2460    ///
2461    /// let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
2462    /// let neg_v = -v;
2463    /// assert_eq!(neg_v, Vec4::new(-1.0, -2.0, -3.0, -4.0));
2464    /// ```
2465    #[inline]
2466    fn neg(self) -> Self::Output {
2467        self * -1.0
2468    }
2469}
2470
2471/// Quaternions are efficient and robust mathematical objects for representing rotations! Understanding the details of
2472/// how a quaternion works is not generally necessary for using them effectively, so don’t worry too much if they seem
2473/// weird to you. They’re weird to me too.
2474///
2475/// If you’re interested in learning the details though, 3Blue1Brown and Ben Eater have an excellent interactive lesson
2476/// about them!
2477/// <https://stereokit.net/Pages/StereoKit/Quat.html>
2478///
2479///  see also [`glam::Quat`]
2480/// ### Examples
2481/// ```
2482/// use stereokit_rust::maths::{Quat, Vec3, Vec4};
2483///
2484/// let mut quat1 = Quat::new(0.0, 0.0, 0.0, 1.0);
2485/// let mut quat2 = Quat::from_angles(0.0, 90.0, 0.0);
2486/// let mut quat2b :Quat= [0.0, 90.0, 0.0].into();
2487/// let mut quat3 = Quat::look_at(Vec3::X, Vec3::ZERO, None);
2488/// let vec4_w: Vec4 = (quat2 - quat3).into();
2489///
2490/// // quat2 == quat3 but because of epsilon here is the demo:
2491/// assert_eq!(vec4_w.w,            1.0);
2492/// assert_eq!(vec4_w.length_sq(),  1.0);
2493/// assert_eq!(quat2b,              quat2);
2494///
2495/// assert_eq!(quat1,               Quat::IDENTITY);
2496/// assert_eq!(*quat1.normalize(),  Quat::IDENTITY);
2497/// assert_eq!(*quat1.invert(),     Quat::IDENTITY);
2498///
2499/// ```
2500#[repr(C)]
2501#[derive(Debug, Copy, Clone)]
2502pub struct Quat {
2503    pub x: f32,
2504    pub y: f32,
2505    pub z: f32,
2506    pub w: f32,
2507}
2508impl From<glam::Quat> for Quat {
2509    fn from(val: glam::Quat) -> Self {
2510        Quat { x: val.x, y: val.y, z: val.z, w: val.w }
2511    }
2512}
2513impl From<Quat> for glam::Quat {
2514    fn from(val: Quat) -> Self {
2515        Self::from_xyzw(val.x, val.y, val.z, val.w)
2516    }
2517}
2518impl From<glam::Vec4> for Quat {
2519    fn from(val: glam::Vec4) -> Self {
2520        Quat { x: val.x, y: val.y, z: val.z, w: val.w }
2521    }
2522}
2523impl From<Quat> for glam::Vec4 {
2524    fn from(val: Quat) -> Self {
2525        Self::new(val.x, val.y, val.z, val.w)
2526    }
2527}
2528impl From<[f32; 3]> for Quat {
2529    fn from(val: [f32; 3]) -> Self {
2530        Quat::from_angles(val[0], val[1], val[2])
2531    }
2532}
2533impl From<Vec4> for Quat {
2534    fn from(val: Vec4) -> Self {
2535        Quat { x: val.x, y: val.y, z: val.z, w: val.w }
2536    }
2537}
2538impl From<Quat> for Vec4 {
2539    fn from(val: Quat) -> Self {
2540        Self { x: val.x, y: val.y, z: val.z, w: val.w }
2541    }
2542}
2543
2544impl Default for Quat {
2545    // Identity quaternion (no rotation)
2546    fn default() -> Self {
2547        Quat::IDENTITY
2548    }
2549}
2550
2551///  Warning: Equality with a precision of 0.000001
2552impl PartialEq for Quat {
2553    ///  Warning: Equality with a precision of 0.00001
2554    /// ### Example
2555    /// ```
2556    /// use stereokit_rust::maths::Quat;
2557    ///
2558    /// let q0 = Quat::new(1.00002, 2.0, 3.0, 4.0);
2559    /// let q1 = Quat::new(1.000001, 2.000001, 3.000001, 4.0);
2560    /// let q2 = Quat::new(1.0, 2.0, 3.0, 4.0);
2561    /// assert_ne!(q0, q1);
2562    /// assert_eq!(q1, q2);
2563    /// ```
2564    fn eq(&self, other: &Self) -> bool {
2565        ((self.x - other.x).abs() < 0.00001)
2566            && ((self.y - other.y).abs() < 0.00001)
2567            && ((self.z - other.z).abs() < 0.00001)
2568            && ((self.w - other.w).abs() < 0.00001)
2569    }
2570}
2571
2572unsafe extern "C" {
2573    pub fn quat_difference(a: *const Quat, b: *const Quat) -> Quat;
2574    pub fn quat_lookat(from: *const Vec3, at: *const Vec3) -> Quat;
2575    pub fn quat_lookat_up(from: *const Vec3, at: *const Vec3, up: *const Vec3) -> Quat;
2576    pub fn quat_from_angles(pitch_x_deg: f32, yaw_y_deg: f32, roll_z_deg: f32) -> Quat;
2577    pub fn quat_slerp(a: *const Quat, b: *const Quat, t: f32) -> Quat;
2578    pub fn quat_normalize(a: *const Quat) -> Quat;
2579    pub fn quat_inverse(a: *const Quat) -> Quat;
2580    pub fn quat_mul(a: *const Quat, b: *const Quat) -> Quat;
2581    pub fn quat_mul_vec(a: *const Quat, b: *const Vec3) -> Vec3;
2582    pub fn quat_to_axis_angle(a: Quat, out_axis: *mut Vec3, out_rotation_deg: *mut f32);
2583}
2584
2585impl Quat {
2586    /// This is the ‘multiply by one!’ of the quaternion rotation world. It’s basically a default, no rotation
2587    /// quaternion.
2588    /// <https://stereokit.net/Pages/StereoKit/Quat/Identity.html>
2589    pub const IDENTITY: Self = Self { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };
2590
2591    /// This is a quaternion that represents a 180 degree rotation around the Y axis. It’s useful for
2592    /// representing a 180 degree turn in a 3D space, such as when you want to face the opposite direction.
2593    pub const Y_180: Self = Self { x: 0.0, y: 1.0, z: 0.0, w: 0.0 };
2594
2595    /// ZERO may be found when testing some [`crate::system::Input`], [`crate::system::Pointer`] or [`crate::system::Controller`]
2596    pub const ZERO: Self = Self { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
2597
2598    /// You may want to use static creation methods, like Quat::look_at, or Quat::IDENTITY instead of this one! Unless you
2599    /// know what you’re doing.
2600    /// <https://stereokit.net/Pages/StereoKit/Quat/Quat.html>
2601    #[inline]
2602    pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
2603        Self { x, y, z, w }
2604    }
2605
2606    /// Makes this Quat the reverse rotation! If this quat goes from A to B, the inverse will go from B to A.
2607    /// Costly, see get_inverse for a faster way to get this.
2608    /// <https://stereokit.net/Pages/StereoKit/Quat/Invert.html>
2609    ///
2610    /// see also [`Quat::get_inverse`] [`quat_inverse`]
2611    /// ### Examples
2612    /// ```
2613    /// use stereokit_rust::maths::Quat;
2614    ///
2615    /// let mut q = Quat::new(1.0, 2.0, 3.0, 4.0);
2616    /// q.invert();
2617    /// assert_eq!(q, Quat { x: -0.033333335, y: -0.06666667, z: -0.1, w: 0.13333334 });
2618    /// ```
2619    #[inline]
2620    pub fn invert(&mut self) -> &mut Self {
2621        let m = unsafe { quat_inverse(self) };
2622        self.x = m.x;
2623        self.y = m.y;
2624        self.z = m.z;
2625        self.w = m.w;
2626        self
2627    }
2628
2629    /// Return the conjugate
2630    /// ### Examples
2631    /// ```
2632    /// use stereokit_rust::maths::Quat;
2633    ///
2634    /// let mut q = Quat::new(1.0, 2.0, 3.0, 4.0);
2635    /// let q2 = q.conjugate();
2636    /// assert_eq!(q2, Quat { x: -1.0, y: -2.0, z: -3.0, w: 4.0 });
2637    /// ```
2638    #[inline]
2639    pub fn conjugate(&self) -> Self {
2640        Self { x: -self.x, y: -self.y, z: -self.z, w: self.w }
2641    }
2642
2643    /// Normalize this quaternion with the same orientation, and a length of 1.
2644    /// Costly, see get_normalized for a faster way to get this.
2645    /// <https://stereokit.net/Pages/StereoKit/Quat/Normalize.html>
2646    ///
2647    /// see also [`Quat::get_normalized`] [`quat_normalize`]
2648    /// ### Examples
2649    /// ```
2650    /// use stereokit_rust::maths::Quat;
2651    ///
2652    /// let mut q = Quat::new(1.0, 2.0, 3.0, 4.0);
2653    /// q.normalize();
2654    /// assert_eq!(q, Quat::new(0.18257419, 0.36514837, 0.54772256, 0.73029674));
2655    /// ```
2656    #[inline]
2657    pub fn normalize(&mut self) -> &mut Self {
2658        let m = unsafe { quat_normalize(self) };
2659        self.x = m.x;
2660        self.y = m.y;
2661        self.z = m.z;
2662        self.w = m.w;
2663        self
2664    }
2665
2666    /// Rotates a quaternion making it relative to another rotation while preserving it’s “Length”!
2667    /// <https://stereokit.net/Pages/StereoKit/Quat/Relative.html>
2668    /// * `to` - The relative quaternion.
2669    ///
2670    /// Returns this quaternion made relative to another rotation.
2671    /// see also [`quat_mul`]
2672    /// ### Examples
2673    /// ```
2674    /// use stereokit_rust::maths::Quat;
2675    ///
2676    /// let mut q = Quat::from_angles(0.0, 90.0, 0.0);
2677    /// assert_eq!(q, Quat { x: 0.0, y: 0.70710677, z: 0.0, w: 0.7071067 });
2678    ///
2679    /// let to = Quat::from_angles(0.0, 0.0, 90.0);
2680    /// q.relative(to);
2681    /// assert_eq!(q, Quat { x: 0.70710677, y: 0.0, z: 0.0, w: 0.7071067 });
2682    /// ```
2683    #[inline]
2684    pub fn relative(&mut self, to: Self) -> &mut Self {
2685        let m = to.mul(*self).mul(to.get_inverse());
2686        self.x = m.x;
2687        self.y = m.y;
2688        self.z = m.z;
2689        self.w = m.w;
2690        self
2691    }
2692
2693    /// This rotates a point around the origin by the Quat.
2694    /// <https://stereokit.net/Pages/StereoKit/Quat/Rotate.html>
2695    /// * `point` - The point to rotate around the origin.
2696    ///
2697    /// Returns the rotated point.
2698    /// see also [`quat_mul_vec`]
2699    /// ### Examples
2700    /// ```
2701    /// use stereokit_rust::maths::{Vec3, Quat};
2702    ///
2703    /// let q = Quat::from_angles(0.0, 90.0, 0.0);
2704    /// let point = Vec3::new(1.0, 0.0, 0.0);
2705    /// let rotated_point = q.rotate_point(point);
2706    /// assert_eq!(rotated_point, Vec3::new(0.0, 0.0, -1.0));
2707    /// ```
2708    #[inline]
2709    pub fn rotate_point(&self, point: Vec3) -> Vec3 {
2710        unsafe { quat_mul_vec(self, &point) }
2711    }
2712
2713    /// Get an array of the 3 angles in degrees of this Quat with x, y and z axis
2714    /// <https://stereokit.net/Pages/StereoKit/Quat.html>
2715    ///
2716    /// see also [`quat_to_axis_angle`]
2717    /// ### Examples
2718    /// ```
2719    /// use stereokit_rust::maths::{Quat, Vec3};
2720    ///
2721    /// let quat = Quat::from_angles(90.0, 180.0, -180.0);
2722    ///
2723    /// let angles: Vec3  = quat.to_angles_degrees().into();
2724    /// assert_eq!(angles, [-270.0, 0.0, 0.0].into());
2725    /// ```
2726    #[inline]
2727    pub fn to_angles_degrees(&self) -> [f32; 3] {
2728        let mut axis = Vec3::ZERO;
2729        let mut rotation: f32 = 0.0;
2730        unsafe { quat_to_axis_angle(*self, &mut axis, &mut rotation) };
2731        axis.normalize();
2732        [rotation * axis.x, rotation * axis.y, rotation * axis.z]
2733    }
2734
2735    /// Get an array of the 3 angles in radians of this Quat with x, y and z axis
2736    /// <https://stereokit.net/Pages/StereoKit/Quat.html>
2737    ///
2738    /// ### Examples
2739    /// ```
2740    /// use stereokit_rust::maths::{Quat, Vec3};
2741    ///
2742    /// let quat = Quat::from_angles(90.0, 0.0, 0.0);
2743    /// let angles = quat.to_angles();
2744    /// assert_eq!(angles, [1.5707964, 0.0, 0.0]);
2745    /// ```
2746    #[inline]
2747    pub fn to_angles(&self) -> [f32; 3] {
2748        self.to_angles_degrees().map(|x| x.to_radians())
2749    }
2750
2751    /// This rotates a point around the origin by the Quat.
2752    /// <https://stereokit.net/Pages/StereoKit/Quat/Rotate.html>
2753    /// * `a` - The Quat to use for rotation.
2754    /// * `point` - The point to rotate around the origin.
2755    ///
2756    /// Returns the rotated point.
2757    /// see also [`quat_mul_vec`] operator '*' [`Quat::rotate_point`]
2758    /// ### Examples
2759    /// ```
2760    /// use stereokit_rust::maths::{Vec3, Quat};
2761    ///
2762    /// let a = Quat::from_angles(0.0, 90.0, 0.0);
2763    /// let point = Vec3::new(1.0, 0.0, 0.0);
2764    /// let result1 = a * point;
2765    /// let result2 = Quat::rotate(a, point);
2766    /// let result3 = a.rotate_point(point);
2767    /// assert_eq!(result1, result2);
2768    /// assert_eq!(result2, result3);
2769    /// assert_eq!(result1, Vec3::new(0.0, 0.0, -1.0));
2770    /// ```
2771    #[inline]
2772    pub fn rotate(a: Quat, point: Vec3) -> Vec3 {
2773        unsafe { quat_mul_vec(&a, &point) }
2774    }
2775
2776    /// Creates a quaternion that goes from one rotation to another.
2777    /// <https://stereokit.net/Pages/StereoKit/Quat/Delta.html>
2778    /// * `from` - The origin rotation.
2779    /// * `to` - The target rotation.
2780    ///
2781    /// Returns the quaternion between from and to.
2782    /// see also `-` operator [`quat_difference`]
2783    /// ### Examples
2784    /// ```
2785    /// use stereokit_rust::maths::Quat;
2786    ///
2787    /// let from = Quat::from_angles(180.0, 0.0, 0.0);
2788    /// let to = Quat::from_angles(0.0, 180.0, 0.0);
2789    /// let delta = Quat::delta(from, to);
2790    /// assert_eq!(delta, Quat::from_angles(0.0, 0.0, 180.0));
2791    ///
2792    /// let delta_b = from - to;
2793    /// assert_eq!(delta_b, delta);
2794    /// ```
2795    #[inline]
2796    pub fn delta(from: Self, to: Self) -> Self {
2797        unsafe { quat_difference(&from, &to) }
2798    }
2799
2800    /// Creates a rotation that goes from one direction to another. Which is comes in handy when trying to roll
2801    /// something around with position data.
2802    /// <https://stereokit.net/Pages/StereoKit/Quat/Delta.html>
2803    /// * `from` - The origin direction.
2804    /// * `to` - The target direction.
2805    ///
2806    /// Returns the quaternion between the two directions.
2807    /// ### Examples
2808    /// ```
2809    /// use stereokit_rust::maths::{Quat, Vec3};
2810    ///
2811    /// let from = Vec3::new(1.0, 0.0, 0.0);
2812    /// let to = Vec3::new(0.0, 0.0, 1.0);
2813    /// let delta = Quat::delta_dir(from, to);
2814    /// assert_eq!(delta, Quat::from_angles(0.0, -90.0, 0.0));
2815    /// ```
2816    #[inline]
2817    pub fn delta_dir(from: Vec3, to: Vec3) -> Self {
2818        let c = Vec3::cross(from, to);
2819        let mut out = Quat { x: c.x, y: c.y, z: c.z, w: 1.0 + Vec3::dot(from, to) };
2820        *(out.normalize())
2821    }
2822
2823    /// Creates a Roll/Pitch/Yaw rotation (applied in that order) from the provided angles in degrees! There is also a
2824    /// From<[f32; 3]> for Quat implementation that does the same thing.
2825    /// <https://stereokit.net/Pages/StereoKit/Quat/FromAngles.html>
2826    /// * `pitch_x_deg` - The angle to rotate around the X-axis in degrees.
2827    /// * `yaw_y_deg` - The angle to rotate around the Y-axis in degrees.
2828    /// * `roll_z_deg` - The angle to rotate around the Z-axis in degrees.
2829    ///
2830    /// Returns a quaternion representing the given Roll/Pitch/Yaw rotation!
2831    /// see also [`quat_from_angles`] [`Quat::from`]
2832    /// ### Examples
2833    /// ```
2834    /// use stereokit_rust::maths::Quat;
2835    ///
2836    /// let quat = Quat::from_angles(45.0, 30.0, 60.0);
2837    /// let quat2: Quat = [45.0, 30.0, 60.0].into();
2838    /// assert_eq!(quat, quat2);
2839    ///
2840    /// let quat = Quat::from_angles(0.0, 180.0, 0.0);
2841    /// let quat2: Quat = Quat::Y_180;
2842    /// assert_eq!(quat, quat2);
2843    /// ```
2844    #[inline]
2845    pub fn from_angles(pitch_x_deg: f32, yaw_y_deg: f32, roll_z_deg: f32) -> Self {
2846        unsafe { quat_from_angles(pitch_x_deg, yaw_y_deg, roll_z_deg) }
2847    }
2848
2849    /// Creates a rotation that describes looking from a point, to another point! This is a great function for camera
2850    /// style rotation, or other facing behavior when you know where an object is, and where you want it to look at.
2851    /// This rotation works best when applied to objects that face Vec3.Forward in their resting/model space pose.
2852    /// <https://stereokit.net/Pages/StereoKit/Quat/LookAt.html>
2853    /// * `from` - Position of where the 'object' is.
2854    /// * `at` - The position you want the 'object' to look at.
2855    /// * `up` - Look From/At positions describe X and Y axis rotation well, but leave Z Axis/Roll
2856    ///   undefined. Providing an upDirection vector helps to indicate roll around the From/At line. If None : up
2857    ///   direction will be (0,1,0), to prevent roll.    
2858    ///
2859    /// Returns a rotation that describes looking from a point, towards another point.
2860    /// see also [`quat_lookat`] [`quat_lookat_up`]
2861    /// ### Examples
2862    /// ```
2863    /// use stereokit_rust::maths::{Quat, Vec3};
2864    ///
2865    /// let from = Vec3::new(1.0, 0.0, 0.0);
2866    /// let at = Vec3::new(0.0, 0.0, 1.0);
2867    /// let up = Vec3::new(0.0, 1.0, 0.0);
2868    /// let quat = Quat::look_at(from, at, Some(up));
2869    /// assert_eq!(quat, Quat::from_angles(0.0, 135.0, 0.0));
2870    ///
2871    /// let quat = Quat::look_at(from, at, None);
2872    /// assert_eq!(quat, Quat::from_angles(0.0, 135.0, 0.0));
2873    /// ```
2874    #[inline]
2875    pub fn look_at<V: Into<Vec3>>(from: V, at: V, up: Option<Vec3>) -> Self {
2876        let from = from.into();
2877        let at = at.into();
2878        match up {
2879            Some(up) => unsafe { quat_lookat_up(&from, &at, &up) },
2880            None => unsafe { quat_lookat(&from, &at) },
2881        }
2882    }
2883
2884    /// Creates a rotation that describes looking towards a direction. This is great for quickly describing facing
2885    /// behavior! This rotation works best when applied to objects that face Vec3.Forward in their resting/model space
2886    /// pose.
2887    /// <https://stereokit.net/Pages/StereoKit/Quat/LookDir.html>
2888    /// * `direction` - The direction the rotation should be looking. Doesn't need to be normalized.
2889    ///
2890    /// Returns a  rotation that describes looking towards a direction.
2891    /// see also [`quat_lookat`]
2892    /// ### Examples
2893    /// ```
2894    /// use stereokit_rust::maths::{Quat, Vec3};
2895    ///
2896    /// let direction = Vec3::new(1.0, 0.0, 0.0);
2897    /// let quat = Quat::look_dir(direction);
2898    /// assert_eq!(quat, Quat::from_angles(0.0, 270.0, 0.0));
2899    /// ```
2900    #[inline]
2901    pub fn look_dir<V: Into<Vec3>>(direction: V) -> Self {
2902        let direction = direction.into();
2903        unsafe { quat_lookat(&Vec3::ZERO, &direction) }
2904    }
2905
2906    /// Spherical Linear interpolation. Interpolates between two quaternions! Both Quats should be normalized/unit
2907    /// quaternions, or you may get unexpected results.
2908    /// <https://stereokit.net/Pages/StereoKit/Quat/Slerp.html>
2909    /// * `a` - Start quaternion, should be normalized/unit length.
2910    /// * `b` - End quaternion, should be normalized/unit length.
2911    /// * `slerp` - The interpolation amount! This’ll be a if 0, and b if 1. Unclamped.
2912    ///
2913    /// Returns a blend between the two quaternions!
2914    /// see also [`quat_slerp`]
2915    /// ### Examples
2916    /// ```
2917    /// use stereokit_rust::maths::Quat;
2918    ///
2919    /// let a = Quat::from_angles(0.0, 0.0, 0.0);
2920    /// let b = Quat::from_angles(0.0, 0.0, 90.0);
2921    /// let result = Quat::slerp(a, b, 0.25);
2922    /// assert_eq!(result, Quat::from_angles(0.0, 0.0, 22.5));
2923    /// ```
2924    #[inline]
2925    pub fn slerp(a: Self, b: Self, slerp: f32) -> Self {
2926        unsafe { quat_slerp(&a, &b, slerp) }
2927    }
2928
2929    /// The reverse rotation! If this quat goes from A to B, the inverse will go from B to A.
2930    /// <https://stereokit.net/Pages/StereoKit/Quat/Inverse.html>
2931    ///
2932    /// see also [`quat_inverse`]
2933    /// ### Examples
2934    /// ```
2935    /// use stereokit_rust::maths::Quat;
2936    ///
2937    /// let q = Quat::from_angles(90.0, 0.0, 0.0);
2938    /// let q_inv = q.get_inverse();
2939    /// assert_eq!(q_inv, Quat::from_angles(-90.0, 0.0, 0.0));
2940    /// ```
2941    #[inline]
2942    pub fn get_inverse(&self) -> Self {
2943        unsafe { quat_inverse(self) }
2944    }
2945
2946    /// A normalized quaternion has the same orientation, and a length of 1.
2947    /// <https://stereokit.net/Pages/StereoKit/Quat/Normalized.html>
2948    ///
2949    /// see also [`quat_normalize`]
2950    /// ### Examples
2951    /// ```
2952    /// use stereokit_rust::maths::Quat;
2953    ///
2954    /// let q = Quat::new(2.0, 0.0, 0.0, 0.0);
2955    /// let normalized = q.get_normalized();
2956    /// assert_eq!(normalized, Quat::new(1.0, 0.0, 0.0, 0.0));
2957    /// assert_eq!(normalized, Quat::from_angles(180.0, 0.0, 0.0));
2958    /// ```
2959    #[inline]
2960    pub fn get_normalized(&self) -> Self {
2961        unsafe { quat_normalize(self) }
2962    }
2963
2964    /// A Vec4 and a Quat are only really different by name and purpose. So, if you need to do Quat math with your
2965    /// Vec4, or visa versa, who am I to judge?
2966    /// <https://stereokit.net/Pages/StereoKit/Quat/Vec4.html>
2967    ///
2968    /// see also [`Quat::from`]
2969    /// ### Examples
2970    /// ```
2971    /// use stereokit_rust::maths::{Quat, Vec4};
2972    ///
2973    /// let quat = Quat::new(1.0, 2.0, 3.0, 4.0);
2974    /// let vec4 = Vec4::new(1.0, 2.0, 3.0, 4.0);
2975    /// assert_eq!(vec4, quat.get_as_vec4());
2976    /// assert_eq!(vec4, quat.into());
2977    /// assert_eq!(quat, vec4.into());
2978    /// ```
2979    #[inline]
2980    pub fn get_as_vec4(&self) -> Vec4 {
2981        Vec4 { x: self.x, y: self.y, z: self.z, w: self.w }
2982    }
2983
2984    /// This is the combination of rotations a and b. Note that order matters h
2985    /// <https://stereokit.net/Pages/StereoKit/Quat/op_Multiply.html>
2986    ///
2987    /// see also `*` operator [`quat_mul`]
2988    /// ### Examples
2989    /// ```
2990    /// use stereokit_rust::maths::Quat;
2991    ///
2992    /// let a = Quat::from_angles(180.0, 0.0, 0.0);
2993    /// let b = Quat::from_angles(0.0, 180.0, 0.0);
2994    /// let c = a * b;
2995    /// let d = a.mul(b);
2996    /// assert_eq!(c, Quat::from_angles(0.0, 0.0, -180.0));
2997    /// assert_eq!(d, Quat::from_angles(0.0, 0.0, -180.0));
2998    /// ```
2999    #[inline]
3000    pub fn mul(&self, rhs: Self) -> Self {
3001        unsafe { quat_mul(self, &rhs) }
3002    }
3003
3004    /// This rotates a point around the origin by the Quat.
3005    /// <https://stereokit.net/Pages/StereoKit/Quat/op_Multiply.html>
3006    ///
3007    /// see also `*` operator [`quat_mul_vec`]
3008    /// ### Examples
3009    /// ```
3010    /// use stereokit_rust::maths::{Quat, Vec3};
3011    ///
3012    /// let q = Quat::from_angles(0.0, 90.0, 0.0);
3013    /// let v = Vec3::new(1.0, 0.0, 0.0);
3014    /// let result = q.mul_vec3(v);
3015    /// assert_eq!(result, Vec3::new(0.0, 0.0, -1.0));
3016    ///
3017    /// let result_b = q * v;
3018    /// assert_eq!(result_b, result);
3019    /// ```
3020    #[inline]
3021    pub fn mul_vec3<V: Into<Vec3>>(&self, rhs: V) -> Vec3 {
3022        let rhs = rhs.into();
3023        unsafe { quat_mul_vec(self, &rhs) }
3024    }
3025
3026    /// get an array
3027    ///
3028    /// see also [`Quat::from`]
3029    /// ### Examples
3030    /// ```
3031    /// use stereokit_rust::maths::Quat;
3032    ///
3033    /// let q = Quat::new(1.0, 2.0, 3.0, 4.0);
3034    /// assert_eq!(q.to_array(), [1.0, 2.0, 3.0, 4.0]);
3035    /// ```
3036    #[inline]
3037    pub const fn to_array(&self) -> [f32; 4] {
3038        [self.x, self.y, self.z, self.w]
3039    }
3040}
3041
3042impl Display for Quat {
3043    /// Mostly for debug purposes, this is a decent way to log or inspect the vector in debug mode. Looks
3044    /// like “[x, y, z, w]”
3045    /// <https://stereokit.net/Pages/StereoKit/Quat/ToString.html>
3046    ///
3047    /// ### Examples
3048    /// ```
3049    /// use stereokit_rust::maths::Quat;
3050    ///
3051    /// let quat = Quat::new(1.0, 2.0, 3.3, 4.0);
3052    /// assert_eq!(format!("{}", quat), "[x:1, y:2, z:3.3, w:4]");
3053    /// ```
3054    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3055        write!(f, "[x:{}, y:{}, z:{}, w:{}]", self.x, self.y, self.z, self.w)
3056    }
3057}
3058
3059/// This is the combination of rotations a and b. Note that order matters h
3060/// <https://stereokit.net/Pages/StereoKit/Quat/op_Multiply.html>
3061///
3062/// see also [`quat_mul`]
3063impl Mul<Quat> for Quat {
3064    type Output = Self;
3065
3066    /// ### Examples
3067    /// ```
3068    /// use stereokit_rust::maths::Quat;
3069    ///
3070    /// let a = Quat::from_angles(180.0, 0.0, 0.0);
3071    /// let b = Quat::from_angles(0.0, 180.0, 0.0);
3072    /// let c = Quat::from_angles(0.0, 0.0, -180.0);
3073    /// assert_eq!(a * b, c);
3074    /// ```
3075    #[inline]
3076    fn mul(self, rhs: Self) -> Self::Output {
3077        unsafe { quat_mul(&self, &rhs) }
3078    }
3079}
3080
3081/// This is the combination of rotations a and b. Note that order matters h
3082/// <https://stereokit.net/Pages/StereoKit/Quat/op_Multiply.html>
3083///
3084/// see also [`quat_mul`]
3085impl MulAssign<Quat> for Quat {
3086    /// ### Examples
3087    /// ```
3088    /// use stereokit_rust::maths::Quat;
3089    ///
3090    /// let mut q = Quat::new(1.0, 0.0, 0.0, 0.0);
3091    /// let r = Quat::new(0.0, 1.0, 0.0, 0.0);
3092    /// q *= r;
3093    /// assert_eq!(q, Quat::new(0.0, 0.0, -1.0, 0.0));
3094    /// ```
3095    #[inline]
3096    fn mul_assign(&mut self, rhs: Quat) {
3097        *self = unsafe { quat_mul(self, &rhs) }
3098    }
3099}
3100
3101/// This rotates a point around the origin by the Quat.
3102/// <https://stereokit.net/Pages/StereoKit/Quat/op_Multiply.html>
3103///
3104/// see also [`quat_mul_vec`]
3105impl Mul<Vec3> for Quat {
3106    type Output = Vec3;
3107
3108    /// ### Examples
3109    /// ```
3110    /// use stereokit_rust::maths::{Quat, Vec3};
3111    ///
3112    /// let q = Quat::from_angles(0.0, 90.0, 0.0);
3113    /// let v = Vec3::new(1.0, 0.0, 0.0);
3114    /// assert_eq!(q * v, Vec3::new(0.0, 0.0, -1.0));
3115    /// ```
3116    fn mul(self, rhs: Vec3) -> Self::Output {
3117        unsafe { quat_mul_vec(&self, &rhs) }
3118    }
3119}
3120
3121/// Gets a Quat representing the rotation from a to b.
3122/// <https://stereokit.net/Pages/StereoKit/Quat/op_Subtraction.html>
3123/// see also QuatT::delta()
3124///
3125/// see also [`quat_difference`]
3126impl Sub<Quat> for Quat {
3127    type Output = Self;
3128
3129    /// ### Examples
3130    /// ```
3131    /// use stereokit_rust::maths::Quat;
3132    ///
3133    /// let from = Quat::from_angles(180.0, 0.0, 0.0);
3134    /// let to = Quat::from_angles(0.0, 180.0, 0.0);
3135    /// let delta = Quat::delta(from, to);
3136    /// assert_eq!(delta, Quat::from_angles(0.0, 0.0, 180.0));
3137    /// assert_eq!(from - to, delta);
3138    /// ```
3139    fn sub(self, rhs: Self) -> Self::Output {
3140        unsafe { quat_difference(&self, &rhs) }
3141    }
3142}
3143
3144/// A Matrix in StereoKit is a 4x4 grid of numbers that is used to represent a transformation for any sort of position
3145/// or vector! This is an oversimplification of what a matrix actually is, but it’s accurate in this case.
3146///
3147/// Matrices are really useful for transforms because you can chain together all sorts of transforms into a single
3148/// Matrix! A Matrix transform really shines when applied to many positions, as the more expensive operations get cached
3149/// within the matrix values.
3150///
3151/// Multiple matrix transforms can be combined by multiplying them. In StereoKit, to create a matrix that first scales
3152/// an object, followed by rotating it, and finally translating it you would use this order:
3153/// Matrix M = Matrix.S(...) * Matrix.R(...) * Matrix.T(...);
3154///
3155/// This order is related to the fact that StereoKit uses row-major order to store matrices. Note that in other 3D
3156/// frameworks and certain 3D math references you may find column-major matrices, which would need the reverse order
3157/// (i.e. TRS), so please keep this in mind when creating transformations.
3158///
3159/// Matrices are prominently used within shaders for mesh transforms!
3160/// <https://stereokit.net/Pages/StereoKit/Matrix.html>
3161///
3162/// see also [`glam::Mat4`]
3163/// ### Examples
3164/// ```
3165/// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
3166/// use stereokit_rust::{maths::{Vec3, Quat, Matrix}, model::Model};
3167///
3168/// let model = Model::from_file("center.glb", None).unwrap().copy();
3169/// let transform = Matrix::t_r_s(Vec3::NEG_Y * 0.7, [0.0, 155.0, 10.0], Vec3::ONE * 0.3);
3170///
3171/// filename_scr = "screenshots/matrix.jpeg";
3172/// test_screenshot!( // !!!! Get a proper main loop !!!!
3173///     model.draw(token, transform, None, None);
3174/// );
3175/// ```
3176/// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/matrix.jpeg" alt="screenshot" width="200">
3177#[repr(C)]
3178#[derive(Copy, Clone)]
3179pub union Matrix {
3180    pub row: [Vec4; 4usize],
3181    pub m: [f32; 16usize],
3182}
3183
3184impl From<glam::Mat4> for Matrix {
3185    fn from(m: glam::Mat4) -> Self {
3186        Matrix { row: [m.x_axis.into(), m.y_axis.into(), m.z_axis.into(), m.w_axis.into()] }
3187    }
3188}
3189
3190impl From<[f32; 16]> for Matrix {
3191    fn from(s: [f32; 16]) -> Self {
3192        Self { m: s }
3193    }
3194}
3195
3196impl From<Pose> for Matrix {
3197    fn from(pose: Pose) -> Self {
3198        Self::t_r(pose.position, pose.orientation)
3199    }
3200}
3201
3202impl std::fmt::Debug for Matrix {
3203    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3204        write!(f, "{self}")
3205    }
3206}
3207
3208///  Warning: Equality with a precision of 0.1 millimeter
3209impl PartialEq for Matrix {
3210    /// Warning: Equality with a precision of 0.00001
3211    /// ### Examples
3212    /// ```
3213    /// use stereokit_rust::maths::Matrix;
3214    ///
3215    /// let matrix = Matrix::IDENTITY;
3216    /// assert_eq!(matrix, Matrix::IDENTITY);
3217    /// ```
3218    fn eq(&self, other: &Self) -> bool {
3219        unsafe {
3220            self.row[0] == other.row[0]
3221                && self.row[1] == other.row[1]
3222                && self.row[2] == other.row[2]
3223                && self.row[3] == other.row[3]
3224        }
3225    }
3226}
3227
3228unsafe extern "C" {
3229    pub fn pose_matrix_out(pose: *const Pose, out_result: *mut Matrix, scale: Vec3);
3230    pub fn matrix_inverse(a: *const Matrix, out_Matrix: *mut Matrix);
3231    pub fn matrix_invert(a: *const Matrix) -> Matrix;
3232    pub fn matrix_mul(a: *const Matrix, b: *const Matrix, out_Matrix: *mut Matrix);
3233    // Deprecated: pub fn matrix_mul_point(transform: *const Matrix, point: *const Vec3) -> Vec3;
3234    // Deprecated: pub fn matrix_mul_point4(transform: *const Matrix, point: *const Vec4) -> Vec4;
3235    pub fn matrix_mul_direction(transform: *const Matrix, direction: *const Vec3) -> Vec3;
3236    // Deprecated: pub fn matrix_mul_rotation(transform: *const Matrix, orientation: *const Quat) -> Quat;
3237    // Deprecated: pub fn matrix_mul_pose(transform: *const Matrix, pose: *const Pose) -> Pose;
3238    pub fn matrix_transform_pt(transform: Matrix, point: Vec3) -> Vec3;
3239    pub fn matrix_transform_pt4(transform: Matrix, point: Vec4) -> Vec4;
3240    pub fn matrix_transform_dir(transform: Matrix, direction: Vec3) -> Vec3;
3241    pub fn matrix_transform_ray(transform: Matrix, ray: Ray) -> Ray;
3242    pub fn matrix_transform_quat(transform: Matrix, rotation: Quat) -> Quat;
3243    pub fn matrix_transform_pose(transform: Matrix, pose: Pose) -> Pose;
3244    pub fn matrix_transpose(transform: Matrix) -> Matrix;
3245    pub fn matrix_to_angles(transform: *const Matrix) -> Vec3;
3246    pub fn matrix_trs(position: *const Vec3, orientation: *const Quat, scale: *const Vec3) -> Matrix;
3247    pub fn matrix_t(position: Vec3) -> Matrix;
3248    pub fn matrix_r(orientation: Quat) -> Matrix;
3249    pub fn matrix_s(scale: Vec3) -> Matrix;
3250    pub fn matrix_ts(position: Vec3, scale: Vec3) -> Matrix;
3251    pub fn matrix_trs_out(out_result: *mut Matrix, position: *const Vec3, orientation: *const Quat, scale: *const Vec3);
3252    pub fn matrix_perspective(fov_degrees: f32, aspect_ratio: f32, near_clip: f32, far_clip: f32) -> Matrix;
3253    pub fn matrix_orthographic(width: f32, height: f32, near_clip: f32, far_clip: f32) -> Matrix;
3254    pub fn matrix_decompose(
3255        transform: *const Matrix,
3256        out_position: *mut Vec3,
3257        out_scale: *mut Vec3,
3258        out_orientation: *mut Quat,
3259    ) -> Bool32T;
3260    pub fn matrix_extract_translation(transform: *const Matrix) -> Vec3;
3261    pub fn matrix_extract_scale(transform: *const Matrix) -> Vec3;
3262    pub fn matrix_extract_rotation(transform: *const Matrix) -> Quat;
3263    pub fn matrix_extract_pose(transform: *const Matrix) -> Pose;
3264}
3265
3266impl Matrix {
3267    /// Identity matrix made of [[Vec4::X, Vec4::Y, Vec4::Z, Vec4::W]]
3268    pub const IDENTITY: Matrix = Matrix { row: [Vec4::X, Vec4::Y, Vec4::Z, Vec4::W] };
3269
3270    /// Identity matrix rotated 180 degrees around the Y axis made of [[Vec4::NEG_X, Vec4::Y, Vec4::NEG_Z, Vec4::W]]
3271    /// This is mainly used for test screenshots, but it can be useful for other things too!
3272    pub const Y_180: Matrix = Matrix { row: [Vec4::NEG_X, Vec4::Y, Vec4::NEG_Z, Vec4::W] };
3273
3274    /// Null or Zero matrix made of [[Vec4::ZERO, Vec4::ZERO, Vec4::ZERO, Vec4::ZERO]]
3275    pub const NULL: Matrix = Matrix { row: [Vec4::ZERO, Vec4::ZERO, Vec4::ZERO, Vec4::ZERO] };
3276
3277    /// This creates a matrix used for projecting 3D geometry onto a 2D surface for rasterization. Orthographic
3278    /// projection matrices will preserve parallel lines. This is great for 2D scenes or content.
3279    /// <https://stereokit.net/Pages/StereoKit/Matrix/Orthographic.html>
3280    /// * `width` - in meters, of the area that will  be projected.
3281    /// * `height` - The height, in meters, of the area that will be projected
3282    /// * `near_clip` - Anything closer than this distance (in meters) will be discarded. Must not be zero, and if you
3283    ///   make this too small, you may experience glitching in your depth buffer.
3284    /// * `far_clip` - Anything further than this distance (in meters) will be discarded. For low resolution depth
3285    ///   buffers, this should not be too far away, or you'll see bad z-fighting artifacts.    
3286    ///
3287    /// Returns the final orthographic Matrix.
3288    /// ### Examples
3289    /// ```
3290    /// use stereokit_rust::maths::{Vec3, Matrix};
3291    ///
3292    /// let translate = Matrix::orthographic(1.0, 1.0, 0.1, 100.0);
3293    /// let point = Vec3::new(1.0, 2.0, 3.0);
3294    ///
3295    /// let projection = translate * point;
3296    /// assert_eq!(projection, Vec3 { x: 2.0, y: 4.0, z: -0.03103103 });
3297    /// ```
3298    /// see also [`matrix_orthographic`]
3299    #[inline]
3300    pub fn orthographic(width: f32, height: f32, near_clip: f32, far_clip: f32) -> Self {
3301        unsafe { matrix_orthographic(width, height, near_clip, far_clip) }
3302    }
3303
3304    /// This creates a matrix used for projecting 3D geometry onto a 2D surface for rasterization. Perspective
3305    /// projection matrices will cause parallel lines to converge at the horizon. This is great for normal looking
3306    /// content.
3307    /// <https://stereokit.net/Pages/StereoKit/Matrix/Perspective.html>
3308    /// * `fov_degrees` - This is the vertical field of view of the perspective matrix, units are in degrees.
3309    /// * `aspect_ratio` - The projection surface's width/height.
3310    /// * `near_clip` - Anything closer than this distance (in meters) will be discarded. Must not be zero, and if you
3311    ///   make this too small, you may experience glitching in your depth buffer.
3312    /// * `far_clip` - Anything further than this distance (in meters) will be discarded. For low resolution depth
3313    ///   buffers, this should not be too far away, or you'll see bad z-fighting artifacts.    
3314    ///
3315    /// Returns the final perspective matrix.
3316    /// see also [`matrix_perspective`]
3317    /// ### Examples
3318    /// ```
3319    /// use stereokit_rust::maths::{Vec3, Matrix};
3320    ///
3321    /// let translate = Matrix::perspective(90.0, 1.0, 0.1, 100.0);
3322    /// let point = Vec3::new(1.0, 2.0, 3.0);
3323    ///
3324    /// let projection = translate * point;
3325    /// assert_eq!(projection,  Vec3 { x: 72.946686, y: 145.89337, z: -3.1031032 });
3326    /// ```
3327    #[inline]
3328    pub fn perspective(fov_degrees: f32, aspect_ratio: f32, near_clip: f32, far_clip: f32) -> Self {
3329        unsafe { matrix_perspective(fov_degrees.to_radians(), aspect_ratio, near_clip, far_clip) }
3330    }
3331
3332    /// This creates a matrix used for projecting 3D geometry onto a 2D surface for rasterization. With the known camera
3333    /// intrinsics, you can replicate its perspective!
3334    /// <https://stereokit.net/Pages/StereoKit/Matrix/Perspective.html>
3335    /// * `image_resolution` - The resolution of the image. This should be the image's width and height in pixels.
3336    /// * `focal_length_px` - The focal length of camera in pixels, with image coordinates +X (pointing right) and +Y
3337    ///   (pointing up).
3338    /// * `near_clip` - Anything closer than this distance (in meters) will be discarded. Must not be zero, and if you
3339    ///   make this too small, you may experience glitching in your depth buffer.
3340    /// * `far_clip` - Anything further than this distance (in meters) will be discarded. For low resolution depth
3341    ///   buffers, this should not be too far away, or you'll see bad z-fighting artifacts.
3342    ///
3343    /// Returns the final perspective matrix.
3344    /// Remarks: Think of the optical axis as an imaginary line that passes through the camera lens. In front of the
3345    /// camera lens, there's an image plane, perpendicular to the optical axis, where the image of the scene being
3346    /// captured is formed. Its distance is equal to the focal length of the camera from the center of the lens. Here,
3347    /// we find the ratio between the size of the image plane and distance from the camera in one unit distance and
3348    /// multiply it by the near clip distance to find a near plane that is parallel.
3349    ///
3350    /// see also [`matrix_perspective`]
3351    /// ### Examples
3352    /// ```
3353    /// use stereokit_rust::maths::{Vec2, Vec3, Matrix};
3354    ///
3355    /// let translate = Matrix::perspective_focal(Vec2::new(1.0, 1.0), 1.0, 0.1, 100.0);
3356    /// let point = Vec3::new(1.0, 2.0, 3.0);
3357    ///
3358    /// let projection = translate * point;
3359    /// assert_eq!(projection,  Vec3 { x: 2.0, y: 4.0, z: -3.1031032 });
3360    /// ```
3361    #[inline]
3362    pub fn perspective_focal(image_resolution: Vec2, focal_length_px: f32, near_clip: f32, far_clip: f32) -> Self {
3363        let near_plane_dimensions = image_resolution / focal_length_px * near_clip;
3364
3365        let two_near = near_clip + near_clip;
3366        let f_range = far_clip / (near_clip - far_clip);
3367
3368        Self {
3369            m: [
3370                two_near / near_plane_dimensions.x,
3371                0.0,
3372                0.0,
3373                0.0,
3374                //
3375                0.0,
3376                two_near / near_plane_dimensions.y,
3377                0.0,
3378                0.0,
3379                //
3380                0.0,
3381                0.0,
3382                f_range,
3383                -1.0,
3384                //
3385                0.0,
3386                0.0,
3387                f_range * near_clip,
3388                0.0,
3389            ],
3390        }
3391    }
3392
3393    /// A transformation that describes one position looking at another point. This is particularly useful for
3394    /// describing camera transforms!
3395    /// <https://stereokit.net/Pages/StereoKit/Matrix/LookAt.html>
3396    ///
3397    /// see also [`matrix_r`]
3398    /// ### Examples
3399    /// ```
3400    /// use stereokit_rust::maths::{Vec3, Matrix};
3401    ///
3402    /// let from = Vec3::new(1.0, 0.0, 0.0);
3403    /// let at = Vec3::new(0.0, 0.0, 0.0);
3404    /// let up = Vec3::new(0.0, 1.0, 0.0);
3405    /// let transform = Matrix::look_at(from, at, Some(up));
3406    /// assert_eq!(transform, Matrix::from([
3407    ///     0.0, 0.0, 1.0, 0.0,
3408    ///     0.0, 1.0, 0.0, 0.0,
3409    ///     1.0, 0.0, 0.0, 0.0,
3410    ///     0.0, 0.0,-1.0, 1.0,
3411    /// ]));
3412    ///
3413    /// let transform_b = Matrix::look_at(from, at, None);
3414    /// assert_eq!(transform, transform_b);
3415    /// ```
3416    #[inline]
3417    pub fn look_at(from: Vec3, at: Vec3, up: Option<Vec3>) -> Self {
3418        let up = up.unwrap_or(Vec3::UP);
3419        let forward = (from - at).get_normalized();
3420        let right_v = Vec3::perpendicular_right(forward, up).get_normalized();
3421        let up_v = Vec3::perpendicular_right(right_v, forward).get_normalized();
3422        Self {
3423            m: [
3424                right_v.x,
3425                up_v.x,
3426                forward.x,
3427                0.0,
3428                //
3429                right_v.y,
3430                up_v.y,
3431                forward.y,
3432                0.0,
3433                //
3434                right_v.z,
3435                up_v.z,
3436                forward.z,
3437                0.0,
3438                //
3439                -Vec3::dot(from, right_v),
3440                -Vec3::dot(from, up_v),
3441                -Vec3::dot(from, forward),
3442                1.0,
3443            ],
3444        }
3445    }
3446
3447    /// Create a rotation matrix from a Quaternion. Consider using [`Matrix::update_r`] when you have to recalculate
3448    /// Matrix at each steps in main loop.
3449    /// <https://stereokit.net/Pages/StereoKit/Matrix/R.html>
3450    /// * `rotation` - The quaternion describing the rotation for this transform.
3451    ///
3452    /// returns a Matrix that will rotate by the provided Quaternion orientation.
3453    /// see also [`matrix_r`] [`Matrix::update_r`]
3454    /// ### Examples
3455    /// ```
3456    /// use stereokit_rust::maths::{Quat, Matrix};
3457    ///
3458    /// let rotation = Quat::from_angles(90.0, 0.0, 0.0);
3459    /// let matrix = Matrix::r(rotation);
3460    /// assert_eq!(matrix, Matrix::from([
3461    ///     1.0, 0.0, 0.0, 0.0,
3462    ///     0.0, 0.0, 1.0, 0.0,
3463    ///     0.0,-1.0, 0.0, 0.0,
3464    ///     0.0, 0.0, 0.0, 1.0,
3465    /// ]));
3466    ///
3467    /// let rotation = Quat::from_angles(0.0, 90.0, 0.0);
3468    /// let matrix = Matrix::r(rotation);
3469    /// assert_eq!(matrix, Matrix::from([
3470    ///     0.0, 0.0, -1.0, 0.0,
3471    ///     0.0, 1.0,  0.0, 0.0,
3472    ///     1.0, 0.0,  0.0, 0.0,
3473    ///     0.0, 0.0,  0.0, 1.0,
3474    /// ]));
3475    ///
3476    /// ```
3477    #[inline]
3478    pub fn r<Q: Into<Quat>>(rotation: Q) -> Self {
3479        unsafe { matrix_r(rotation.into()) }
3480    }
3481
3482    /// Create a rotation matrix from a Quaternion.
3483    /// <https://stereokit.net/Pages/StereoKit/Matrix/R.html>
3484    /// * `rotation` - The quaternion describing the rotation for this transform.
3485    ///
3486    /// see also [`matrix_trs_out`] [`Matrix::r`]
3487    /// ### Examples
3488    /// ```
3489    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
3490    /// use stereokit_rust::{maths::{Vec3, Quat, Matrix}, mesh::Mesh, material::Material,
3491    ///                      util::Time};
3492    ///
3493    /// let mesh = Mesh::cube();
3494    /// let material = Material::pbr();
3495    ///
3496    /// let mut transform = Matrix::IDENTITY;
3497    /// let mut delta_rotate = 90.0;
3498    ///
3499    /// test_steps!( // !!!! Get a proper main loop !!!!
3500    ///     delta_rotate = (delta_rotate + 10.0  * Time::get_stepf()) % 360.0;
3501    ///     let rotation = Quat::from_angles(0.0, delta_rotate, 0.0);
3502    ///
3503    ///     transform.update_r(&rotation);
3504    ///
3505    ///     mesh.draw(token, &material, transform, None, None);
3506    ///     assert_eq!(transform, Matrix::r(rotation));
3507    /// );
3508    #[inline]
3509    pub fn update_r(&mut self, rotation: &Quat) {
3510        unsafe { matrix_trs_out(self, &Vec3::ZERO, rotation, &Vec3::ONE) }
3511    }
3512
3513    /// Creates a scaling Matrix, where scale can be different on each axis (non-uniform).Consider using
3514    /// [`Matrix::update_s`] when you have to recalculate Matrix at each steps in main loop.
3515    /// <https://stereokit.net/Pages/StereoKit/Matrix/S.html>
3516    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is the default.
3517    ///
3518    /// Returns a non-uniform scaling matrix.
3519    /// see also [`matrix_s`] [`Matrix::update_s`]
3520    /// ### Examples
3521    /// ```
3522    /// use stereokit_rust::maths::{Vec3, Matrix};
3523    ///
3524    /// let scale = Matrix::s(Vec3::new(2.0, 3.0, 4.0));
3525    /// let point = Vec3::new(1.0, 1.0, 1.0);
3526    /// let scaled_point = scale * point;
3527    /// assert_eq!(scaled_point, Vec3::new(2.0, 3.0, 4.0));
3528    /// ```
3529    #[inline]
3530    pub fn s<V: Into<Vec3>>(scale: V) -> Self {
3531        unsafe { matrix_s(scale.into()) }
3532    }
3533
3534    /// Creates a scaling Matrix, where scale can be different on each axis (non-uniform).
3535    /// <https://stereokit.net/Pages/StereoKit/Matrix/S.html>
3536    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is the default.
3537    ///
3538    /// see also [`matrix_trs_out`] [`Matrix::s`]
3539    /// ### Examples
3540    /// ```
3541    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
3542    /// use stereokit_rust::{maths::{Vec3, Quat, Matrix}, mesh::Mesh, material::Material,
3543    ///                      util::Time};
3544    ///
3545    /// let mesh = Mesh::cube();
3546    /// let material = Material::pbr();
3547    ///
3548    /// let mut transform = Matrix::IDENTITY;
3549    /// let mut delta_scale = 2.0;
3550    ///
3551    /// test_steps!( // !!!! Get a proper main loop !!!!
3552    ///     let scale = Vec3::ONE * (delta_scale * Time::get_stepf()).cos();
3553    ///
3554    ///     transform.update_s(&scale);
3555    ///
3556    ///     mesh.draw(token, &material, transform, None, None);
3557    ///     assert_eq!(transform, Matrix::s(scale));
3558    /// );
3559    /// ```
3560    #[inline]
3561    pub fn update_s(&mut self, scale: &Vec3) {
3562        unsafe { matrix_trs_out(self, &Vec3::ZERO, &Quat::IDENTITY, scale) }
3563    }
3564
3565    /// Translate. Creates a translation Matrix! Consider using [`Matrix::update_t`] when you have to recalculate
3566    /// Matrix at each steps in main loop.
3567    /// <https://stereokit.net/Pages/StereoKit/Matrix/T.html>
3568    /// * `translation` - Move an object by this amount.
3569    ///
3570    /// Returns a Matrix containing a simple translation!
3571    /// see also [`matrix_t`] [`Matrix::update_t`]
3572    /// ### Examples
3573    /// ```
3574    /// use stereokit_rust::maths::{Vec3, Matrix};
3575    ///
3576    /// let translation = Matrix::t(Vec3::new(1.0, 2.0, 3.0));
3577    /// let point = Vec3::new(0.0, 0.0, 0.0);
3578    /// let translated_point = translation * point;
3579    /// assert_eq!(translated_point, Vec3::new(1.0, 2.0, 3.0));
3580    /// ```    
3581    #[inline]
3582    pub fn t<V: Into<Vec3>>(translation: V) -> Self {
3583        unsafe { matrix_t(translation.into()) }
3584    }
3585
3586    /// Translate. Creates a translation Matrix!
3587    /// <https://stereokit.net/Pages/StereoKit/Matrix/T.html>
3588    /// * `translation` - Move an object by this amount.
3589    ///
3590    /// see also [`matrix_trs_out`] [`Matrix::t`]
3591    /// ### Examples
3592    /// ```
3593    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
3594    /// use stereokit_rust::{maths::{Vec3, Quat, Matrix}, mesh::Mesh, material::Material,
3595    ///                      util::Time};
3596    ///
3597    /// let mesh = Mesh::cube();
3598    /// let material = Material::pbr();
3599    ///
3600    /// let mut transform = Matrix::IDENTITY;
3601    /// let mut position = Vec3::ZERO;
3602    ///
3603    /// test_steps!( // !!!! Get a proper main loop !!!!
3604    ///     position += Vec3::NEG_Z * Time::get_stepf();
3605    ///
3606    ///     transform.update_t(&position);
3607    ///
3608    ///     mesh.draw(token, &material, transform, None, None);
3609    ///     assert_eq!(transform, Matrix::t(position));
3610    /// );
3611    /// ```
3612    #[inline]
3613    pub fn update_t(&mut self, translation: &Vec3) {
3614        unsafe { matrix_trs_out(self, translation, &Quat::IDENTITY, &Vec3::ONE) }
3615    }
3616
3617    /// Translate, Rotate. Creates a transform Matrix using these components!
3618    /// <https://stereokit.net/Pages/StereoKit/Matrix/TR.html>
3619    /// * `translation` - Move an object by this amount.
3620    /// * `rotation` - The quaternion describing the rotation for this transform.
3621    ///
3622    /// Returns a Matrix that combines translation and rotation information into a single Matrix!
3623    /// see also [`matrix_trs`]
3624    #[deprecated(since = "0.40.0", note = "please use Matrix::t_r or Matrix::update_t_r")]
3625    #[inline]
3626    pub fn tr(translation: &Vec3, rotation: &Quat) -> Self {
3627        unsafe { matrix_trs(translation, rotation, &Vec3::ONE) }
3628    }
3629
3630    /// Translate, Rotate. Creates a transform Matrix using these components! Consider using
3631    /// [`Matrix::update_t_r`] when you have to recalculate Matrix at each steps in main loop.
3632    /// <https://stereokit.net/Pages/StereoKit/Matrix/TR.html>
3633    /// * `translation` - Move an object by this amount.
3634    /// * `rotation` - The quaternion describing the rotation for this transform.
3635    ///
3636    /// Returns a Matrix that combines translation and rotation information into a single Matrix!
3637    /// see also [`matrix_trs`] [`Matrix::update_t_r`]
3638    /// ### Examples
3639    /// ```
3640    /// use stereokit_rust::maths::{Vec3, Matrix};
3641    ///
3642    /// let transform = Matrix::t_r([1.0, 2.0, 3.0], [0.0, 180.0, 0.0]);
3643    /// let point = Vec3::new(1.0, 1.0, 1.0);
3644    /// let transformed_point = transform * point;
3645    /// assert_eq!(transformed_point, Vec3::new(0.0, 3.0, 2.0));
3646    /// ```
3647    #[inline]
3648    pub fn t_r<V: Into<Vec3>, Q: Into<Quat>>(translation: V, rotation: Q) -> Self {
3649        unsafe { matrix_trs(&translation.into(), &rotation.into(), &Vec3::ONE) }
3650    }
3651
3652    /// Translate, Rotate. Creates a transform Matrix using these components!
3653    /// <https://stereokit.net/Pages/StereoKit/Matrix/TR.html>
3654    /// * `translation` - Move an object by this amount.
3655    /// * `rotation` - The quaternion describing the rotation for this transform.
3656    ///
3657    /// see also [`matrix_trs_out`] [`Matrix::t_r`]
3658    /// ### Examples
3659    /// ```
3660    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
3661    /// use stereokit_rust::{maths::{Vec3, Quat, Matrix}, mesh::Mesh, material::Material,
3662    ///                      util::Time};
3663    ///
3664    /// let mesh = Mesh::cube();
3665    /// let material = Material::pbr();
3666    ///
3667    /// let mut transform = Matrix::IDENTITY;
3668    /// let mut position = Vec3::ZERO;
3669    /// let mut delta_rotate = 90.0;
3670    ///
3671    /// test_steps!( // !!!! Get a proper main loop !!!!
3672    ///     position += Vec3::NEG_Z * Time::get_stepf();
3673    ///     delta_rotate = (delta_rotate + 10.0  * Time::get_stepf()) % 360.0;
3674    ///     let rotation = Quat::from_angles(0.0, delta_rotate, 0.0);
3675    ///
3676    ///     transform.update_t_r(&position, &rotation);
3677    ///
3678    ///     mesh.draw(token, &material, transform, None, None);
3679    ///     assert_eq!(transform, Matrix::t_r(position, rotation));
3680    /// );
3681    #[inline]
3682    pub fn update_t_r(&mut self, translation: &Vec3, rotation: &Quat) {
3683        unsafe { matrix_trs_out(self, translation, rotation, &Vec3::ONE) }
3684    }
3685
3686    /// Translate, Scale. Creates a transform Matrix using these components!
3687    /// <https://stereokit.net/Pages/StereoKit/Matrix/TS.html>
3688    /// * `translation` - Move an object by this amount.
3689    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is the default.
3690    ///
3691    /// Returns a Matrix that combines translation and rotation information into a single Matrix!
3692    /// see also [`matrix_ts`]
3693    #[deprecated(since = "0.40.0", note = "please use Matrix::t_s or Matrix::update_t_s")]
3694    #[inline]
3695    pub fn ts<V: Into<Vec3>>(translation: V, scale: V) -> Self {
3696        unsafe { matrix_ts(translation.into(), scale.into()) }
3697    }
3698
3699    /// Translate, Scale. Creates a transform Matrix using these components! Consider using
3700    /// [`Matrix::update_t_s`] when you have to recalculate Matrix at each steps in main loop.
3701    /// <https://stereokit.net/Pages/StereoKit/Matrix/TS.html>
3702    /// * `translation` - Move an object by this amount.
3703    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is the default.
3704    ///
3705    /// Returns a Matrix that combines translation and rotation information into a single Matrix!
3706    /// see also [`matrix_ts`] [`Matrix::update_t_s`]
3707    /// ### Examples
3708    /// ```
3709    /// use stereokit_rust::maths::{Vec3, Matrix};
3710    ///
3711    /// let transform = Matrix::t_s([1.0, 2.0, 3.0], [2.0, 2.0, 2.0]);
3712    /// let point = Vec3::new(1.0, 1.0, 1.0);
3713    /// let transformed_point = transform * point;
3714    /// assert_eq!(transformed_point, Vec3::new(3.0, 4.0, 5.0));
3715    /// ```
3716    #[inline]
3717    pub fn t_s<V: Into<Vec3>>(translation: V, scale: V) -> Self {
3718        unsafe { matrix_ts(translation.into(), scale.into()) }
3719    }
3720
3721    /// Translate, Scale. Creates a transform Matrix using these components!
3722    /// <https://stereokit.net/Pages/StereoKit/Matrix/TS.html>
3723    /// * `translation` - Move an object by this amount.
3724    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is the default.
3725    ///
3726    /// Returns a Matrix that combines translation and rotation information into a single Matrix!
3727    /// see also [`matrix_trs_out`] [`Matrix::t_s`]
3728    /// ### Examples
3729    /// ```
3730    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
3731    /// use stereokit_rust::{maths::{Vec3, Quat, Matrix}, mesh::Mesh, material::Material,
3732    ///                      util::Time};
3733    ///
3734    /// let mesh = Mesh::cube();
3735    /// let material = Material::pbr();
3736    ///
3737    /// let mut transform = Matrix::IDENTITY;
3738    /// let mut position = Vec3::ZERO;
3739    /// let mut delta_scale = 2.0;
3740    ///
3741    /// test_steps!( // !!!! Get a proper main loop !!!!
3742    ///     position += Vec3::NEG_Z * Time::get_stepf();
3743    ///     let scale = Vec3::ONE * (delta_scale * Time::get_stepf()).cos();
3744    ///
3745    ///     transform.update_t_s(&position, &scale);
3746    ///
3747    ///     mesh.draw(token, &material, transform, None, None);
3748    ///     assert_eq!(transform, Matrix::t_s(position, scale));
3749    /// );
3750    /// ```
3751    #[inline]
3752    pub fn update_t_s(&mut self, translation: &Vec3, scale: &Vec3) {
3753        unsafe { matrix_trs_out(self, translation, &Quat::IDENTITY, scale) }
3754    }
3755
3756    /// Translate, Rotate, Scale. Creates a transform Matrix using all these components!
3757    /// <https://stereokit.net/Pages/StereoKit/Matrix/TRS.html>
3758    /// * `translation` - Move an object by this amount.
3759    /// * `rotation` - The quaternion describing the rotation for this transform.
3760    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is a good default.
3761    ///
3762    /// Returns a Matrix that combines translation, rotation and scale information into a single Matrix!
3763    /// see also [`matrix_trs`]
3764    #[deprecated(since = "0.40.0", note = "please use Matrix::t_r_s or Matrix::update_t_r_s")]
3765    #[inline]
3766    pub fn trs(translation: &Vec3, rotation: &Quat, scale: &Vec3) -> Self {
3767        unsafe { matrix_trs(translation, rotation, scale) }
3768    }
3769
3770    /// Translate, Rotate, Scale. Creates a transform Matrix using all these components! Consider using
3771    /// [`Matrix::update_t_r_s`] when you have to recalculate Matrix at each steps in main loop.
3772    /// <https://stereokit.net/Pages/StereoKit/Matrix/TRS.html>
3773    /// * `translation` - Move an object by this amount.
3774    /// * `rotation` - The quaternion describing the rotation for this transform.
3775    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is a good default.
3776    ///
3777    /// Returns a Matrix that combines translation, rotation and scale information into a single Matrix!
3778    /// see also [`matrix_trs`] [`Matrix::update_t_r_s`]
3779    /// ### Examples
3780    /// ```
3781    /// use stereokit_rust::maths::{Vec3, Matrix};
3782    ///
3783    /// let transform = Matrix::t_r_s([1.0, 2.0, 3.0], [0.0, 180.0, 0.0], [2.0, 2.0, 2.0]);
3784    /// let point = Vec3::new(1.0, 1.0, 1.0);
3785    /// let transformed_point = transform * point;
3786    /// assert_eq!(transformed_point, Vec3::new(-1.0, 4.0, 1.0));
3787    /// ```
3788    #[inline]
3789    pub fn t_r_s<V: Into<Vec3>, Q: Into<Quat>>(translation: V, rotation: Q, scale: V) -> Self {
3790        unsafe { matrix_trs(&translation.into(), &rotation.into(), &scale.into()) }
3791    }
3792
3793    /// Translate, Rotate, Scale. Creates a transform Matrix using all these components!
3794    /// <https://stereokit.net/Pages/StereoKit/Matrix/TRS.html>
3795    /// * `translation` - Move an object by this amount.
3796    /// * `rotation` - The quaternion describing the rotation for this transform.
3797    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is a good default.
3798    ///
3799    /// Returns a Matrix that combines translation, rotation and scale information into a single Matrix!
3800    /// see also [`matrix_trs_out`] [`Matrix::t_r_s`]
3801    /// ### Examples
3802    /// ```
3803    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
3804    /// use stereokit_rust::{maths::{Vec3, Quat, Matrix}, mesh::Mesh, material::Material,
3805    ///                      util::Time};
3806    ///
3807    /// let mesh = Mesh::cube();
3808    /// let material = Material::pbr();
3809    ///
3810    /// let mut transform = Matrix::IDENTITY;
3811    /// let mut position = Vec3::ZERO;
3812    /// let mut delta_scale = 2.0;
3813    /// let mut delta_rotate = 90.0;
3814    ///
3815    /// test_steps!( // !!!! Get a proper main loop !!!!
3816    ///     position += Vec3::NEG_Z * Time::get_stepf();
3817    ///     delta_rotate = (delta_rotate + 10.0  * Time::get_stepf()) % 360.0;
3818    ///     let rotation = Quat::from_angles(0.0, delta_rotate, 0.0);
3819    ///     let scale = Vec3::ONE * (delta_scale * Time::get_stepf()).cos();
3820    ///
3821    ///     transform.update_t_r_s(&position, &rotation, &scale);
3822    ///
3823    ///     mesh.draw(token, &material, transform, None, None);
3824    ///     assert_eq!(transform, Matrix::t_r_s(position, rotation, scale));
3825    /// );
3826    /// ```
3827    #[inline]
3828    pub fn update_t_r_s(&mut self, translation: &Vec3, rotation: &Quat, scale: &Vec3) {
3829        unsafe { matrix_trs_out(self, translation, rotation, scale) }
3830    }
3831
3832    /// Translate, Rotate, Scale. Update a transform Matrix using all these components!
3833    /// <https://stereokit.net/Pages/StereoKit/Matrix/TRS.html>
3834    /// * `translation` - Move an object by this amount.
3835    /// * `rotation` - The quaternion describing the rotation for this transform.
3836    /// * `scale` - How much larger or smaller this transform makes things. Vec3::ONE is a good default.
3837    ///
3838    /// see also [`matrix_trs_out`]
3839    #[deprecated(since = "0.40.0", note = "please use Matrix::update_t_r, Matrix::update_t_s or Matrix::update_t_r_s")]
3840    #[inline]
3841    #[allow(clippy::not_unsafe_ptr_arg_deref)]
3842    pub fn trs_to_pointer(translation: &Vec3, rotation: &Quat, scale: &Vec3, out_result: *mut Matrix) {
3843        unsafe { matrix_trs_out(out_result, translation, rotation, scale) }
3844    }
3845
3846    /// Inverts this Matrix! If the matrix takes a point from a -> b, then its inverse takes the point from b -> a.
3847    /// The Matrix is modified so use get_inverse* for performance gains
3848    /// <https://stereokit.net/Pages/StereoKit/Matrix/Invert.html>
3849    ///
3850    /// see also [`Matrix::get_inverse`] [`matrix_invert`]
3851    /// ### Examples
3852    /// ```
3853    /// use stereokit_rust::maths::{Vec3, Matrix};
3854    ///
3855    /// let mut transform = Matrix::t([1.0, 2.0, 3.0]);
3856    /// transform.invert();
3857    /// let point = Vec3::new(1.0, 2.0, 3.0);
3858    /// let transformed_point = transform * point;
3859    /// assert_eq!(transformed_point, Vec3::new(0.0, 0.0, 0.0));
3860    /// ```
3861    #[inline]
3862    pub fn invert(&mut self) -> &mut Self {
3863        let m = unsafe { matrix_invert(self) };
3864        unsafe {
3865            self.row[0] = m.row[0];
3866            self.row[1] = m.row[1];
3867            self.row[2] = m.row[2];
3868            self.row[3] = m.row[3];
3869        }
3870        self
3871    }
3872
3873    /// Transposes this Matrix! Transposing is like rotating the matrix 90 clockwise, or turning the rows into columns.
3874    /// This can be useful for inverting orthogonal matrices, or converting matrices for use in a math library that
3875    /// uses different conventions! The Matrix is modified so use get_transposed* for performance gains
3876    /// <https://stereokit.net/Pages/StereoKit/Matrix/Transpose.html>
3877    ///
3878    /// see also [`matrix_transpose`]
3879    /// ### Examples
3880    /// ```
3881    /// use stereokit_rust::maths::{Vec3, Matrix};
3882    ///
3883    /// let mut transform = Matrix::t([1.0, 2.0, 3.0]);
3884    /// assert_eq!(transform, Matrix::from([
3885    ///     1.0, 0.0, 0.0, 0.0,
3886    ///     0.0, 1.0, 0.0, 0.0,
3887    ///     0.0, 0.0, 1.0, 0.0,
3888    ///     1.0, 2.0, 3.0, 1.0,
3889    /// ]));
3890    ///
3891    /// transform.transpose();
3892    /// assert_eq!(transform, Matrix::from([
3893    ///     1.0, 0.0, 0.0, 1.0,
3894    ///     0.0, 1.0, 0.0, 2.0,
3895    ///     0.0, 0.0, 1.0, 3.0,
3896    ///     0.0, 0.0, 0.0, 1.0,
3897    /// ]));
3898    /// ```
3899    #[inline]
3900    pub fn transpose(&mut self) -> &mut Self {
3901        let m = unsafe { matrix_transpose(*self) };
3902        unsafe {
3903            self.row[0] = m.row[0];
3904            self.row[1] = m.row[1];
3905            self.row[2] = m.row[2];
3906            self.row[3] = m.row[3];
3907        }
3908        self
3909    }
3910
3911    /// Returns this transformation matrix to its original translation, rotation and scale components. Not exactly a
3912    /// cheap function. If this is not a transform matrix, there’s a chance this call will fail, and return false.
3913    /// <https://stereokit.net/Pages/StereoKit/Matrix/Decompose.html>
3914    /// Returns the tuple (position:Vec3, scale:Vec3, orientation:QuatT)
3915    ///
3916    /// see also [`matrix_decompose`] [`Matrix::decompose_to_ptr`]
3917    /// ### Examples
3918    /// ```
3919    /// use stereokit_rust::maths::{Matrix, Vec3, Quat};
3920    ///
3921    /// let position = Vec3::new(1.0, 2.0, 3.0);
3922    /// let orientation = Quat::from_angles(0.0, 90.0, 0.0);
3923    /// let scale = Vec3::new(2.0, 2.0, 2.0);
3924    /// let matrix = Matrix::t_r_s(position, orientation, scale);
3925    ///
3926    /// let (pos, sca, ori) = matrix.decompose().unwrap();
3927    /// assert_eq!(pos, position);
3928    /// assert_eq!(sca, scale);
3929    /// assert_eq!(ori, orientation);
3930    /// ```
3931    #[inline]
3932    pub fn decompose(&self) -> Option<(Vec3, Vec3, Quat)> {
3933        let position: *mut Vec3 = &mut Vec3 { x: 0.0, y: 0.0, z: 0.0 };
3934        let scale: *mut Vec3 = &mut Vec3 { x: 0.0, y: 0.0, z: 0.0 };
3935        let orientation: *mut Quat = &mut Quat { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
3936        match unsafe { matrix_decompose(self, position, scale, orientation) } {
3937            0 => None,
3938            _ => unsafe { Some((*position, *scale, *orientation)) },
3939        }
3940    }
3941
3942    /// Returns this transformation matrix to its original translation, rotation and scale components. Not exactly a
3943    /// cheap function. If this is not a transform matrix, there’s a chance this call will fail, and return false.
3944    /// <https://stereokit.net/Pages/StereoKit/Matrix/Decompose.html>
3945    /// * `out_position` - The translation component of the matrix.
3946    /// * `out_orientation` - The rotation component of the matrix, some lossiness may be encountered when
3947    ///   composing/decomposing.
3948    /// * `out_scale` - The scale component of the matrix.
3949    ///
3950    /// see also [`matrix_decompose`]
3951    /// ### Examples
3952    /// ```
3953    /// use stereokit_rust::maths::{Matrix, Vec3, Quat};
3954    ///
3955    /// let position = Vec3::new(1.0, 2.0, 3.0);
3956    /// let orientation = Quat::from_angles(0.0, 90.0, 0.0);
3957    /// let scale = Vec3::new(2.0, 2.0, 2.0);
3958    /// let matrix = Matrix::t_r_s(position, orientation, scale);
3959    ///
3960    /// let mut pos = Vec3::ZERO;
3961    /// let mut sca = Vec3::ZERO;
3962    /// let mut ori = Quat::ZERO;
3963    ///
3964    /// matrix.decompose_to_ptr(&mut pos, &mut ori, &mut sca);
3965    /// assert_eq!(pos, position);
3966    /// assert_eq!(sca, scale);
3967    /// assert_eq!(ori, orientation);
3968    /// ```
3969    #[inline]
3970    pub fn decompose_to_ptr(&self, out_position: &mut Vec3, out_orientation: &mut Quat, out_scale: &mut Vec3) -> bool {
3971        unsafe { matrix_decompose(self, out_position, out_scale, out_orientation) != 0 }
3972    }
3973
3974    /// Transforms a point through the Matrix! This is basically just multiplying a vector (x,y,z,1) with the Matrix.
3975    /// <https://stereokit.net/Pages/StereoKit/Matrix/Transform.html>
3976    /// * `point` - The point to transform.
3977    ///
3978    /// Returns the point transformed by the Matrix.
3979    /// see also the '*' operator [`matrix_transform_pt`]
3980    /// ### Examples
3981    /// ```
3982    /// use stereokit_rust::maths::{Vec3, Matrix};
3983    ///
3984    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
3985    /// let point = Vec3::new(1.0, 1.0, 1.0);
3986    /// let transformed_point = transform.transform_point(point);
3987    /// assert_eq!(transformed_point, Vec3::new(2.0, 3.0, 4.0));
3988    ///
3989    /// let transformed_point_b = transform * point;
3990    /// assert_eq!(transformed_point_b, transformed_point);
3991    /// ```
3992    #[inline]
3993    pub fn transform_point<V: Into<Vec3>>(&self, point: V) -> Vec3 {
3994        unsafe { matrix_transform_pt(*self, point.into()) }
3995    }
3996
3997    /// Shorthand to transform a ray though the Matrix! This properly transforms the position with the point transform
3998    /// method, and the direction with the direction transform method. Does not normalize, nor does it preserve a
3999    /// normalized direction if the Matrix contains scale data.
4000    /// <https://stereokit.net/Pages/StereoKit/Matrix/Transform.html>
4001    /// * `ray` - A ray you wish to transform from one space to another.
4002    ///
4003    /// Returns the Ray transformed by the Matrix.
4004    /// see also the `*` operator [`matrix_transform_ray`]
4005    /// ### Examples
4006    /// ```
4007    /// use stereokit_rust::maths::{Vec3, Matrix, Ray};
4008    ///
4009    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4010    /// let ray = Ray::new([0.0, 0.0, 0.0], [1.0, 0.0, 0.0]);
4011    /// let transformed_ray = transform.transform_ray(ray);
4012    /// assert_eq!(transformed_ray, Ray::new([1.0, 2.0, 3.0], [1.0, 0.0, 0.0]));
4013    ///
4014    /// let transformed_ray_b = transform * ray;
4015    /// assert_eq!(transformed_ray_b, transformed_ray);
4016    /// ```
4017    #[inline]
4018    pub fn transform_ray<R: Into<Ray>>(&self, ray: R) -> Ray {
4019        unsafe { matrix_transform_ray(*self, ray.into()) }
4020    }
4021
4022    /// Shorthand for transforming a Pose! This will transform the position of the Pose with the matrix, extract a
4023    /// rotation Quat from the matrix and apply that to the Pose’s orientation. Note that extracting a rotation Quat
4024    /// is an expensive operation, so if you’re doing it more than once, you should cache the rotation Quat and do this
4025    /// transform manually.
4026    /// <https://stereokit.net/Pages/StereoKit/Matrix/Transform.html>
4027    /// * `pose` - The original pose.
4028    ///
4029    /// Returns the transformed pose.
4030    /// see also the `*` operator [`matrix_transform_pose`]
4031    /// ### Examples
4032    /// ```
4033    /// use stereokit_rust::maths::{Pose, Vec3, Matrix};
4034    ///
4035    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4036    /// let pose = Pose::new([0.0, 0.0, 0.0], None);
4037    /// let transformed_pose = transform.transform_pose(pose);
4038    /// assert_eq!(transformed_pose, Pose::new([1.0, 2.0, 3.0], None));
4039    ///
4040    /// let transformed_pose_b = transform * pose;
4041    /// assert_eq!(transformed_pose_b, transformed_pose);
4042    /// ```
4043    #[inline]
4044    pub fn transform_pose<P: Into<Pose>>(&self, pose: P) -> Pose {
4045        unsafe { matrix_transform_pose(*self, pose.into()) }
4046    }
4047
4048    /// Shorthand for transforming a rotation! This will extract a rotation Quat from the matrix and apply that to the
4049    /// QuatT's orientation. Note that extracting a rotation Quat is an expensive operation, so if you’re doing it more
4050    /// than once, you should cache the rotation Quat and do this transform manually.
4051    /// <https://stereokit.net/Pages/StereoKit/Matrix/Transform.html>
4052    /// * `rotation` - The original rotation
4053    ///
4054    /// Return the transformed quat.
4055    /// see also the `*` operator [`matrix_transform_quat`]
4056    /// ### Examples
4057    /// ```
4058    /// use stereokit_rust::maths::{Quat, Matrix};
4059    ///
4060    /// let transform = Matrix::r([0.0, 90.0, 0.0]);
4061    /// let rotation = Quat::from_angles(0.0, 90.0, 0.0);
4062    /// let transformed_rotation = transform.transform_quat(rotation);
4063    /// assert_eq!(transformed_rotation, Quat::from_angles(0.0, 180.0, 0.0));
4064    ///
4065    /// let transformed_rotation_b = transform * rotation;
4066    /// assert_eq!(transformed_rotation_b, transformed_rotation);
4067    /// ```
4068    #[inline]
4069    pub fn transform_quat<Q: Into<Quat>>(&self, rotation: Q) -> Quat {
4070        unsafe { matrix_transform_quat(*self, rotation.into()) }
4071    }
4072
4073    /// Transforms a point through the Matrix, but excluding translation! This is great for transforming vectors that
4074    /// are -directions- rather than points in space. Use this to transform normals and directions. The same as
4075    /// multiplying (x,y,z,0) with the Matrix. Do not correspond to `*` operator !
4076    /// <https://stereokit.net/Pages/StereoKit/Matrix/TransformNormal.html>
4077    /// * `normal` - A direction vector to be transformed.
4078    ///
4079    /// Returns the direction transformed by the Matrix.
4080    /// see also [`matrix_transform_dir`]
4081    /// ### Examples
4082    /// ```
4083    /// use stereokit_rust::maths::{Vec3, Matrix};
4084    ///
4085    /// let transform = Matrix::r([0.0, 90.0, 0.0]);
4086    /// let normal = Vec3::new(1.0, 0.0, 0.0);
4087    /// let transformed_normal = transform.transform_normal(normal);
4088    /// assert_eq!(transformed_normal, Vec3::new(0.0, 0.0, -1.0));
4089    /// ```
4090    #[inline]
4091    pub fn transform_normal<V: Into<Vec3>>(&self, normal: V) -> Vec3 {
4092        unsafe { matrix_transform_dir(*self, normal.into()) }
4093    }
4094
4095    /// Creates an inverse matrix! If the matrix takes a point from a -> b, then its inverse takes the point
4096    /// from b -> a.
4097    /// <https://stereokit.net/Pages/StereoKit/Matrix/Inverse.html>
4098    ///
4099    /// see also [`matrix_inverse`]
4100    /// ### Examples
4101    /// ```
4102    /// use stereokit_rust::maths::{Vec3, Matrix};
4103    ///
4104    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4105    /// let inverse = transform.get_inverse();
4106    /// let point = Vec3::new(1.0, 2.0, 3.0);
4107    /// let transformed_point = inverse * point;
4108    /// assert_eq!(transformed_point, Vec3::new(0.0, 0.0, 0.0));
4109    /// ```
4110    #[inline]
4111    pub fn get_inverse(&self) -> Self {
4112        let out: *mut Matrix = &mut Matrix { row: [Vec4::ZERO, Vec4::ZERO, Vec4::ZERO, Vec4::ZERO] };
4113        unsafe {
4114            matrix_inverse(self, out);
4115            *out
4116        }
4117    }
4118
4119    /// Creates an inverse matrix! If the matrix takes a point from a -> b, then its inverse takes the point
4120    /// from b -> a.
4121    /// <https://stereokit.net/Pages/StereoKit/Matrix/Inverse.html>
4122    /// * `out` - The output matrix.
4123    ///
4124    /// see also [`matrix_inverse`]
4125    /// ### Examples
4126    /// ```
4127    /// use stereokit_rust::maths::{Vec3, Matrix};
4128    ///
4129    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4130    /// let mut inverse = Matrix::NULL;
4131    ///
4132    /// transform.get_inverse_to_ptr(&mut inverse);
4133    /// let point = Vec3::new(1.0, 2.0, 3.0);
4134    /// let transformed_point = inverse * point;
4135    /// assert_eq!(transformed_point, Vec3::new(0.0, 0.0, 0.0));
4136    /// ```
4137    #[inline]
4138    pub fn get_inverse_to_ptr(&self, out: &mut Matrix) {
4139        unsafe {
4140            matrix_inverse(self, out);
4141        }
4142    }
4143
4144    /// Extracts translation and rotation information from the transform matrix, and makes a Pose from it! Not exactly
4145    /// fast. This is backed by Decompose, so if you need any additional info, it’s better to just call Decompose instead.
4146    /// <https://stereokit.net/Pages/StereoKit/Matrix/Pose.html>
4147    ///
4148    /// see also [`matrix_extract_pose`]
4149    /// ### Examples
4150    /// ```
4151    /// use stereokit_rust::maths::{Vec3, Quat, Matrix, Pose};
4152    ///
4153    /// let matrix = Matrix::t_r(Vec3::new(1.0, 2.0, 3.0), [0.0, 0.0, 0.0]);
4154    ///
4155    /// let pose = matrix.get_pose();
4156    /// assert_eq!(pose.position, Vec3::new(1.0, 2.0, 3.0));
4157    /// assert_eq!(pose.orientation, Quat::IDENTITY)
4158    /// ```
4159    #[inline]
4160    pub fn get_pose(&self) -> Pose {
4161        unsafe { matrix_extract_pose(self) }
4162    }
4163
4164    /// A slow function that returns the rotation quaternion embedded in this transform matrix. This is backed by
4165    /// Decompose, so if you need any additional info, it’s better to just call Decompose instead.
4166    /// <https://stereokit.net/Pages/StereoKit/Matrix/Rotation.html>
4167    ///
4168    /// see also [`matrix_extract_rotation`]
4169    /// ### Examples
4170    /// ```
4171    /// use stereokit_rust::maths::{Vec3, Quat, Matrix};
4172    ///
4173    /// let matrix = Matrix::t_r(Vec3::new(1.0, 2.0, 3.0), [0.0, 90.0, 0.0]);
4174    ///
4175    /// let rotation = matrix.get_rotation();
4176    /// assert_eq!(rotation, Quat::from_angles(0.0, 90.0, 0.0))
4177    /// ```
4178    #[inline]
4179    pub fn get_rotation(&self) -> Quat {
4180        unsafe { matrix_extract_rotation(self) }
4181    }
4182
4183    /// Returns the scale embedded in this transform matrix. Not exactly cheap, requires 3 sqrt calls, but is cheaper
4184    /// than calling Decompose.
4185    /// <https://stereokit.net/Pages/StereoKit/Matrix/Scale.html>
4186    ///
4187    /// see also [`matrix_extract_scale`]
4188    /// ### Examples
4189    /// ```
4190    /// use stereokit_rust::maths::{Vec3, Matrix};
4191    ///
4192    /// let matrix = Matrix::t_s(Vec3::new(1.0, 2.0, 3.0), Vec3::new(2.0, 2.0, 2.0));
4193    ///
4194    /// let scale = matrix.get_scale();
4195    /// assert_eq!(scale, Vec3::new(2.0, 2.0, 2.0))
4196    /// ```
4197    #[inline]
4198    pub fn get_scale(&self) -> Vec3 {
4199        unsafe { matrix_extract_scale(self) }
4200    }
4201
4202    /// A fast getter that will return or set the translation component embedded in this transform matrix.
4203    /// <https://stereokit.net/Pages/StereoKit/Matrix/Translation.html>
4204    ///
4205    /// see also [`matrix_extract_translation`]
4206    /// ### Examples
4207    /// ```
4208    /// use stereokit_rust::maths::{Vec3, Matrix};
4209    ///
4210    /// let transform = Matrix::r([0.0, 90.0, 0.0]);
4211    /// let normal = Vec3::new(1.0, 0.0, 0.0);
4212    ///
4213    /// let transformed_normal = transform.transform_normal(normal);
4214    /// assert_eq!(transformed_normal, Vec3::new(0.0, 0.0, -1.0));
4215    /// ```
4216    #[inline]
4217    pub fn get_translation(&self) -> Vec3 {
4218        unsafe { matrix_extract_translation(self) }
4219    }
4220
4221    /// Creates a matrix that has been transposed! Transposing is like rotating the matrix 90 clockwise, or turning
4222    /// the rows into columns. This can be useful for inverting orthogonal matrices, or converting matrices for use
4223    /// in a math library that uses different conventions!
4224    /// <https://stereokit.net/Pages/StereoKit/Matrix/Transposed.html>
4225    ///
4226    /// see also [`matrix_transpose`]
4227    /// ### Examples
4228    /// ```
4229    /// use stereokit_rust::maths::{Vec3, Matrix};
4230    ///
4231    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4232    /// assert_eq!(transform, Matrix::from([
4233    ///     1.0, 0.0, 0.0, 0.0,
4234    ///     0.0, 1.0, 0.0, 0.0,
4235    ///     0.0, 0.0, 1.0, 0.0,
4236    ///     1.0, 2.0, 3.0, 1.0,
4237    /// ]));
4238    ///
4239    /// let transposed = transform.get_transposed();
4240    /// assert_eq!(transposed, Matrix::from([
4241    ///     1.0, 0.0, 0.0, 1.0,
4242    ///     0.0, 1.0, 0.0, 2.0,
4243    ///     0.0, 0.0, 1.0, 3.0,
4244    ///     0.0, 0.0, 0.0, 1.0,
4245    /// ]));
4246    /// ```
4247    #[inline]
4248    pub fn get_transposed(&self) -> Self {
4249        unsafe { matrix_transpose(*self) }
4250    }
4251}
4252
4253impl Display for Matrix {
4254    /// Mostly for debug purposes, this is a decent way to log or inspect the matrix in debug mode. Looks
4255    /// like “[, , , ]”
4256    ///
4257    /// ### Examples
4258    /// ```
4259    /// use stereokit_rust::maths::Matrix;
4260    ///
4261    /// let matrix = Matrix::from([
4262    ///     1.0, 2.0, 3.3, 4.0,
4263    ///     5.0, 6.0, 7.0, 8.0,
4264    ///     9.0, 10.0, 11.0, 12.0,
4265    ///     13.0, 14.0, 15.0, 16.0,
4266    /// ]);
4267    /// assert_eq!(format!("{}", matrix),
4268    /// "[\r\n [x:1, y:2, z:3.3, w:4],\r\n [x:5, y:6, z:7, w:8],\r\n [x:9, y:10, z:11, w:12],\r\n [x:13, y:14, z:15, w:16]]");
4269    /// ```
4270    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4271        unsafe { write!(f, "[\r\n {},\r\n {},\r\n {},\r\n {}]", self.row[0], self.row[1], self.row[2], self.row[3]) }
4272    }
4273}
4274/// Multiplies the vector by the Matrix! Since only a 1x4 vector can be multiplied against a 4x4 matrix, this uses ‘1’
4275/// for the 4th element, so the result will also include translation! To exclude translation,
4276/// use Matrix.transform_normal.
4277/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4278///
4279/// see also [`matrix_transform_pt`]
4280impl Mul<Vec3> for Matrix {
4281    type Output = Vec3;
4282
4283    /// ### Examples
4284    /// ```
4285    /// use stereokit_rust::maths::{Vec3, Matrix};
4286    ///
4287    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4288    /// let point = Vec3::new(1.0, 1.0, 1.0);
4289    ///
4290    /// let transformed_point = transform * point;
4291    /// assert_eq!(transformed_point, Vec3::new(2.0, 3.0, 4.0));
4292    /// ```
4293    fn mul(self, rhs: Vec3) -> Self::Output {
4294        unsafe { matrix_transform_pt(self, rhs) }
4295    }
4296}
4297
4298/// Multiplies the vector by the Matrix! Since only a 1x4 vector can be multiplied against a 4x4 matrix, this uses ‘1’
4299/// for the 4th element, so the result will also include translation! To exclude translation,
4300/// use Matrix.transform_normal.
4301/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4302///
4303/// see also [`matrix_transform_pt`]
4304impl MulAssign<Matrix> for Vec3 {
4305    /// ### Examples
4306    /// ```
4307    /// use stereokit_rust::maths::{Vec3, Matrix};
4308    ///
4309    /// let mut point = Vec3::new(1.0, 1.0, 1.0);
4310    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4311    ///
4312    /// point *= transform;
4313    /// assert_eq!(point, Vec3::new(2.0, 3.0, 4.0));
4314    /// ```
4315    fn mul_assign(&mut self, rhs: Matrix) {
4316        let res = unsafe { matrix_transform_pt(rhs, *self) };
4317        self.x = res.x;
4318        self.y = res.y;
4319        self.z = res.z;
4320    }
4321}
4322
4323/// Multiplies the vector by the Matrix! Since only a 1x4 vector can be multiplied against a 4x4 matrix, this uses ‘1’
4324/// for the 4th element, so the result will also include translation! To exclude translation,
4325/// use Matrix.transform_normal.
4326/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4327///
4328/// see also [`matrix_transform_pt`]
4329impl Mul<Matrix> for Vec3 {
4330    type Output = Vec3;
4331
4332    /// ### Examples
4333    /// ```
4334    /// use stereokit_rust::maths::{Vec3, Matrix};
4335    ///
4336    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4337    /// let point = Vec3::new(1.0, 1.0, 1.0);
4338    ///
4339    /// let transformed_point = point * transform;
4340    /// assert_eq!(transformed_point, Vec3::new(2.0, 3.0, 4.0));
4341    /// ```
4342    fn mul(self, rhs: Matrix) -> Self::Output {
4343        unsafe { matrix_transform_pt(rhs, self) }
4344    }
4345}
4346
4347/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4348///
4349/// see also [`matrix_transform_pt4`]
4350impl Mul<Vec4> for Matrix {
4351    type Output = Vec4;
4352
4353    /// ### Examples
4354    /// ```
4355    /// use stereokit_rust::maths::{Vec4, Matrix};
4356    ///
4357    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4358    /// let v4 = Vec4::new(1.0, 1.0, 1.0, 1.0);
4359    ///
4360    /// let transformed_v4 = transform * v4;
4361    /// assert_eq!(transformed_v4, Vec4::new(2.0, 3.0, 4.0, 1.0));
4362    /// ```
4363    fn mul(self, rhs: Vec4) -> Self::Output {
4364        unsafe { matrix_transform_pt4(self, rhs) }
4365    }
4366}
4367
4368/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4369///
4370/// see also [`matrix_transform_pt4`]
4371impl MulAssign<Matrix> for Vec4 {
4372    /// ### Examples
4373    /// ```
4374    /// use stereokit_rust::maths::{Vec4, Matrix};
4375    ///
4376    /// let mut v4 = Vec4::new(1.0, 1.0, 1.0, 1.0);
4377    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4378    ///
4379    /// v4 *= transform;
4380    /// assert_eq!(v4, Vec4::new(2.0, 3.0, 4.0, 1.0));
4381    /// ```
4382    fn mul_assign(&mut self, rhs: Matrix) {
4383        let res = unsafe { matrix_transform_pt4(rhs, *self) };
4384        self.x = res.x;
4385        self.y = res.y;
4386        self.z = res.z;
4387        self.w = res.w
4388    }
4389}
4390
4391/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4392///
4393/// see also [`matrix_transform_pt4`]
4394impl Mul<Matrix> for Vec4 {
4395    type Output = Vec4;
4396
4397    /// ### Examples
4398    /// ```
4399    /// use stereokit_rust::maths::{Vec4, Matrix};
4400    ///
4401    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4402    /// let v4 = Vec4::new(1.0, 1.0, 1.0, 1.0);
4403    ///
4404    /// let transformed_v4 = v4 * transform;
4405    /// assert_eq!(transformed_v4, Vec4::new(2.0, 3.0, 4.0, 1.0));
4406    /// ```
4407    fn mul(self, rhs: Matrix) -> Self::Output {
4408        unsafe { matrix_transform_pt4(rhs, self) }
4409    }
4410}
4411
4412/// Transforms a Ray by the Matrix! The position and direction are both multiplied by the matrix, accounting properly for
4413/// which should include translation, and which should not.
4414/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4415///
4416/// see also [`matrix_transform_ray`]
4417impl Mul<Ray> for Matrix {
4418    type Output = Ray;
4419
4420    /// ### Examples
4421    /// ```
4422    /// use stereokit_rust::maths::{Vec3, Matrix, Ray};
4423    ///
4424    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4425    /// let ray = Ray::new([0.0, 0.0, 0.0], [1.0, 0.0, 0.0]);
4426    ///
4427    /// let transformed_ray = transform * ray;
4428    /// assert_eq!(transformed_ray, Ray::new([1.0, 2.0, 3.0], [1.0, 0.0, 0.0]));
4429    /// ```
4430    fn mul(self, rhs: Ray) -> Self::Output {
4431        unsafe { matrix_transform_ray(self, rhs) }
4432    }
4433}
4434
4435/// Transforms a Ray by the Matrix! The position and direction are both multiplied by the matrix, accounting properly for
4436/// which should include translation, and which should not.
4437/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4438///
4439/// see also [`matrix_transform_ray`]
4440impl MulAssign<Matrix> for Ray {
4441    /// ```
4442    /// use stereokit_rust::maths::{Vec3, Matrix, Ray};
4443    ///
4444    /// let mut ray = Ray::new([0.0, 0.0, 0.0], [1.0, 0.0, 0.0]);
4445    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4446    ///
4447    /// ray *= transform;
4448    /// assert_eq!(ray, Ray::new([1.0, 2.0, 3.0], [1.0, 0.0, 0.0]));
4449    /// ```
4450    fn mul_assign(&mut self, rhs: Matrix) {
4451        let res = unsafe { matrix_transform_ray(rhs, *self) };
4452        self.position = res.position;
4453        self.direction = res.direction;
4454    }
4455}
4456
4457/// Transforms a Ray by the Matrix! The position and direction are both multiplied by the matrix, accounting properly for
4458/// which should include translation, and which should not.
4459/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4460///
4461/// see also [`matrix_transform_ray`]
4462impl Mul<Matrix> for Ray {
4463    type Output = Ray;
4464
4465    /// ### Examples
4466    /// ```
4467    /// use stereokit_rust::maths::{Vec3, Matrix, Ray};
4468    ///
4469    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4470    /// let ray = Ray::new([0.0, 0.0, 0.0], [1.0, 0.0, 0.0]);
4471    ///
4472    /// let transformed_ray = ray * transform;
4473    /// assert_eq!(transformed_ray, Ray::new([1.0, 2.0, 3.0], [1.0, 0.0, 0.0]));
4474    /// ```
4475    fn mul(self, rhs: Matrix) -> Self::Output {
4476        unsafe { matrix_transform_ray(rhs, self) }
4477    }
4478}
4479
4480/// Transform an orientation by the Matrix.
4481/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4482///
4483/// see also [`matrix_transform_quat`]
4484impl Mul<Quat> for Matrix {
4485    type Output = Quat;
4486
4487    /// ### Examples
4488    /// ```
4489    /// use stereokit_rust::maths::{Quat, Matrix};
4490    ///
4491    /// let transform = Matrix::r([0.0, 90.0, 0.0]);
4492    /// let rotation = Quat::from_angles(0.0, 0.0, 0.0);
4493    ///
4494    /// let transformed_rotation = transform * rotation;
4495    /// assert_eq!(transformed_rotation, Quat::from_angles(0.0, 90.0, 0.0));
4496    /// ```
4497    fn mul(self, rhs: Quat) -> Self::Output {
4498        unsafe { matrix_transform_quat(self, rhs) }
4499    }
4500}
4501
4502/// Transform an orientation by the Matrix.
4503/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4504///
4505/// see also [`matrix_transform_quat`]
4506impl MulAssign<Matrix> for Quat {
4507    /// ### Examples
4508    /// ```
4509    /// use stereokit_rust::maths::{Quat, Matrix};
4510    ///
4511    /// let mut rotation = Quat::from_angles(0.0, 0.0, 0.0);
4512    /// let transform = Matrix::r([0.0, 90.0, 0.0]);
4513    ///
4514    /// rotation *= transform;
4515    /// assert_eq!(rotation, Quat::from_angles(0.0, 90.0, 0.0));
4516    /// ```
4517    fn mul_assign(&mut self, rhs: Matrix) {
4518        let res = unsafe { matrix_transform_quat(rhs, *self) };
4519        self.x = res.x;
4520        self.y = res.y;
4521        self.z = res.z;
4522        self.w = res.w
4523    }
4524}
4525
4526/// Transform an orientation by the Matrix.
4527/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4528///
4529/// see also [`matrix_transform_quat`]
4530impl Mul<Matrix> for Quat {
4531    type Output = Quat;
4532
4533    /// ### Examples
4534    /// ```
4535    /// use stereokit_rust::maths::{Quat, Matrix};
4536    ///
4537    /// let transform = Matrix::r([0.0, 90.0, 0.0]);
4538    /// let rotation = Quat::from_angles(0.0, 0.0, 0.0);
4539    ///
4540    /// let transformed_rotation = rotation * transform;
4541    /// assert_eq!(transformed_rotation, Quat::from_angles(0.0, 90.0, 0.0));
4542    /// ```
4543    fn mul(self, rhs: Matrix) -> Self::Output {
4544        unsafe { matrix_transform_quat(rhs, self) }
4545    }
4546}
4547
4548/// Transforms a Pose by the Matrix! The position and orientation are both transformed by the matrix, accounting
4549/// properly for the Pose’s quaternion.
4550/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4551///
4552/// see also [`matrix_transform_pose`]
4553impl Mul<Pose> for Matrix {
4554    type Output = Pose;
4555
4556    /// ### Examples
4557    /// ```
4558    /// use stereokit_rust::maths::{Pose, Vec3, Matrix};
4559    ///
4560    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4561    /// let pose = Pose::new([0.0, 0.0, 0.0], None);
4562    ///
4563    /// let transformed_pose = transform * pose;
4564    /// assert_eq!(transformed_pose, Pose::new([1.0, 2.0, 3.0], None));
4565    /// ```
4566    fn mul(self, rhs: Pose) -> Self::Output {
4567        unsafe { matrix_transform_pose(self, rhs) }
4568    }
4569}
4570
4571/// Transforms a Pose by the Matrix! The position and orientation are both transformed by the matrix, accounting
4572/// properly for the Pose’s quaternion.
4573/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4574///
4575/// see also [`matrix_transform_pose`]
4576impl MulAssign<Matrix> for Pose {
4577    /// ### Examples
4578    /// ```
4579    /// use stereokit_rust::maths::{Pose, Vec3, Matrix};
4580    ///
4581    /// let mut pose = Pose::new([0.0, 0.0, 0.0], None);
4582    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4583    ///
4584    /// pose *= transform;
4585    /// assert_eq!(pose, Pose::new([1.0, 2.0, 3.0], None));
4586    /// ```
4587    fn mul_assign(&mut self, rhs: Matrix) {
4588        let res = unsafe { matrix_transform_pose(rhs, *self) };
4589        self.position = res.position;
4590        self.orientation = res.orientation;
4591    }
4592}
4593
4594/// Transforms a Pose by the Matrix! The position and orientation are both transformed by the matrix, accounting
4595/// properly for the Pose’s quaternion.
4596/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4597///
4598/// see also [`matrix_transform_pose`]
4599impl Mul<Matrix> for Pose {
4600    type Output = Pose;
4601
4602    /// ### Examples
4603    /// ```
4604    /// use stereokit_rust::maths::{Pose, Vec3, Matrix};
4605    ///
4606    /// let transform = Matrix::t([1.0, 2.0, 3.0]);
4607    /// let pose = Pose::new([0.0, 0.0, 0.0], None);
4608    ///
4609    /// let transformed_pose = pose * transform;
4610    /// assert_eq!(transformed_pose, Pose::new([1.0, 2.0, 3.0], None));
4611    /// ```
4612    fn mul(self, rhs: Matrix) -> Self::Output {
4613        unsafe { matrix_transform_pose(rhs, self) }
4614    }
4615}
4616
4617/// Multiplies two matrices together! This is a great way to combine transform operations. Note that StereoKit’s
4618/// matrices are row-major, and multiplication order is important! To translate, then scale, multiply in order of
4619/// ‘translate * scale’.
4620/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4621///
4622/// see also [`matrix_mul`]
4623impl Mul<Matrix> for Matrix {
4624    type Output = Self;
4625
4626    /// ### Examples
4627    /// ```
4628    /// use stereokit_rust::maths::{Vec3, Matrix};
4629    ///
4630    /// let transform_a = Matrix::t([1.0, 2.0, 3.0]);
4631    /// let transform_b = Matrix::s([2.0, 2.0, 2.0]);
4632    ///
4633    /// let transform_c = transform_a * transform_b;
4634    /// let point = Vec3::new(1.0, 1.0, 1.0);
4635    /// let transformed_point = transform_c * point;
4636    /// assert_eq!(transformed_point, Vec3::new(4.0, 6.0, 8.0));
4637    /// ```
4638    fn mul(self, rhs: Matrix) -> Self::Output {
4639        let out: *mut Matrix = &mut Matrix { row: [Vec4::ZERO, Vec4::ZERO, Vec4::ZERO, Vec4::ZERO] };
4640        unsafe {
4641            matrix_mul(&self, &rhs, out);
4642            *out
4643        }
4644    }
4645}
4646
4647/// Multiplies two matrices together! This is a great way to combine transform operations. Note that StereoKit’s
4648/// matrices are row-major, and multiplication order is important! To translate, then scale, multiply in order of
4649/// ‘translate * scale’.
4650/// <https://stereokit.net/Pages/StereoKit/Matrix/op_Multiply.html>
4651///
4652/// see also [`matrix_mul`]
4653impl MulAssign<Matrix> for Matrix {
4654    /// ### Examples
4655    /// ```
4656    /// use stereokit_rust::maths::{Vec3, Matrix};
4657    ///
4658    /// let mut transform_a = Matrix::t([1.0, 2.0, 3.0]);
4659    /// let transform_b = Matrix::s([2.0, 2.0, 2.0]);
4660    ///
4661    /// transform_a *= transform_b;
4662    /// let point = Vec3::new(1.0, 1.0, 1.0);
4663    /// let transformed_point = transform_a * point;
4664    /// assert_eq!(transformed_point, Vec3::new(4.0, 6.0, 8.0));
4665    /// ```
4666    fn mul_assign(&mut self, rhs: Matrix) {
4667        unsafe { matrix_mul(self, &rhs, self) };
4668    }
4669}
4670
4671/// Bounds is an axis aligned bounding box type that can be used for storing the sizes of objects, calculating
4672/// containment, intersections, and more!
4673///
4674/// While the constructor uses a center+dimensions for creating a bounds, don’t forget the static From* methods that
4675/// allow you to define a Bounds from different types of data!
4676/// <https://stereokit.net/Pages/StereoKit/Bounds.html>
4677///
4678/// ### Examples
4679/// ```
4680/// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
4681/// use stereokit_rust::{maths::{Vec3, Matrix, Pose}, model::Model, ui::Ui,
4682///     mesh::Mesh, material::Material, util::named_colors};
4683///
4684/// let model = Model::from_file("center.glb", None).unwrap().copy();
4685/// let cube = Mesh::cube();
4686/// let mut material_cube = Material::ui_box();
4687/// material_cube.color_tint(named_colors::GOLD)
4688///              .border_size(0.05);
4689///
4690/// let scale = 0.4;
4691/// let bounds = model.get_bounds() * scale;
4692/// let transform = Matrix::s(Vec3::ONE * scale);
4693/// let transform_cube = Matrix::t_s( bounds.center, bounds.dimensions);
4694/// let mut handle_pose =
4695///     Pose::new([0.0,-0.95,-0.65], Some([0.0, 140.0, 0.0].into()));
4696///
4697/// filename_scr = "screenshots/bounds.jpeg";
4698/// test_screenshot!( // !!!! Get a proper main loop !!!!
4699///     Ui::handle_begin( "Model Handle", &mut handle_pose,
4700///                       bounds, false, None, None);
4701///     model.draw(token, transform, None, None);
4702///     cube.draw(token, &material_cube, transform_cube, None, None);
4703///     Ui::handle_end();
4704/// );
4705/// ```
4706/// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/bounds.jpeg" alt="screenshot" width="200">
4707#[derive(Copy, Clone, Debug, Default, PartialEq)]
4708#[repr(C)]
4709pub struct Bounds {
4710    pub center: Vec3,
4711    pub dimensions: Vec3,
4712}
4713
4714/// AsRef
4715impl AsRef<Bounds> for Bounds {
4716    fn as_ref(&self) -> &Bounds {
4717        self
4718    }
4719}
4720
4721unsafe extern "C" {
4722    pub fn bounds_ray_intersect(bounds: Bounds, ray: Ray, out_pt: *mut Vec3) -> Bool32T;
4723    pub fn bounds_point_contains(bounds: Bounds, pt: Vec3) -> Bool32T;
4724    pub fn bounds_line_contains(bounds: Bounds, pt1: Vec3, pt2: Vec3) -> Bool32T;
4725    pub fn bounds_capsule_contains(bounds: Bounds, pt1: Vec3, pt2: Vec3, radius: f32) -> Bool32T;
4726    pub fn bounds_grow_to_fit_pt(bounds: Bounds, pt: Vec3) -> Bounds;
4727    pub fn bounds_grow_to_fit_box(bounds: Bounds, box_: Bounds, opt_box_transform: *const Matrix) -> Bounds;
4728    pub fn bounds_transform(bounds: Bounds, transform: Matrix) -> Bounds;
4729}
4730
4731impl Bounds {
4732    /// Creates a bounding box object!
4733    /// <https://stereokit.net/Pages/StereoKit/Bounds/Bounds.html>
4734    /// * center - The exact center of the box.
4735    /// * dimensions - The total size of the box, from one end to the other. This is the width, height, and depth of
4736    ///   the Bounds.
4737    ///
4738    /// ### Examples
4739    /// ```
4740    /// use stereokit_rust::maths::{Vec3, Bounds};
4741    ///
4742    /// let bounds = Bounds::new([1.0, 2.0, 3.0], [4.0, 5.0, 6.0]);
4743    /// assert_eq!(bounds.center, Vec3::new(1.0, 2.0, 3.0));
4744    /// assert_eq!(bounds.dimensions, Vec3::new(4.0, 5.0, 6.0));
4745    /// ```
4746    #[inline]
4747    pub fn new<V: Into<Vec3>>(center: V, dimensions: V) -> Bounds {
4748        Bounds { center: center.into(), dimensions: dimensions.into() }
4749    }
4750
4751    /// Creates a bounding box object centered around zero!
4752    /// <https://stereokit.net/Pages/StereoKit/Bounds/Bounds.html>
4753    /// * dimensions - The total size of the box, from one end to the other. This is the width, height, and depth of
4754    ///   the Bounds.
4755    ///
4756    /// ### Examples
4757    /// ```
4758    /// use stereokit_rust::maths::{Vec3, Bounds};
4759    ///
4760    /// let bounds = Bounds::bounds_centered( [4.0, 5.0, 6.0]);
4761    /// assert_eq!(bounds.center, Vec3::ZERO);
4762    /// assert_eq!(bounds.dimensions, Vec3::new(4.0, 5.0, 6.0));
4763    /// ```
4764    #[inline]
4765    pub fn bounds_centered(dimensions: impl Into<Vec3>) -> Bounds {
4766        Bounds { center: Vec3::ZERO, dimensions: dimensions.into() }
4767    }
4768
4769    /// Create a bounding box from a corner, plus box dimensions.
4770    /// <https://stereokit.net/Pages/StereoKit/Bounds/FromCorner.html>
4771    /// * bottom_left_back - The -X,-Y,-Z corner of the box.
4772    /// * dimensions - The dimensions of the bounding box.
4773    ///
4774    /// ### Examples
4775    /// ```
4776    /// use stereokit_rust::maths::{Vec3, Bounds};
4777    ///
4778    /// let bounds = Bounds::from_corner( Vec3::ZERO, [1.0, 2.0, 3.0].into());
4779    /// assert_eq!(bounds.center, [0.5, 1.0, 1.5].into());
4780    /// assert_eq!(bounds.dimensions, Vec3::new(1.0, 2.0, 3.0));
4781    /// ```
4782    #[inline]
4783    pub fn from_corner<V: Into<Vec3>>(bottom_left_back: V, dimensions: V) -> Bounds {
4784        let dim = dimensions.into();
4785        Bounds { center: bottom_left_back.into() + dim / 2.0, dimensions: dim }
4786    }
4787
4788    /// Create a bounding box between two corner points.
4789    /// <https://stereokit.net/Pages/StereoKit/Bounds/FromCorners.html>
4790    /// * bottom_left_back - The -X,-Y,-Z corner of the box.
4791    /// * top_right_front - The +X,+Y,+Z corner of the box.
4792    ///
4793    /// ### Examples
4794    /// ```
4795    /// use stereokit_rust::maths::{Vec3, Bounds};
4796    ///
4797    /// let bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
4798    /// assert_eq!(bounds.center, Vec3::ONE / 2.0);
4799    /// assert_eq!(bounds.dimensions, Vec3::ONE);
4800    /// ```
4801    #[inline]
4802    pub fn from_corners<V: Into<Vec3>>(bottom_left_back: V, top_right_front: V) -> Bounds {
4803        let blb = bottom_left_back.into();
4804        let trf = top_right_front.into();
4805        Bounds { center: blb / 2.0 + trf / 2.0, dimensions: (trf - blb).abs() }
4806    }
4807
4808    /// Grow the Bounds to encapsulate the provided point. Returns the result, and does NOT modify the current bounds.
4809    /// <https://stereokit.net/Pages/StereoKit/Bounds/Grown.html>
4810    /// * pt - The point to encapsulate! This should be in the same space as the bounds.
4811    ///
4812    /// see also [`bounds_grow_to_fit_pt]
4813    /// ### Examples
4814    /// ```
4815    /// use stereokit_rust::maths::{Vec3, Bounds};
4816    ///
4817    /// let mut bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
4818    /// bounds.grown_point(Vec3::new(1.0, 2.0, 3.0));
4819    /// assert_eq!(bounds.center, Vec3{ x: 0.5, y: 1.0, z: 1.5 });
4820    /// assert_eq!(bounds.dimensions, Vec3 { x: 1.0, y: 2.0, z: 3.0 });
4821    /// ```
4822    #[inline]
4823    pub fn grown_point(&mut self, pt: impl Into<Vec3>) -> &mut Self {
4824        let b = unsafe { bounds_grow_to_fit_pt(*self, pt.into()) };
4825        self.center = b.center;
4826        self.dimensions = b.dimensions;
4827        self
4828    }
4829
4830    /// Grow the Bounds to encapsulate the provided box after it has been transformed by the provided matrix transform.
4831    /// This will transform each corner of the box, and expand the bounds to encapsulate each point!
4832    /// <https://stereokit.net/Pages/StereoKit/Bounds/Grown.html>
4833    /// * box_ - the box to encapsulate! The corners of this box are transformed, and then used to grow the bounds.
4834    /// * opt_box_transform - to center use Matrix::IDENTITY
4835    ///
4836    /// see also [`bounds_grow_to_fit_box]
4837    /// see also [`bounds_grow_to_fit_pt]
4838    /// ### Examples
4839    /// ```
4840    /// use stereokit_rust::maths::{Vec3, Matrix, Bounds};
4841    ///
4842    /// let mut bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
4843    /// let bounds_plus = Bounds::from_corners( Vec3::ONE, Vec3::ONE * 2.0);
4844    /// bounds.grown_box(bounds_plus, Matrix::IDENTITY);
4845    /// assert_eq!(bounds.center, Vec3::ONE);
4846    /// assert_eq!(bounds.dimensions, Vec3::ONE * 2.0);
4847    /// ```
4848    #[inline]
4849    pub fn grown_box<M: Into<Matrix>>(&mut self, box_: impl AsRef<Bounds>, opt_box_transform: M) -> &mut Self {
4850        let b = unsafe { bounds_grow_to_fit_box(*self, *(box_.as_ref()), &opt_box_transform.into()) };
4851        self.center = b.center;
4852        self.dimensions = b.dimensions;
4853        self
4854    }
4855
4856    /// Scale this bounds. It will scale the center as well as the dimensions! Modifies this bounds object.
4857    /// <https://stereokit.net/Pages/StereoKit/Bounds/Scale.html>
4858    /// * scale - The scale to apply.
4859    ///
4860    /// see also [Bounds::scale_vec] [Bounds::scaled] [Bounds::scaled_vec] and '/' '*' operator
4861    /// ### Examples
4862    /// ```
4863    /// use stereokit_rust::maths::{Vec3, Matrix, Bounds};
4864    ///
4865    /// let mut bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
4866    /// bounds.scale(2.0);
4867    /// let bounds_plus = Bounds::from_corners( Vec3::ZERO, Vec3::ONE) * 2.0;
4868    ///
4869    /// assert_eq!(bounds.center, bounds_plus.center);
4870    /// assert_eq!(bounds.dimensions, bounds_plus.dimensions);
4871    /// ```
4872    #[inline]
4873    pub fn scale(&mut self, scale: f32) -> &mut Self {
4874        self.dimensions *= scale;
4875        self.center *= scale;
4876        self
4877    }
4878
4879    /// Scale this bounds. It will scale the center as well as the dimensions! Modifies this bounds object.
4880    /// <https://stereokit.net/Pages/StereoKit/Bounds/Scale.html>
4881    /// * scale - The scale to apply.
4882    ///
4883    /// see also [Bounds::scale] [Bounds::scaled_vec] [Bounds::scaled] and '/' '*' operator
4884    /// ### Examples
4885    /// ```
4886    /// use stereokit_rust::maths::{Vec3, Matrix, Bounds};
4887    ///
4888    /// let mut bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
4889    /// bounds.scale_vec([1.0, 2.0, 3.0]);
4890    /// let bounds_plus = Bounds::from_corners( Vec3::ZERO, Vec3::ONE) * Vec3::new(1.0, 2.0, 3.0);
4891    ///
4892    /// assert_eq!(bounds.center, bounds_plus.center);
4893    /// assert_eq!(bounds.dimensions, bounds_plus.dimensions);
4894    /// ```
4895    #[inline]
4896    pub fn scale_vec(&mut self, scale: impl Into<Vec3>) -> &mut Self {
4897        let scale = scale.into();
4898        self.dimensions *= scale;
4899        self.center *= scale;
4900        self
4901    }
4902
4903    /// Does the Bounds contain the given point? This includes points that are on the surface of the Bounds.
4904    /// <https://stereokit.net/Pages/StereoKit/Bounds/Contains.html>
4905    /// * pt - A point in the same coordinate space as the Bounds.
4906    ///
4907    /// see also [`bounds_point_contains`]
4908    /// ### Examples
4909    /// ```
4910    /// use stereokit_rust::maths::{Vec3, Bounds, Matrix};
4911    ///
4912    /// // A cube of 1 meter per side at this position, aligned with x y and z axis.
4913    /// let box_transform = Matrix::t([10.0, 1.0, 2.0]);
4914    /// let box_bounds = Bounds::bounds_centered([1.0,1.0,1.0]);
4915    ///
4916    /// let inv = box_transform.get_inverse();
4917    /// let point1 = inv.transform_point([10.2, 1.3, 2.4]);
4918    /// let point2 = inv.transform_point([10.9, 1.8, 2.1]);
4919    /// let point3 = inv.transform_point([10.5, 2.01, 1.7]);
4920    /// let point4 = inv.transform_point([9.5, 0.7, 1.5]);
4921    ///
4922    /// assert!(box_bounds.contains_point(point1),  "point1 should be inside");
4923    /// assert!(!box_bounds.contains_point(point2), "point2 should be outside");
4924    /// assert!(!box_bounds.contains_point(point3), "point3 should be outside");
4925    /// assert!(box_bounds.contains_point(point4),  "point4 should be inside");
4926    ///
4927    /// assert!(box_bounds.contains_point([0.5, 0.5, 0.5]),
4928    ///         "inverse point should be inside");
4929    /// ```
4930    #[inline]
4931    pub fn contains_point(&self, pt: impl Into<Vec3>) -> bool {
4932        unsafe { bounds_point_contains(*self, pt.into()) != 0 }
4933    }
4934
4935    /// Does the Bounds contain or intersects with the given line?
4936    /// <https://stereokit.net/Pages/StereoKit/Bounds/Contains.html>
4937    /// * line_pt1 - The first point on the line.
4938    /// * line_pt2 - The second point on the line.
4939    ///
4940    /// see also [`bounds_line_contains`]
4941    /// ### Examples
4942    /// ```
4943    /// use stereokit_rust::maths::{Vec3, Bounds, Matrix};
4944    ///
4945    /// // A cube of 1 meter per side at this position, aligned with x y and z axis.
4946    /// let box_transform = Matrix::t([10.0, 1.0, 2.0]);
4947    /// let box_bounds = Bounds::bounds_centered([1.0,1.0,1.0]);
4948    ///
4949    /// let inv = box_transform.get_inverse();
4950    /// let point1 = inv.transform_point([10.2, 1.3, 2.4]);
4951    /// let point2 = inv.transform_point([10.9, 1.8, 2.1]);
4952    /// let point3 = inv.transform_point([10.5, 2.01, 1.7]);
4953    /// let point4 = inv.transform_point([9.5, 0.7, 1.5]);
4954    ///
4955    /// assert!(box_bounds.contains_line(point1, point2),  "point1-point2 should be inside");
4956    /// assert!(!box_bounds.contains_line(point2, point3), "point2-point3 should be outside");
4957    /// assert!(box_bounds.contains_line(point3, point4),  "point3-point4 should be inside");
4958    /// assert!(box_bounds.contains_line(point4, point1),  "point4-point1 should be inside");
4959    ///
4960    /// assert!(box_bounds.contains_line([0.1, 0.1, 0.1], [0.9, 0.9, 0.9]),
4961    ///         "inverse line should be inside");
4962    /// ```
4963    #[inline]
4964    pub fn contains_line<V3: Into<Vec3>>(&self, line_pt1: V3, line_pt2: V3) -> bool {
4965        unsafe { bounds_line_contains(*self, line_pt1.into(), line_pt2.into()) != 0 }
4966    }
4967
4968    /// Does the bounds contain or intersect with the given capsule?
4969    /// <https://stereokit.net/Pages/StereoKit/Bounds/Contains.html>
4970    /// * pt1 - The first point of the capsule.
4971    /// * pt2 - The second point of the capsule.
4972    /// * radius - The radius of the capsule.
4973    ///
4974    /// see also [`bounds_capsule_contains`]
4975    /// ### Examples
4976    /// ```
4977    /// use stereokit_rust::maths::{Vec3, Bounds, Matrix};
4978    ///
4979    /// // A cube of 1 meter per side at this position, aligned with x y and z axis.
4980    /// let box_transform = Matrix::t([10.0, 1.0, 2.0]);
4981    /// let box_bounds = Bounds::bounds_centered([1.0,1.0,1.0]);
4982    ///
4983    /// let inv = box_transform.get_inverse();
4984    /// let point1 = inv.transform_point([10.2, 1.3, 2.4]);
4985    /// let point2 = inv.transform_point([10.9, 1.8, 2.1]);
4986    /// let point3 = inv.transform_point([10.5, 2.01, 1.7]);
4987    /// let point4 = inv.transform_point([9.5, 0.7, 1.5]);
4988    ///
4989    /// assert!(box_bounds.contains_capsule(point1, point2, 0.1),  "point1-point2 should be inside");
4990    /// assert!(!box_bounds.contains_capsule(point2, point3, 0.1), "point2-point3 * 0.1 should be outside");
4991    /// assert!(box_bounds.contains_capsule(point2, point3, 0.4),  "point2-point3 * 0.4 should be inside");
4992    /// assert!(box_bounds.contains_capsule(point3, point4, 0.1),  "point3-point4 should be inside");
4993    /// assert!(box_bounds.contains_capsule(point4, point1, 0.1),  "point4-point1 should be inside");
4994    ///
4995    /// assert!(box_bounds.contains_capsule([0.1, 0.1, 0.1], [0.9, 0.9, 0.9], 10.0),
4996    ///         "inverse line * 10 should be inside");
4997    /// ```
4998    #[inline]
4999    pub fn contains_capsule<V3: Into<Vec3>>(&self, line_pt1: V3, line_pt2: V3, radius: f32) -> bool {
5000        unsafe { bounds_capsule_contains(*self, line_pt1.into(), line_pt2.into(), radius) != 0 }
5001    }
5002
5003    /// Calculate the intersection between a Ray, and these bounds. Returns false if no intersection occurred, and ‘at’
5004    /// will contain the nearest intersection point to the start of the ray if an intersection is found!
5005    /// <https://stereokit.net/Pages/StereoKit/Bounds/Intersect.html>
5006    /// * ray - Any Ray in the same coordinate space as the Bounds
5007    ///
5008    /// Returns the closest intersection point to the origin of the ray or None if there isn't an instersection
5009    /// see also [`bounds_ray_intersect`] same as [`Ray::intersect_bounds`]
5010    /// ### Examples
5011    /// ```
5012    /// use stereokit_rust::maths::{Vec3, Bounds, Matrix, Ray};
5013    ///
5014    /// // A cube of 1 meter per side at this position, aligned with x y and z axis.
5015    /// let box_transform = Matrix::t([10.0, 1.0, 2.0]);
5016    /// let box_bounds = Bounds::bounds_centered([1.0,1.0,1.0]);
5017    ///
5018    /// let inv = box_transform.get_inverse();
5019    /// let ray1 = inv.transform_ray(Ray::new([10.2, 1.3, 2.4],[0.0, 1.0, 0.0]));
5020    /// let ray2 = inv.transform_ray(Ray::new([10.9, 1.8, 2.6],[0.0, 0.0, 1.0]));
5021    /// let ray3 = inv.transform_ray(Ray::new([10.5, 2.0, 2.7],[1.0, 0.0, 1.0]));
5022    ///
5023    /// assert!(box_bounds.intersect(ray1).is_some(),  "should be a point of contact");
5024    /// assert_eq!(box_bounds.intersect(ray2), None);
5025    /// assert_eq!(box_bounds.intersect(ray3),  None);
5026    /// assert_eq!(box_bounds.intersect(Ray::new([1.1, 1.1, 1.1], [-1.9, -1.9, -1.9])),
5027    ///             Some([0.5, 0.5, 0.5].into()));
5028    ///
5029    /// // We want the contact point for ray1
5030    /// let contact_point = box_bounds.intersect(ray1)
5031    ///         .expect ("There should be a point of contact");
5032    ///
5033    /// let contact_point = box_transform.transform_point(contact_point);
5034    /// assert_eq!(contact_point,  [10.2, 1.3, 2.4 ].into());
5035    /// ```
5036    #[inline]
5037    pub fn intersect<R: Into<Ray>>(&self, ray: R) -> Option<Vec3> {
5038        let mut pt = Vec3::default();
5039        let ray = ray.into();
5040        match unsafe { bounds_ray_intersect(*self, ray, &mut pt) != 0 } {
5041            true => Some(pt),
5042            false => None,
5043        }
5044    }
5045
5046    /// Scale the bounds. It will scale the center as well as the dimensions! Returns a new Bounds.
5047    /// equivalent to using multiply operator
5048    /// <https://stereokit.net/Pages/StereoKit/Bounds/Scaled.html>
5049    /// * scale - The scale to apply.
5050    ///
5051    /// see also [Bounds::scale] [Bounds::scaled_vec] [Bounds::scale_vec] and '/' '*' operator
5052    /// ### Examples
5053    /// ```
5054    /// use stereokit_rust::maths::{Vec3, Bounds};
5055    ///
5056    /// let mut bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
5057    /// let bounds_scaled = bounds.scaled(2.0);
5058    /// let bounds_plus = Bounds::from_corners( Vec3::ZERO, Vec3::ONE) * 2.0;
5059    ///
5060    /// assert_eq!(*bounds.scale(2.0), bounds_scaled);
5061    /// assert_eq!(bounds_scaled.center, bounds_plus.center);
5062    /// assert_eq!(bounds_scaled.dimensions, bounds_plus.dimensions);
5063    /// ```
5064    #[inline]
5065    pub fn scaled(&self, scale: f32) -> Self {
5066        *self * scale
5067    }
5068
5069    /// Scale the bounds. It will scale the center as well as the dimensions! Returns a new Bounds.
5070    /// equivalent to using multiply operator
5071    /// <https://stereokit.net/Pages/StereoKit/Bounds/Scaled.html>
5072    /// * scale - The scale to apply.
5073    ///
5074    /// see also [Bounds::scale_vec] [Bounds::scale] [Bounds::scaled] and '/' '*' operator
5075    /// ### Examples
5076    /// ```
5077    /// use stereokit_rust::maths::{Vec3, Bounds};
5078    ///
5079    /// let bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
5080    /// let bounds_scaled = bounds.scaled_vec([1.0, 2.0, 3.0]);
5081    /// let bounds_plus = Bounds::from_corners( Vec3::ZERO, Vec3::ONE) * Vec3::new(1.0, 2.0, 3.0);
5082    ///
5083    /// assert_eq!(bounds * Vec3::new(1.0, 2.0, 3.0), bounds_scaled);
5084    /// assert_eq!(bounds_scaled.center, bounds_plus.center);
5085    /// assert_eq!(bounds_scaled.dimensions, bounds_plus.dimensions);
5086    /// ```
5087    #[inline]
5088    pub fn scaled_vec(&self, scale: impl Into<Vec3>) -> Self {
5089        *self * scale.into()
5090    }
5091
5092    /// This returns a Bounds that encapsulates the transformed points of the current Bounds’s corners.
5093    /// Note that this will likely introduce a lot of extra empty volume in many cases, as the result is still always axis aligned.
5094    /// <https://stereokit.net/Pages/StereoKit/Bounds/Transformed.html>
5095    /// * transform - A transform Matrix for the current Bounds’s corners.
5096    ///
5097    /// see also [`bounds_transform]
5098    /// ### Examples
5099    ///```
5100    /// use stereokit_rust::maths::{Vec3, Bounds, Matrix};
5101    ///
5102    /// let matrix = Matrix::r([90.0, 90.0, 90.0]);
5103    /// let bounds = Bounds::bounds_centered([1.0, 1.0, 1.0]);
5104    /// let bounds_transformed = bounds.transformed(matrix);
5105    ///
5106    /// assert_eq!(bounds_transformed.dimensions, Vec3{x: 1.0000001, y: 0.99999994, z: 0.99999994});
5107    /// assert_eq!(bounds_transformed.center, Vec3{x:0.0, y:0.0, z:0.0})
5108    ///```
5109    #[inline]
5110    pub fn transformed(&self, transform: impl Into<Matrix>) -> Self {
5111        unsafe { bounds_transform(*self, transform.into()) }
5112    }
5113
5114    /// From the front, this is the Top (Y+), Left (X+), Center
5115    /// (Z0) of the bounds. Useful when working with UI layout bounds.
5116    /// <https://stereokit.net/Pages/StereoKit/Bounds/TLC.html>
5117    ///
5118    /// see also [Bounds::tlb]
5119    /// ### Examples
5120    ///```
5121    /// use stereokit_rust::maths::{Vec3, Bounds};
5122    ///
5123    /// let bounds = Bounds::bounds_centered([1.0, 1.0, 1.0]);
5124    ///
5125    /// assert_eq!(bounds.tlc(), Vec3{x:0.5, y:0.5, z: 0.0});
5126    ///```    
5127    #[inline]
5128    pub fn tlc(&self) -> Vec3 {
5129        self.center + self.dimensions.xy0() / 2.0
5130    }
5131
5132    /// From the front, this is the Top (Y+), Left (X+), Back (Z+)
5133    /// of the bounds. Useful when working with UI layout bounds.
5134    /// <https://stereokit.net/Pages/StereoKit/Bounds/TLB.html>
5135    ///
5136    /// see also [Bounds::tlb]
5137    /// ### Examples
5138    ///```
5139    /// use stereokit_rust::maths::{Vec3, Bounds};
5140    ///
5141    /// let bounds = Bounds::bounds_centered([1.0, 1.0, 1.0]);
5142    ///
5143    /// assert_eq!(bounds.tlb(), Vec3{x:0.5, y:0.5, z: 0.5});
5144    ///```
5145    #[inline]
5146    pub fn tlb(&self) -> Vec3 {
5147        self.center + self.dimensions / 2.0
5148    }
5149}
5150
5151impl Display for Bounds {
5152    /// Creates a text description of the Bounds, in the format of “[center:X dimensions:X]”
5153    /// <https://stereokit.net/Pages/StereoKit/Bounds/ToString.html>
5154    ///
5155    /// ### Examples
5156    /// ```
5157    /// use stereokit_rust::maths::{Vec3, Bounds};
5158    ///
5159    /// let bounds = Bounds::new([1.1, 2.0, 3.0], [4.0, 5.0, 6.0]);
5160    /// assert_eq!(format!("{}", bounds),
5161    ///            "[center:[x:1.1, y:2, z:3] dimensions:[x:4, y:5, z:6]]");
5162    /// ```
5163    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5164        write!(f, "[center:{} dimensions:{}]", self.center, self.dimensions)
5165    }
5166}
5167/// This operator will create a new Bounds that has been properly scaled up by the float. This does affect the center
5168/// position of the Bounds.
5169/// <https://stereokit.net/Pages/StereoKit/Bounds/op_Multiply.html>
5170impl Mul<f32> for Bounds {
5171    type Output = Bounds;
5172
5173    /// ### Examples
5174    /// ```
5175    /// use stereokit_rust::maths::{Vec3, Bounds};
5176    ///
5177    /// let bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
5178    ///
5179    /// let bounds_scaled = bounds * 2.0;
5180    /// assert_eq!(bounds_scaled.center, Vec3::ONE);
5181    /// assert_eq!(bounds_scaled.dimensions, Vec3::new(2.0, 2.0, 2.0));
5182    /// ```
5183    fn mul(self, rhs: f32) -> Self::Output {
5184        Bounds { center: self.center * rhs, dimensions: self.dimensions * rhs }
5185    }
5186}
5187
5188/// This operator will create a new Bounds that has been properly scaled up by the float. This does affect the center
5189/// position of the Bounds.
5190/// <https://stereokit.net/Pages/StereoKit/Bounds/op_Multiply.html>
5191impl MulAssign<f32> for Bounds {
5192    /// ### Examples
5193    /// ```
5194    /// use stereokit_rust::maths::{Vec3, Bounds};
5195    ///
5196    /// let mut bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
5197    ///
5198    /// bounds *= 2.0;
5199    /// assert_eq!(bounds.center, Vec3::ONE);
5200    /// assert_eq!(bounds.dimensions, Vec3::new(2.0, 2.0, 2.0));
5201    /// ```
5202    fn mul_assign(&mut self, rhs: f32) {
5203        self.center.mul_assign(rhs);
5204        self.dimensions.mul_assign(rhs);
5205    }
5206}
5207
5208/// This operator will create a new Bounds that has been properly scaled up by the float. This does affect the center
5209/// position of the Bounds.
5210/// <https://stereokit.net/Pages/StereoKit/Bounds/op_Multiply.html>
5211impl Mul<Bounds> for f32 {
5212    type Output = Bounds;
5213
5214    /// ### Examples
5215    /// ```
5216    /// use stereokit_rust::maths::{Vec3, Bounds};
5217    ///
5218    /// let bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
5219    ///
5220    /// let bounds_scaled = 2.0 * bounds;
5221    /// assert_eq!(bounds_scaled.center, Vec3::ONE);
5222    /// assert_eq!(bounds_scaled.dimensions, Vec3::new(2.0, 2.0, 2.0));
5223    /// ```
5224    fn mul(self, rhs: Bounds) -> Self::Output {
5225        Bounds { center: rhs.center * self, dimensions: rhs.dimensions * self }
5226    }
5227}
5228
5229/// This operator will create a new Bounds that has been properly scaled up by the Vec3. This does affect the center
5230/// position of the Bounds.
5231/// <https://stereokit.net/Pages/StereoKit/Bounds/op_Multiply.html>
5232impl Mul<Vec3> for Bounds {
5233    type Output = Bounds;
5234
5235    /// ### Examples
5236    /// ```
5237    /// use stereokit_rust::maths::{Vec3, Bounds};
5238    ///
5239    /// let bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
5240    ///
5241    /// let bounds_scaled = bounds * Vec3::new(1.0, 2.0, 3.0);
5242    /// assert_eq!(bounds_scaled.center, Vec3::new(0.5, 1.0, 1.5));
5243    /// assert_eq!(bounds_scaled.dimensions, Vec3::new(1.0, 2.0, 3.0));
5244    /// ```
5245    fn mul(self, rhs: Vec3) -> Self::Output {
5246        Bounds { center: self.center * rhs, dimensions: self.dimensions * rhs }
5247    }
5248}
5249
5250/// This operator will create a new Bounds that has been properly scaled up by the Vec3. This does affect the center
5251/// position of the Bounds.
5252/// <https://stereokit.net/Pages/StereoKit/Bounds/op_Multiply.html>
5253impl MulAssign<Vec3> for Bounds {
5254    /// ### Examples
5255    /// ```
5256    /// use stereokit_rust::maths::{Vec3, Bounds};
5257    ///
5258    /// let mut bounds = Bounds::from_corners( Vec3::ZERO, Vec3::ONE);
5259    ///
5260    /// bounds *= Vec3::new(1.0, 2.0, 3.0);
5261    /// assert_eq!(bounds.center, Vec3::new(0.5, 1.0, 1.5));
5262    /// assert_eq!(bounds.dimensions, Vec3::new(1.0, 2.0, 3.0));
5263    /// ```
5264    fn mul_assign(&mut self, rhs: Vec3) {
5265        self.center.mul_assign(rhs);
5266        self.dimensions.mul_assign(rhs);
5267    }
5268}
5269
5270/// Planes are really useful for collisions, intersections, and visibility testing!
5271///
5272/// This plane is stored using the ax + by + cz + d = 0 formula, where the normal is a,b,c, and the d is, well, d.
5273/// <https://stereokit.net/Pages/StereoKit/Plane.html>
5274/// ### Examples
5275/// ```
5276/// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
5277/// use stereokit_rust::{maths::{Vec3, Matrix, Plane},
5278///                      mesh::Mesh, material::Material, util::named_colors};
5279///
5280/// let plane_mesh = Mesh::generate_plane_up([1.0,1.0], None, true);
5281/// let mut material_plane = Material::pbr();
5282///
5283/// let transform_wall = Matrix::t_r([-0.5, 0.0, 0.0],
5284///                                  [0.0, 0.0, 90.0]);
5285/// let transform_floor = Matrix::t([0.0, -0.5, 0.0]);
5286///
5287/// let wall =   Plane::new (Vec3::X, 0.5);
5288/// let wall_b = Plane::from_point( [-0.5, -1.1, -1.1].into(), Vec3::X);
5289/// let wall_c = Plane::from_points([-0.5, -2.2, -2.2],
5290///                                 [-0.5, -3.3, -3.3],
5291///                                 [-0.5, -4.4, -14.4]);
5292///
5293/// assert_eq!(wall.closest(Vec3::Y), Vec3 {x:-0.5, y:1.0, z:0.0});
5294/// assert_eq!(wall_b.closest(Vec3::Y), Vec3 {x:-0.5, y:1.0, z:0.0});
5295/// assert_eq!(wall_c.closest(Vec3::Y), Vec3 {x:-0.5, y:1.0, z:0.0});
5296/// assert_eq!(wall, wall_b);
5297/// //assert_eq!(wall, wall_c); // differents but the same
5298///
5299/// filename_scr = "screenshots/plane.jpeg";
5300/// test_screenshot!( // !!!! Get a proper main loop !!!!
5301///     plane_mesh.draw(token, &material_plane, transform_wall, Some(named_colors::CYAN.into()), None);
5302///     plane_mesh.draw(token, &material_plane, transform_floor, Some(named_colors::BLACK.into()), None);
5303/// );
5304/// ```
5305/// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/plane.jpeg" alt="screenshot" width="200">
5306#[derive(Copy, Clone, Debug, Default)]
5307#[repr(C)]
5308pub struct Plane {
5309    /// The direction the plane is facing.
5310    pub normal: Vec3,
5311    /// The distance/travel along the plane's normal from
5312    /// the origin to the surface of the plane.
5313    pub d: f32,
5314}
5315
5316/// AsRef
5317impl AsRef<Plane> for Plane {
5318    fn as_ref(&self) -> &Plane {
5319        self
5320    }
5321}
5322
5323///  Warning: Equality with a precision of 0.1 millimeter
5324impl PartialEq for Plane {
5325    ///  Warning: Equality with a precision of 0.1 millimeter
5326    fn eq(&self, other: &Self) -> bool {
5327        self.normal == other.normal && self.d - other.d < 0.0001
5328    }
5329}
5330
5331unsafe extern "C" {
5332    pub fn plane_from_points(p1: Vec3, p2: Vec3, p3: Vec3) -> Plane;
5333    pub fn plane_from_ray(ray: Ray) -> Plane;
5334    pub fn plane_ray_intersect(plane: Plane, ray: Ray, out_pt: *mut Vec3) -> Bool32T;
5335    pub fn plane_line_intersect(plane: Plane, p1: Vec3, p2: Vec3, out_pt: *mut Vec3) -> Bool32T;
5336    pub fn plane_point_closest(plane: Plane, pt: Vec3) -> Vec3;
5337}
5338
5339impl Plane {
5340    /// Creates a Plane directly from the ax + by + cz + d = 0 formula!
5341    /// <https://stereokit.net/Pages/StereoKit/Plane/Plane.html>
5342    pub fn new<V: Into<Vec3>>(normal: V, d: f32) -> Plane {
5343        Plane { normal: normal.into(), d }
5344    }
5345
5346    /// Creates a plane from a normal, and any point on the plane!
5347    /// <https://stereokit.net/Pages/StereoKit/Plane/Plane.html>
5348    ///
5349    /// ## Examples
5350    /// ```
5351    /// use stereokit_rust::maths::{Plane,Vec3};
5352    /// let wall_x = Plane::from_point(Vec3::X*4.0,  Vec3::X);
5353    /// assert_eq!(wall_x.d , -4.0);
5354    /// ````
5355    #[inline]
5356    pub fn from_point<V: Into<Vec3>>(point_on_plane: V, plane_normal: V) -> Plane {
5357        let p_o_p = point_on_plane.into();
5358        let normal = plane_normal.into();
5359        // let plane0 = Plane { normal, d: 0.0 };
5360        // let p0 = plane0.closest(p_o_p);
5361        //Plane { normal, d: Vec3::distance(p0, p_o_p) }
5362        Plane { normal, d: -Vec3::dot(p_o_p, normal) }
5363    }
5364
5365    /// Creates a plane from 3 points that are directly on that plane.
5366    /// Unstable as some normal with NaN values may be created if the points are aligned.
5367    ///
5368    /// <https://stereokit.net/Pages/StereoKit/Plane/Plane.html>
5369    ///
5370    /// ## Examples
5371    /// ```
5372    /// use stereokit_rust::maths::{Plane,Vec3};
5373    /// let ground = Plane::from_points([1.0, 1.5, 0.0],
5374    ///                                 [0.0, 1.5, 1.0],
5375    ///                                 [1.0, 1.5, 1.0]);
5376    /// assert_eq!(ground.d , 1.5);
5377    /// assert!(ground.normal.y + 1.0 < 0.0001);
5378    ///
5379    /// let wall_c = Plane::from_points([-0.5, -0.4, -1.0],
5380    ///                                 [-0.5, 0.0, 3.0],
5381    ///                                 [-0.5, 0.3, -4.0]);
5382    /// println! ("{:?}", wall_c);
5383    /// assert_eq!(wall_c.d , 0.5);
5384    /// assert!(wall_c.normal.x - 1.0 < 0.0001);
5385    /// ```
5386    #[deprecated(since = "0.4.0", note = "Unstable! use `Plane::from_point` or `Plane::new` instead")]
5387    #[inline]
5388    pub fn from_points<V: Into<Vec3>>(point_on_plane1: V, point_on_plane2: V, point_on_plane3: V) -> Plane {
5389        let p1 = point_on_plane1.into();
5390        let p2 = point_on_plane2.into();
5391        let p3 = point_on_plane3.into();
5392        let dir1 = p2 - p1;
5393        let dir2 = p2 - p3;
5394        let mut normal = Vec3::cross(dir1, dir2).get_normalized();
5395        if normal.z.is_nan() {
5396            let dir1 = p1 - p3;
5397            let dir2 = p1 - p2;
5398            normal = Vec3::cross(dir1, dir2).get_normalized();
5399            if normal.z.is_nan() {
5400                let dir1 = p3 - p1;
5401                let dir2 = p3 - p2;
5402                normal = Vec3::cross(dir1, dir2).get_normalized();
5403            }
5404        }
5405
5406        //let plane0 = Plane { normal, d: 0.0 };
5407        //let p0 = plane0.closest(p2);
5408        //Plane { normal, d: Vec3::distance(p0, p2) }
5409        Plane { normal, d: -Vec3::dot(p2, normal) }
5410
5411        // Do not save the problem : unsafe{plane_from_points(p1, p2, p3)}
5412    }
5413
5414    /// Finds the closest point on this plane to the given point!
5415    /// <https://stereokit.net/Pages/StereoKit/Plane/Closest.html>
5416    ///
5417    /// see also [`plane_point_closest`]
5418    /// ## Examples
5419    /// ```
5420    /// use stereokit_rust::maths::{Plane,Vec3};
5421    /// let plane = Plane{normal : Vec3::X , d: -4.0};
5422    /// let closest = plane.closest(Vec3::ZERO);
5423    /// assert_eq!(closest , (Vec3::X * 4.0));
5424    /// let plane = Plane::from_points(Vec3::X , Vec3::Z, Vec3::Y );
5425    /// assert_eq!(plane, Plane{normal : Vec3::ONE / (3.0_f32.sqrt()), d:-1.0/3.0_f32.sqrt()} );
5426    /// let closest = plane.closest(Vec3::ZERO);
5427    /// assert_eq!(closest , Vec3::new(0.3333333,0.3333333,0.3333333));
5428    /// ```
5429    #[inline]
5430    pub fn closest<V: Into<Vec3>>(&self, to: V) -> Vec3 {
5431        unsafe { plane_point_closest(*self, to.into()) }
5432    }
5433
5434    /// Checks the intersection of a ray with this plane!
5435    /// <https://stereokit.net/Pages/StereoKit/Plane/Intersect.html>
5436    /// * ray - The ray we're checking with.
5437    ///
5438    /// Returns the intersection point or None if there isn't an instersection
5439    /// see also [`plane_ray_intersect`] same as [`Ray::intersect_plane`]
5440    #[inline]
5441    pub fn intersect(&self, ray: Ray) -> Option<Vec3> {
5442        let mut pt = Vec3::default();
5443        match unsafe { plane_ray_intersect(*self, ray, &mut pt) != 0 } {
5444            true => Some(pt),
5445            false => None,
5446        }
5447    }
5448
5449    /// Checks the intersection of a line with this plane!
5450    /// <https://stereokit.net/Pages/StereoKit/Plane/Intersect.html>
5451    /// * line_start - Start of the line.
5452    /// * line_end - End of the line.
5453    ///
5454    /// Returns the intersection point or None if there isn't an instersection
5455    /// see also [`plane_line_intersect`]
5456    #[inline]
5457    pub fn intersect_line<V: Into<Vec3>>(&self, line_start: V, line_end: V) -> Option<Vec3> {
5458        let mut pt = Vec3::default();
5459        match unsafe { plane_line_intersect(*self, line_start.into(), line_end.into(), &mut pt) != 0 } {
5460            true => Some(pt),
5461            false => None,
5462        }
5463    }
5464}
5465
5466impl Display for Plane {
5467    /// Creates a text description of the Plane, in the format of “[normal:X distance:X]”
5468    /// ### Examples
5469    /// ```
5470    /// use stereokit_rust::maths::{Vec3, Plane};
5471    ///
5472    /// let plane = Plane::new([1.1, 2.0, 3.0], 4.0);
5473    /// assert_eq!(format!("{}", plane),
5474    ///            "[normal:[x:1.1, y:2, z:3] distance:4]");
5475    /// ```
5476    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5477        write!(f, "[normal:{} distance:{}]", self.normal, self.d)
5478    }
5479}
5480
5481/// Pose represents a location and orientation in space, excluding scale! The default value of a Pose use
5482/// Pose.Identity .
5483/// <https://stereokit.net/Pages/StereoKit/Pose.html>
5484///
5485/// ### Examples
5486/// ```
5487/// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
5488/// use stereokit_rust::{ui::Ui, maths::{Vec3, Pose, Matrix}, model::Model };
5489///
5490/// let plane = Model::from_file("plane.glb", None).unwrap_or_default();
5491/// let bounds = plane.get_bounds();
5492/// let mut handle_pose = Pose::look_at(
5493///     [0.0, -5.5, -10.0], (Vec3::Z + Vec3::X) * 100.0);
5494///
5495/// let mut window_pose = Pose::new(
5496///     [0.0, 0.05, 0.90], Some([0.0, 200.0, 0.0].into()));
5497///
5498/// filename_scr = "screenshots/pose.jpeg";
5499/// test_screenshot!( // !!!! Get a proper main loop !!!!
5500///     Ui::handle_begin( "Model Handle", &mut handle_pose,
5501///                       bounds, false, None, None);
5502///     plane.draw(token, Matrix::IDENTITY, None, None);
5503///     Ui::handle_end();
5504///
5505///     Ui::window_begin("My Window", &mut window_pose, None, None, None);
5506///     Ui::text("My Text", None, None, None, Some(0.14), None, None);
5507///     Ui::window_end();
5508/// );
5509/// ```
5510///
5511/// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/pose.jpeg" alt="screenshot" width="200">
5512#[repr(C)]
5513#[derive(Debug, Copy, Clone, PartialEq)]
5514pub struct Pose {
5515    pub position: Vec3,
5516    pub orientation: Quat,
5517}
5518
5519impl From<Matrix> for Pose {
5520    fn from(matrix: Matrix) -> Self {
5521        matrix.get_pose()
5522    }
5523}
5524
5525impl Default for Pose {
5526    /// Position is Vec3::ZERO, and orientation is Quat::IDENTITY (no rotation)
5527    /// <https://stereokit.net/Pages/StereoKit/Pose/Identity.html>
5528    fn default() -> Self {
5529        Pose::IDENTITY
5530    }
5531}
5532
5533impl Pose {
5534    /// The default Pose: Origin with Quat::IDENTITY orientation.
5535    /// <https://stereokit.net/Pages/StereoKit/Pose/Identity.html>
5536    pub const IDENTITY: Pose = Pose { position: Vec3::new(0.0, 0.0, 0.0), orientation: Quat::IDENTITY };
5537
5538    /// Zero may be encountered when testing some [`crate::system::Input`] [`crate::system::Pointer`] and [`crate::system::Controller`]
5539    pub const ZERO: Pose = Pose { position: Vec3::new(0.0, 0.0, 0.0), orientation: Quat::ZERO };
5540
5541    /// Basic initialization constructor! Just copies in the provided values directly, and uses Identity for the
5542    /// orientation.
5543    /// <https://stereokit.net/Pages/StereoKit/Pose/Pose.html>
5544    ///
5545    /// ### Examples
5546    /// ```
5547    /// use stereokit_rust::maths::{Vec3, Pose};
5548    /// let mut handle_pose = Pose::new( [0.0, 0.05, 0.90], None);
5549    ///
5550    /// let mut window_pose = Pose::new(
5551    ///     [0.0, 0.05, 0.90], Some([0.0, 180.0 * 4.0, 0.0].into()));
5552    ///
5553    /// assert_eq!(handle_pose, window_pose);
5554    #[inline]
5555    pub fn new(position: impl Into<Vec3>, orientation: Option<Quat>) -> Self {
5556        let orientation = orientation.unwrap_or(Quat::IDENTITY);
5557        Self { position: position.into(), orientation }
5558    }
5559
5560    /// Interpolates between two poses! It is unclamped, so values outside of (0,1) will extrapolate their position.
5561    /// <https://stereokit.net/Pages/StereoKit/Pose/Lerp.html>
5562    ///
5563    /// ### Examples
5564    /// ```
5565    /// use stereokit_rust::maths::{Vec3, Pose};
5566    ///
5567    /// let mut pose1 = Pose::new( Vec3::Y, None);
5568    /// let mut pose2 = Pose::new( Vec3::Y, Some([0.0, 45.0, 0.0].into()));
5569    /// let mut pose3 = Pose::new( Vec3::Y, Some([0.0, 90.0, 0.0].into()));
5570    ///
5571    /// assert_eq!(Pose::lerp(pose1, pose3, 0.5), pose2);
5572    #[inline]
5573    pub fn lerp(a: impl Into<Pose>, b: impl Into<Pose>, percent: f32) -> Self {
5574        let a = a.into();
5575        let b = b.into();
5576        Self {
5577            position: Vec3::lerp(a.position, b.position, percent),
5578            orientation: Quat::slerp(a.orientation, b.orientation, percent),
5579        }
5580    }
5581
5582    /// Creates a Pose that looks from one location in the direction of another location. This leaves “Up” as the +Y
5583    /// axis.
5584    /// <https://stereokit.net/Pages/StereoKit/Pose/LookAt.html>
5585    ///
5586    /// ### Examples
5587    /// ```
5588    /// use stereokit_rust::maths::{Vec3, Pose};
5589    ///
5590    /// let mut pose1 = Pose::look_at(Vec3::ZERO, Vec3::NEG_Z );
5591    /// assert_eq!(pose1, Pose::default());
5592    #[inline]
5593    pub fn look_at(from: impl Into<Vec3>, at: impl Into<Vec3>) -> Self {
5594        let from = from.into();
5595        let at = at.into();
5596        Self { position: from, orientation: Quat::look_at(from, at, None) }
5597    }
5598
5599    /// Converts this pose into a transform matrix.
5600    /// <https://stereokit.net/Pages/StereoKit/Pose/ToMatrix.html>
5601    /// * scale - Let you add a scale factor if needed.
5602    ///
5603    /// ### Examples
5604    /// ```
5605    /// use stereokit_rust::maths::{Vec3, Matrix, Pose};
5606    ///
5607    /// let pose1 = Pose::IDENTITY;
5608    ///
5609    /// assert_eq!(pose1.to_matrix(None), Matrix::IDENTITY);    
5610    #[inline]
5611    pub fn to_matrix(&self, scale: Option<Vec3>) -> Matrix {
5612        match scale {
5613            Some(scale) => Matrix::t_r_s(self.position, self.orientation, scale),
5614            None => Matrix::t_r(self.position, self.orientation),
5615        }
5616    }
5617
5618    /// Converts this pose into the inverse of the Pose's transform matrix. This can be used to
5619    /// transform points from the space represented by the Pose into world space.
5620    /// <https://stereokit.net/Pages/StereoKit/Pose/ToMatrixInv.html>
5621    /// * scale - A scale vector! Vec3.One would be an identity scale.
5622    ///
5623    /// ### Examples
5624    /// ```
5625    /// use stereokit_rust::maths::{Vec3, Matrix, Pose};
5626    ///
5627    /// let pose1 = Pose::IDENTITY;
5628    ///
5629    /// assert_eq!(pose1.to_matrix_inv(None), Matrix::IDENTITY);    
5630    ///
5631    /// assert_eq!(pose1.to_matrix_inv(Some(Vec3::new(0.5, 0.25, 0.125))),
5632    ///             [2.0, 0.0, 0.0, 0.0,
5633    ///              0.0, 4.0, 0.0, 0.0,
5634    ///              0.0, 0.0, 8.0, 0.0,
5635    ///              0.0, 0.0, 0.0, 1.0].into());
5636    /// ```
5637    #[inline]
5638    pub fn to_matrix_inv(&self, scale: Option<Vec3>) -> Matrix {
5639        let inv_orientation = self.orientation.conjugate();
5640
5641        match scale {
5642            Some(scale) => {
5643                let inv_scale = 1.0 / scale;
5644
5645                let inv_transform = inv_orientation.rotate_point(-self.position * inv_scale);
5646
5647                Matrix::t_r_s(inv_transform, inv_orientation, inv_scale)
5648            }
5649            None => {
5650                let inv_transform = inv_orientation.rotate_point(-self.position);
5651                Matrix::t_r(inv_transform, inv_orientation)
5652            }
5653        }
5654    }
5655
5656    /// Calculates the forward direction from this pose. This is done by multiplying the orientation with
5657    /// Vec3::new(0, 0, -1). Remember that Forward points down the -Z axis!
5658    /// <https://stereokit.net/Pages/StereoKit/Pose/Forward.html>
5659    ///
5660    /// ### Examples
5661    /// ```
5662    /// use stereokit_rust::maths::{Vec3,  Pose};
5663    ///
5664    /// let pose1 = Pose::default();
5665    /// assert_eq!(pose1.get_forward(), Vec3::NEG_Z);    
5666    ///
5667    /// let pose2 = Pose::look_at(Vec3::new(1.0, 0.0, 0.0), Vec3::new(0.0, 0.0, 0.0));
5668    /// assert_eq!(pose2.get_forward(), Vec3::NEG_X);    
5669    #[inline]
5670    pub fn get_forward(&self) -> Vec3 {
5671        self.orientation.mul_vec3(Vec3::FORWARD)
5672    }
5673
5674    /// This creates a ray starting at the Pose’s position, and pointing in the ‘Forward’ direction. The Ray
5675    /// direction is a unit vector/normalized.
5676    /// <https://stereokit.net/Pages/StereoKit/Pose/Ray.html>
5677    ///
5678    /// see also [`Ray`]
5679    /// ### Examples
5680    /// ```
5681    /// use stereokit_rust::maths::{Vec3, Pose, Ray};
5682    ///
5683    /// let pose1 = Pose::default();
5684    /// let ray_forward = Ray::new( Vec3::ZERO, Vec3::NEG_Z);
5685    /// assert_eq!(pose1.get_ray(), ray_forward);    
5686    ///
5687    /// let pose2 = Pose::look_at(Vec3::new(1.0, 0.0, 0.0), Vec3::new(1.0, 2.0, 0.0));
5688    /// let ray_to_the_left = Ray::new(Vec3::X, Vec3::Y);
5689    /// assert_eq!(pose2.get_ray(), ray_to_the_left);   
5690    #[inline]
5691    pub fn get_ray(&self) -> Ray {
5692        Ray { position: self.position, direction: self.orientation.mul_vec3(Vec3::FORWARD) }
5693    }
5694
5695    /// Calculates the right (+X) direction from this pose. This is done by multiplying the orientation with Vec3.Right.
5696    /// <https://stereokit.net/Pages/StereoKit/Pose/Right.html>
5697    ///
5698    /// ### Examples
5699    /// ```
5700    /// use stereokit_rust::maths::{Vec3, Pose, Ray};
5701    ///
5702    /// let pose1 = Pose::default();
5703    /// assert_eq!(pose1.get_right(), Vec3::X);    
5704    ///
5705    /// let pose2 = Pose::look_at(Vec3::new(1.0, 0.0, 0.0), Vec3::new(1.0, 2.0, 3.0));
5706    /// assert_eq!(pose2.get_right(), Vec3::NEG_X);  
5707    /// ```
5708    #[inline]
5709    pub fn get_right(&self) -> Vec3 {
5710        self.orientation.mul_vec3(Vec3::RIGHT)
5711    }
5712
5713    /// Calculates the up (+Y) direction from this pose. This is done by multiplying the orientation with Vec3.Up.
5714    /// <https://stereokit.net/Pages/StereoKit/Pose/Up.html>
5715    ///
5716    /// ### Examples
5717    /// ```
5718    /// use stereokit_rust::maths::{Vec3, Pose, Ray};
5719    ///
5720    /// let pose1 = Pose::default();
5721    /// assert_eq!(pose1.get_up(), Vec3::Y);    
5722    ///
5723    /// let pose2 = Pose::look_at(Vec3::new(1.0, 0.0, 0.0), Vec3::new(2.0, 0.0, 3.0));
5724    /// assert_eq!(pose2.get_up(), Vec3::Y);  
5725    /// ```
5726    #[inline]
5727    pub fn get_up(&self) -> Vec3 {
5728        self.orientation.mul_vec3(Vec3::UP)
5729    }
5730}
5731
5732impl Display for Pose {
5733    /// A string representation of the Pose, in the format of “position, Forward”. Mostly for debug visualization.
5734    /// <https://stereokit.net/Pages/StereoKit/Pose/ToString.html>
5735    /// ### Examples
5736    /// ```
5737    /// use stereokit_rust::maths::{Vec3, Pose};
5738    ///
5739    /// let pose = Pose::new([1.1, 2.0, 3.0], Some([0.0, 90.0, 0.0].into()));
5740    /// assert_eq!(format!("{}", pose),
5741    ///            "[position:[x:1.1, y:2, z:3] forward:[x:0, y:0.70710677, z:0, w:0.7071067]]");
5742    /// ```
5743    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5744        write!(f, "[position:{} forward:{}]", self.position, self.orientation)
5745    }
5746}
5747
5748/// Represents a sphere in 3D space! Composed of a center point and a radius, can be used for raycasting, collision,
5749/// visibility, and other things!
5750/// <https://stereokit.net/Pages/StereoKit/Sphere.html>
5751///
5752/// ### Examples
5753/// ```
5754/// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
5755/// use stereokit_rust::{maths::{Vec3, Matrix, Sphere, Ray}, system::Lines,
5756///     mesh::Mesh, material::Material, util::named_colors};
5757///
5758/// let sphere = Sphere::new(Vec3::ZERO, 0.5);
5759/// let sphere_mesh = Mesh::generate_sphere(sphere.radius * 2.0, Some(12));
5760/// let mut material_sphere = Material::pbr().copy();
5761/// material_sphere.color_tint(named_colors::GOLD)
5762///                .border_size(0.05);
5763///
5764/// let scale = 0.1;
5765/// let transform = Matrix::t(sphere.center);
5766/// let ray_x = Ray::new(Vec3::X, Vec3::NEG_X);
5767/// let ray_y = Ray::new(Vec3::Y, Vec3::NEG_Y);
5768/// let contact_x = sphere.intersect(ray_x).expect("X Should be there");
5769/// let contact_y = sphere.intersect(ray_y).expect("Y Should be there");
5770///
5771/// assert_eq!(contact_x, Vec3::X * sphere.radius);
5772/// assert_eq!(contact_y, Vec3::Y * sphere.radius);
5773///
5774/// filename_scr = "screenshots/sphere.jpeg";
5775/// test_screenshot!( // !!!! Get a proper main loop !!!!
5776///     sphere_mesh.draw(token, &material_sphere, transform, None, None);
5777///     Lines::add_ray(token, ray_x, 0.30, named_colors::RED, None, 0.04);
5778///     Lines::add_ray(token, ray_y, 0.30, named_colors::GREEN, None, 0.04);
5779/// );
5780/// ```
5781/// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/sphere.jpeg" alt="screenshot" width="200">
5782#[derive(Copy, Clone, Debug, Default, PartialEq)]
5783#[repr(C)]
5784pub struct Sphere {
5785    /// Center of the sphere
5786    pub center: Vec3,
5787    ///Distance from the center, to the surface of the sphere, in meters. Half the diameter.
5788    pub radius: f32,
5789}
5790/// AsRef
5791impl AsRef<Sphere> for Sphere {
5792    fn as_ref(&self) -> &Sphere {
5793        self
5794    }
5795}
5796
5797unsafe extern "C" {
5798    pub fn sphere_ray_intersect(sphere: Sphere, ray: Ray, out_pt: *mut Vec3) -> Bool32T;
5799    pub fn sphere_point_contains(sphere: Sphere, pt: Vec3) -> Bool32T;
5800}
5801
5802impl Sphere {
5803    /// Creates a Sphere directly from the ax + by + cz + d = 0 formula!
5804    /// <https://stereokit.net/Pages/StereoKit/Sphere.html>
5805    ///
5806    /// ### Examples
5807    /// ```
5808    /// use stereokit_rust::maths::{Vec3, Sphere};
5809    ///
5810    /// let sphere = Sphere::new(Vec3::ZERO, 0.5);
5811    /// let sphere_b = Sphere {center : Vec3::ZERO, radius : 0.5};
5812    ///
5813    /// assert_eq!(sphere, sphere_b);
5814    /// ```
5815    #[inline]
5816    pub fn new<V: Into<Vec3>>(center: V, radius: f32) -> Sphere {
5817        Sphere { center: center.into(), radius }
5818    }
5819
5820    /// A fast check to see if the given point is contained in or on a sphere!
5821    /// <https://stereokit.net/Pages/StereoKit/Sphere/Contains.html>
5822    ///
5823    /// see also [`sphere_point_contains`]
5824    /// ### Examples
5825    /// ```
5826    /// use stereokit_rust::maths::{Vec3, Sphere};
5827    ///
5828    /// let sphere = Sphere::new(Vec3::ZERO, 0.5);
5829    ///
5830    /// assert!(sphere.contains(Vec3::ONE * 0.28), "Should be contained");
5831    /// assert!(!sphere.contains(Vec3::ONE * 0.29), "Should not be contained");
5832    /// ```    
5833    #[inline]
5834    pub fn contains<V: Into<Vec3>>(&self, point: V) -> bool {
5835        unsafe { sphere_point_contains(*self, point.into()) != 0 }
5836    }
5837
5838    /// Intersects a ray with this sphere, and finds if they intersect, and if so, where that intersection is!
5839    /// This only finds the closest intersection point to the origin of the ray.
5840    /// <https://stereokit.net/Pages/StereoKit/Sphere/Intersect.html>
5841    /// * ray - A ray to intersect with
5842    ///
5843    /// Returns the closest intersection point to the ray's origin. Or None it there is no intersection.
5844    /// see also [`sphere_ray_intersect`] same as [`Ray::intersect_sphere`]
5845    /// ### Examples
5846    /// ```
5847    /// use stereokit_rust::maths::{Vec3, Sphere, Ray};
5848    ///
5849    /// let sphere = Sphere::new(Vec3::ZERO, 0.5);
5850    ///
5851    /// assert_eq!(sphere.intersect(Ray::new(Vec3::Z, Vec3::NEG_Z)), Some(Vec3::Z * 0.5));
5852    /// assert_ne!(sphere.intersect(Ray::new(Vec3::Z, Vec3::Z)),     None);
5853    /// ```
5854    #[inline]
5855    pub fn intersect(&self, ray: Ray) -> Option<Vec3> {
5856        let mut pt = Vec3::default();
5857        match unsafe { sphere_ray_intersect(*self, ray, &mut pt) != 0 } {
5858            true => Some(pt),
5859            false => None,
5860        }
5861    }
5862}
5863impl Display for Sphere {
5864    /// Creates a text description of the Sphere, in the format of “[center:X radius:X]”
5865    /// ### Examples
5866    /// ```
5867    /// use stereokit_rust::maths::{Vec3, Sphere};
5868    ///
5869    /// let sphere = Sphere::new([1.1, 2.0, 3.0], 4.0);
5870    /// assert_eq!(format!("{}", sphere),
5871    ///            "[center:[x:1.1, y:2, z:3] radius:4]");
5872    /// ```
5873    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5874        write!(f, "[center:{} radius:{}]", self.center, self.radius)
5875    }
5876}
5877/// A pretty straightforward 2D rectangle, defined by the top left corner of the rectangle, and its width/height.
5878/// <https://stereokit.net/Pages/StereoKit/Rect.html>
5879#[derive(Debug, Copy, Clone, PartialEq)]
5880#[repr(C)]
5881pub struct Rect {
5882    /// The X axis position of the top left corner of the rectangle.
5883    pub x: f32,
5884    /// The Y axis position of the top left corner of the rectangle.
5885    pub y: f32,
5886    /// The width of the rectangle.
5887    pub width: f32,
5888    /// The height of the rectangle.
5889    pub height: f32,
5890}
5891
5892impl Default for Rect {
5893    fn default() -> Self {
5894        Self { x: 0.0, y: 0.0, width: 1.0, height: 1.0 }
5895    }
5896}
5897
5898impl Rect {
5899    /// Create a 2D rectangle, defined by the top left corner of the rectangle, and its width/height.
5900    /// <https://stereokit.net/Pages/StereoKit/Rect/Rect.html>
5901    ///
5902    /// ### Examples
5903    /// ```
5904    /// use stereokit_rust::maths::{Rect};
5905    ///
5906    /// let rect = Rect::new(0.0, 0.0, 1920.0, 1080.0);
5907    /// let rect_b = Rect {x:0.0, y:0.0, width:1920.0, height:1080.0};
5908    ///
5909    /// assert_eq!(rect, rect_b);
5910    /// ```
5911    pub const fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
5912        Self { x, y, width, height }
5913    }
5914}
5915
5916/// A position and a direction indicating a ray through space! This is a great tool for intersection testing with
5917/// geometrical shapes.
5918/// <https://stereokit.net/Pages/StereoKit/Ray.html>
5919///
5920/// ### Examples
5921/// ```
5922/// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
5923/// use stereokit_rust::{maths::{Vec3, Matrix, Ray}, model::Model, system::Lines,
5924///     mesh::Mesh, material::Material, util::named_colors};
5925///
5926/// let point = Mesh::sphere();
5927/// let mut material_point =Material::unlit();
5928/// let model = Model::from_file("center.glb", None).unwrap().copy();
5929/// let cube = Mesh::cube();
5930/// let mut material_cube =Material::ui_box();
5931/// material_cube.color_tint(named_colors::GOLD)
5932///              .border_size(0.05);
5933///
5934/// let center = Vec3::new(0.0, -2.5, -2.5);
5935/// let bounds = model.get_bounds();
5936/// let transform = Matrix::t_r(center, [0.0, 220.0, 0.0]);
5937/// let transform_cube = Matrix::t_s( bounds.center, bounds.dimensions) * transform;
5938/// let inv = transform.get_inverse();
5939///
5940/// let ray_x = Ray::new(Vec3{x:4.0, y: 0.0, z:  -2.5}, Vec3::NEG_X);
5941/// let inv_ray_x = inv.transform_ray(ray_x);
5942/// let inv_contact_x = bounds.intersect(inv_ray_x).expect("should be a point of contact");
5943/// let contact_x = transform.transform_point(inv_contact_x);
5944/// let transform_point_x = Matrix::t_s(contact_x, Vec3::ONE * 0.3);
5945///
5946/// filename_scr = "screenshots/ray.jpeg";
5947/// test_screenshot!( // !!!! Get a proper main loop !!!!
5948///     model.draw(token, transform, None, None);
5949///     cube.draw(token, &material_cube, transform_cube, None, None);
5950///     Lines::add_ray(token, ray_x, 1.5, named_colors::WHITE, None, 0.2);
5951///     point.draw(token, &material_point, transform_point_x, Some(named_colors::RED.into()), None );
5952/// );
5953/// ```
5954/// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/ray.jpeg" alt="screenshot" width="200">
5955#[derive(Default, Debug, Copy, Clone, PartialEq)]
5956#[repr(C)]
5957pub struct Ray {
5958    /// The position or origin point of the Ray.
5959    pub position: Vec3,
5960    /// The direction the ray is facing, typically does not require being a unit vector, or normalized direction.
5961    pub direction: Vec3,
5962}
5963
5964unsafe extern "C" {
5965    pub fn ray_intersect_plane(ray: Ray, plane_pt: Vec3, plane_normal: Vec3, out_t: *mut f32) -> Bool32T;
5966    pub fn ray_from_mouse(screen_pixel_pos: Vec2, out_ray: *mut Ray) -> Bool32T;
5967    pub fn ray_point_closest(ray: Ray, pt: Vec3) -> Vec3;
5968}
5969
5970impl Ray {
5971    /// Ray Zero is the default
5972    pub const ZERO: Self = Ray { position: Vec3::ZERO, direction: Vec3::ZERO };
5973
5974    /// Basic initialization constructor! Just copies the parameters into the fields.
5975    /// <https://stereokit.net/Pages/StereoKit/Ray/Ray.html>
5976    /// * position - The position or origin point of the Ray.
5977    /// * direction - The direction the ray is facing, typically does not require being a unit vector, or normalized
5978    ///   direction.
5979    ///
5980    /// ### Examples
5981    /// ```
5982    /// use stereokit_rust::maths::{Vec3, Ray};
5983    ///
5984    /// let ray = Ray::new(Vec3::ZERO, Vec3::ONE);
5985    /// let ray_b = Ray {position: Vec3::ZERO, direction: Vec3::ONE};
5986    ///
5987    /// assert_eq!(ray, ray_b);
5988    /// ```
5989    #[inline]
5990    pub fn new<V: Into<Vec3>>(pos: V, dir: V) -> Self {
5991        Self { position: pos.into(), direction: dir.into() }
5992    }
5993
5994    /// A convenience function that creates a ray from point a, towards point b. Resulting direction is not normalized.
5995    /// <https://stereokit.net/Pages/StereoKit/Ray/FromTo.html>
5996    /// * a - Ray starting point.
5997    /// * b - Location the ray is pointing towards.
5998    ///
5999    /// Returns a ray from point a to point b. Not normalized.
6000    ///
6001    /// ### Examples
6002    /// ```
6003    /// use stereokit_rust::maths::{Vec3, Ray};
6004    ///
6005    /// let ray = Ray::new(Vec3::ZERO, Vec3::ONE);
6006    /// let ray_b = Ray::from_to( Vec3::ZERO, Vec3::ONE);
6007    ///
6008    /// assert_eq!(ray, ray_b);
6009    /// ```
6010    #[inline]
6011    pub fn from_to<V: Into<Vec3>>(a: V, b: V) -> Ray {
6012        let position = a.into();
6013        let direction = b.into() - position;
6014        Ray { position, direction }
6015    }
6016
6017    /// Gets a point along the ray! This is basically just position + direction*percent. If Ray.direction is
6018    /// normalized, then percent is functionally distance, and can be used to find the point a certain distance
6019    /// out along the ray.
6020    /// <https://stereokit.net/Pages/StereoKit/Ray/At.html>
6021    /// * percent - How far along the ray should we get the  point at? This is in multiples of self.direction's
6022    ///   magnitude. If self.direction is normalized, this is functionally the distance.
6023    ///
6024    /// Returns the point at position + direction*percent
6025    ///
6026    /// ### Examples
6027    /// ```
6028    /// use stereokit_rust::maths::{Vec3, Ray};
6029    ///
6030    /// let ray = Ray::new(Vec3::ZERO, Vec3::ONE);
6031    ///
6032    /// assert_eq!(ray.get_at(3.0), Vec3::ONE * 3.0);
6033    /// ```
6034    #[inline]
6035    pub fn get_at(&self, percent: f32) -> Vec3 {
6036        self.position + self.direction * percent
6037    }
6038
6039    /// Calculates the point on the Ray that’s closest to the given point! This will be clamped if the point is behind
6040    /// the ray's origin.
6041    /// <https://stereokit.net/Pages/StereoKit/Ray/Closest.html>
6042    /// * to - Any point in the same coordinate space as the  Ray.
6043    ///
6044    /// Returns the point on the ray that's closest to the given point.
6045    /// see also [`ray_point_closest`]
6046    ///
6047    /// ### Examples
6048    /// ```
6049    /// use stereokit_rust::maths::{Vec3, Plane, Ray};
6050    ///
6051    /// let ray = Ray::new(Vec3::ZERO, Vec3::ONE);
6052    ///
6053    /// assert_eq!(ray.closest(Vec3::Z), Vec3::ONE / 3.0);
6054    /// ```
6055    #[inline]
6056    pub fn closest<V: Into<Vec3>>(&self, to: V) -> Vec3 {
6057        unsafe { ray_point_closest(*self, to.into()) }
6058    }
6059
6060    /// Checks the intersection of this ray with a plane!
6061    /// <https://stereokit.net/Pages/StereoKit/Ray/Intersect.html>
6062    /// * plane - Any plane you want to intersect with.
6063    ///
6064    /// Returns intersection point if there's an intersection information or None if there's no intersection
6065    /// see also [`plane_ray_intersect`] same as [`Plane::intersect`]
6066    ///
6067    /// ### Examples
6068    /// ```
6069    /// use stereokit_rust::maths::{Vec3, Plane, Ray};
6070    ///
6071    /// let ray = Ray::new(Vec3::ZERO, Vec3::ONE);
6072    /// let plane = Plane::new(Vec3::NEG_Y, 2.5);
6073    ///
6074    /// assert_eq!(ray.intersect_plane(plane), Some(Vec3::ONE * 2.5));
6075    /// ```
6076    #[inline]
6077    pub fn intersect_plane(&self, plane: Plane) -> Option<Vec3> {
6078        let mut pt = Vec3::default();
6079        match unsafe { plane_ray_intersect(plane, *self, &mut pt) != 0 } {
6080            true => Some(pt),
6081            false => None,
6082        }
6083    }
6084
6085    /// Checks the intersection of this ray with a sphere!
6086    /// <https://stereokit.net/Pages/StereoKit/Ray/Intersect.html>
6087    /// * sphere - Any sphere you want to intersect with.
6088    ///
6089    /// Returns the closest intersection point to the ray origin if there's an intersection information or None if
6090    /// there's no intersection
6091    /// see also [`sphere_ray_intersect`] same as [`Sphere::intersect`]
6092    ///
6093    /// ### Examples
6094    /// ```
6095    /// use stereokit_rust::maths::{Vec3, Sphere, Ray};
6096    ///
6097    /// let ray = Ray::new(Vec3::ZERO, Vec3::ONE);
6098    /// let sphere = Sphere::new(Vec3::Y, 0.5);
6099    ///
6100    /// assert_eq!(ray.intersect_sphere(sphere), Some(Vec3::ONE * 0.5));
6101    /// ```
6102    #[inline]
6103    pub fn intersect_sphere(&self, sphere: Sphere) -> Option<Vec3> {
6104        let mut pt = Vec3::default();
6105        match unsafe { sphere_ray_intersect(sphere, *self, &mut pt) != 0 } {
6106            true => Some(pt),
6107            false => None,
6108        }
6109    }
6110
6111    /// Checks the intersection of this ray with a bounding box!
6112    /// <https://stereokit.net/Pages/StereoKit/Ray/Intersect.html>
6113    /// * bounds - Any bounds you want to intersect with.
6114    ///
6115    /// Returns the closest intersection point to the ray origin if there's an intersection information or None if
6116    /// there's no intersection
6117    /// see also [`bounds_ray_intersect`] same as [`Bounds::intersect`]
6118    /// ### Examples
6119    /// ```
6120    /// use stereokit_rust::maths::{Vec3, Bounds, Matrix, Ray};
6121    ///
6122    /// // A cube of 1 meter per side at this position, aligned with x y and z axis.
6123    /// let box_transform = Matrix::t([10.0, 1.0, 2.0]);
6124    /// let box_bounds = Bounds::bounds_centered([1.0,1.0,1.0]);
6125    ///
6126    /// let inv = box_transform.get_inverse();
6127    /// let ray1 = inv.transform_ray(Ray::new([10.2, 1.3, 2.4],[0.0, 1.0, 0.0]));
6128    /// let ray2 = inv.transform_ray(Ray::new([10.9, 1.8, 2.6],[0.0, 0.0, 1.0]));
6129    /// let ray3 = inv.transform_ray(Ray::new([10.5, 2.0, 2.7],[1.0, 0.0, 1.0]));
6130    ///
6131    /// assert!(ray1.intersect_bounds(box_bounds).is_some(),  "should be a point of contact");
6132    /// assert_eq!(ray2.intersect_bounds(box_bounds), None);
6133    /// assert_eq!(ray3.intersect_bounds(box_bounds), None);
6134    ///
6135    /// // We want the contact point for ray1
6136    /// let contact_point = box_bounds.intersect(ray1)
6137    ///         .expect ("There should be a point of contact");
6138    ///
6139    /// let contact_point = box_transform.transform_point(contact_point);
6140    /// assert_eq!(contact_point,  [10.2, 1.3, 2.4 ].into());
6141    /// ```
6142    #[inline]
6143    pub fn intersect_bounds(&self, bounds: Bounds) -> Option<Vec3> {
6144        let mut pt = Vec3::default();
6145        match unsafe { bounds_ray_intersect(bounds, *self, &mut pt) != 0 } {
6146            true => Some(pt),
6147            false => None,
6148        }
6149    }
6150
6151    /// Checks the intersection point of this ray and a Mesh with collision data stored on the CPU. A mesh without
6152    /// collision data will always return false. Ray must be in model space, intersection point will be in model
6153    /// space too. You can use the inverse of the mesh’s world transform matrix to bring the ray into model space,
6154    /// see the example in the docs!
6155    /// <https://stereokit.net/Pages/StereoKit/Ray/Intersect.html>
6156    /// * mesh - A mesh containing collision data on the CPU. You can check this with mesh.get_keep_data().
6157    /// * cull - If None has default value of Cull::Back.
6158    ///
6159    /// Returns a tuple with
6160    /// - The intersection point of the ray and the mesh, if an intersection occurs. This is in model space, and must be
6161    ///   transformed back into world space later.
6162    /// - The indice of the mesh where the intersection occurs.
6163    ///
6164    /// see also [`mesh_ray_intersect`] [`Ray::intersect_mesh_to_ptr`]  same as [`Mesh::intersect`]    
6165    /// ### Examples
6166    /// ```
6167    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
6168    /// use stereokit_rust::{maths::{Vec3, Matrix, Quat, Ray}, system::Lines,
6169    ///     util::{named_colors}, mesh::Mesh, material::{Material, Cull}};
6170    ///
6171    /// // Create Meshes
6172    /// let cube = Mesh::generate_cube(Vec3::ONE * 0.8, None);
6173    /// let sphere = Mesh::generate_sphere(1.0, Some(4));
6174    ///
6175    /// let material = Material::pbr().copy();
6176    /// let transform = Matrix::r(Quat::from_angles(40.0, 50.0, 20.0));
6177    /// let inv = transform.get_inverse();
6178    ///
6179    /// let ray = Ray::new([-3.0, 2.0, 0.5 ], [3.0, -2.0, -0.25]);
6180    /// let inv_ray = inv.transform_ray(ray);
6181    ///
6182    /// let (contact_sphere, ind_sphere) = inv_ray.intersect_mesh( &sphere, Some(Cull::Front))
6183    ///     .expect("Ray should touch sphere");
6184    /// let (contact_cube, ind_cube) = inv_ray.intersect_mesh( &cube, Some(Cull::Back))
6185    ///     .expect("Ray should touch cube");
6186    /// assert_eq!(ind_sphere, 672);
6187    /// assert_eq!(ind_cube, 9);
6188    ///
6189    /// let transform_contact_sphere = Matrix::t_s(
6190    ///     transform.transform_point(contact_sphere), Vec3::ONE * 0.1);
6191    /// let transform_contact_cube = Matrix::t_s(
6192    ///     transform.transform_point(contact_cube), Vec3::ONE * 0.1);
6193    ///
6194    /// filename_scr = "screenshots/intersect_meshes.jpeg";
6195    /// test_screenshot!( // !!!! Get a proper main loop !!!!
6196    ///     cube.draw(token, &material, transform, Some(named_colors::CYAN.into()), None);
6197    ///     sphere.draw(token, &material, transform, Some(named_colors::BLUE.into()), None);
6198    ///     Lines::add_ray(token, ray, 2.2, named_colors::WHITE, None, 0.02);
6199    ///     sphere.draw(token, &material, transform_contact_cube,
6200    ///                 Some(named_colors::YELLOW.into()), None );
6201    ///     sphere.draw(token, &material, transform_contact_sphere,
6202    ///                 Some(named_colors::RED.into()), None );
6203    /// );
6204    /// ```
6205    /// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/intersect_meshes.jpeg" alt="screenshot" width="200">
6206    #[inline]
6207    pub fn intersect_mesh(&self, mesh: &Mesh, cull: Option<Cull>) -> Option<(Vec3, VindT)> {
6208        let mut out_ray = Ray::default();
6209        let mut out_inds = 0;
6210        let cull = cull.unwrap_or(Cull::Back);
6211
6212        match unsafe { mesh_ray_intersect(mesh.0.as_ptr(), *self, cull, &mut out_ray, &mut out_inds) != 0 } {
6213            true => Some((out_ray.position, out_inds)),
6214            false => None,
6215        }
6216    }
6217
6218    /// Checks the intersection point of this ray and a Mesh with collision data stored on the CPU. A mesh without
6219    /// collision data will always return false. Ray must be in model space, intersection point will be in model
6220    /// space too. You can use the inverse of the mesh’s world transform matrix to bring the ray into model space,
6221    /// see the example in the docs!
6222    /// <https://stereokit.net/Pages/StereoKit/Ray/Intersect.html>
6223    /// * mesh - A mesh containing collision data on the CPU. You can check this with mesh.get_keep_data()
6224    /// * out_model_space_at - The intersection point and surface direction of the ray and the mesh, if an intersection
6225    ///   occurs. This is in model space, and must be transformed back into world space later. Direction is not
6226    ///   guaranteed to be normalized, especially if your own model->world transform contains scale/skew in it.
6227    /// * out_start_inds - The index of the first index of the triangle that was hit
6228    /// * cull - How should intersection work with respect to the direction the triangles are facing? Should we skip
6229    ///   triangles that are facing away from the ray, or don't skip anything? A good default would be Cull.Back.
6230    ///   If None has default value of Cull::Back.
6231    ///
6232    /// Returns true if an intersection occurs, false otherwise!
6233    /// see also [`mesh_ray_intersect`] [`Ray::intersect_mesh`] same as [`Mesh::intersect_to_ptr`]  
6234    /// ### Examples
6235    /// ```
6236    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
6237    /// use stereokit_rust::{maths::{Vec3, Matrix, Quat, Ray}, system::Lines,
6238    ///     util::{named_colors}, mesh::Mesh, material::{Material, Cull}};
6239    ///
6240    /// // Create Meshes
6241    /// let cube = Mesh::generate_cube(Vec3::ONE * 0.8, None);
6242    /// let sphere = Mesh::generate_sphere(1.0, Some(4));
6243    ///
6244    /// let material = Material::pbr().copy();
6245    /// let transform = Matrix::r(Quat::from_angles(40.0, 50.0, 20.0));
6246    /// let inv = transform.get_inverse();
6247    ///
6248    /// let ray = Ray::new([-3.0, 2.0, 0.5 ], [3.0, -2.0, -0.25]);
6249    /// let inv_ray = inv.transform_ray(ray);
6250    ///
6251    /// let (mut contact_sphere_ray, mut ind_sphere) = (Ray::default(), 0u32);
6252    /// assert!(inv_ray.intersect_mesh_to_ptr(
6253    ///             &sphere, Some(Cull::Front),
6254    ///             &mut contact_sphere_ray, &mut ind_sphere)
6255    ///     ,"Ray should touch sphere");
6256    ///
6257    /// let (mut contact_cube_ray, mut ind_cube) = (Ray::default(), 0u32);
6258    /// assert!( inv_ray.intersect_mesh_to_ptr(
6259    ///             &cube, Some(Cull::Back),
6260    ///             &mut contact_cube_ray, &mut ind_cube)
6261    ///     ,"Ray should touch cube");
6262    ///
6263    /// assert_eq!(ind_sphere, 672);
6264    /// assert_eq!(ind_cube, 9);
6265    ///
6266    /// assert_eq!(transform.transform_ray(contact_sphere_ray),
6267    ///         Ray { position:  Vec3 { x: 0.36746234, y: -0.244975, z: 0.21937825 },
6268    ///               direction: Vec3 { x: 0.58682406, y: -0.6427875, z: 0.49240398 }});
6269    /// assert_eq!(transform.transform_ray(contact_cube_ray),
6270    ///         Ray { position:  Vec3 { x: -0.39531866, y: 0.26354572, z: 0.2829433 },
6271    ///               direction: Vec3 { x: -0.77243483, y: -0.2620026, z: 0.57853174 } });
6272    /// ```
6273    #[inline]
6274    #[allow(clippy::not_unsafe_ptr_arg_deref)]
6275    pub fn intersect_mesh_to_ptr(
6276        &self,
6277        mesh: &Mesh,
6278        cull: Option<Cull>,
6279        out_model_space_at: *mut Ray,
6280        out_start_inds: *mut u32,
6281    ) -> bool {
6282        let cull = cull.unwrap_or(Cull::Back);
6283        unsafe { mesh_ray_intersect(mesh.0.as_ptr(), *self, cull, out_model_space_at, out_start_inds) != 0 }
6284    }
6285
6286    /// Checks the intersection point of this ray and the Solid flagged Meshes in the Model’s visual nodes. Ray must
6287    /// be in model space, intersection point will be in model space too. You can use the inverse of the mesh’s world
6288    /// transform matrix to bring the ray into model space, see the example in the docs!
6289    /// <https://stereokit.net/Pages/StereoKit/Ray/Intersect.html>
6290    /// * model - Any Model that may or may not contain Solid flagged nodes, and Meshes with collision data.
6291    /// * cull - If None has default value of Cull::Back.
6292    ///
6293    /// Returns the intersection point of the ray and the model, if an intersection occurs. This is in model space, and
6294    /// must be transformed back into world space later.
6295    /// see also [`model_ray_intersect`] [`Ray::intersect_model_to_ptr`] same as [`Model::intersect`]
6296    /// ### Examples
6297    /// ```
6298    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
6299    /// use stereokit_rust::{maths::{Vec3, Matrix, Ray}, model::Model, system::Lines,
6300    ///     mesh::Mesh, material::{Material, Cull}, util::named_colors};
6301    ///
6302    /// let model = Model::from_file("center.glb", None).unwrap().copy();
6303    /// let transform = Matrix::t_r([0.0,-2.25,-2.00], [0.0, 140.0, 0.0]);
6304    ///
6305    /// let inv_ray = Ray::new([1.0, 2.0, -3.0], [-1.5, 2.0, 3.0]);
6306    ///
6307    /// let contact_model = inv_ray.intersect_model( &model, Some(Cull::Back))
6308    ///     .expect("Ray should touch model");
6309    ///
6310    /// let ray = transform.transform_ray(inv_ray);
6311    /// let transform_contact_model = Matrix::t(transform.transform_point(contact_model));
6312    /// let point = Mesh::generate_sphere(0.2, Some(2));
6313    /// let material = Material::pbr();
6314    ///
6315    /// filename_scr = "screenshots/intersect_model.jpeg";
6316    /// test_screenshot!( // !!!! Get a proper main loop !!!!
6317    ///     model.draw(token, transform, None, None);
6318    ///     Lines::add_ray(token, ray, 1.2, named_colors::WHITE, None, 0.02);
6319    ///     point.draw(token, &material, transform_contact_model,
6320    ///                Some(named_colors::RED.into()), None );
6321    /// );
6322    /// ```
6323    /// <img src="https://raw.githubusercontent.com/mvvvv/StereoKit-rust/refs/heads/master/screenshots/intersect_model.jpeg" alt="screenshot" width="200">
6324    #[inline]
6325    pub fn intersect_model(&self, model: &Model, cull: Option<Cull>) -> Option<Vec3> {
6326        let mut out_ray = Ray::default();
6327        let cull = cull.unwrap_or(Cull::Back);
6328
6329        match unsafe { model_ray_intersect(model.0.as_ptr(), *self, cull, &mut out_ray) != 0 } {
6330            true => Some(out_ray.position),
6331            false => None,
6332        }
6333    }
6334
6335    /// Checks the intersection point of this ray and the Solid flagged Meshes in the Model’s visual nodes. Ray must
6336    /// be in model space, intersection point will be in model space too. You can use the inverse of the mesh’s world
6337    /// transform matrix to bring the ray into model space, see the example in the docs!
6338    /// <https://stereokit.net/Pages/StereoKit/Ray/Intersect.html>
6339    /// * model - Any Model that may or may not contain Solid flagged nodes, and Meshes with collision data.
6340    /// * cull - If None has default value of Cull::Back.
6341    /// * out_model_space_at  - The intersection point and surface direction of the ray and the model, if an intersection
6342    ///   occurs. This is in model space, and must be transformed back into world space later. Direction is not
6343    ///   guaranteed to be normalized, especially if your own model->world transform contains scale/skew in it.
6344    ///
6345    /// Returns - true if an intersection occurs, false otherwise!
6346    /// see also [`model_ray_intersect`] [`Ray::intersect_model`] same as [`Model::intersect_to_ptr`]
6347    /// ### Examples
6348    /// ```
6349    /// # stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!
6350    /// use stereokit_rust::{maths::{Vec3, Matrix, Ray}, model::Model,
6351    ///     mesh::Mesh, material::{Material, Cull}, util::named_colors};
6352    ///
6353    /// let model = Model::from_file("center.glb", None).unwrap().copy();
6354    /// let transform = Matrix::t_r([0.0,-2.25,-2.00], [0.0, 140.0, 0.0]);
6355    ///
6356    /// let inv_ray = Ray::new([1.0, 2.0, -3.0], [-1.5, 2.0, 3.0]);
6357    ///
6358    /// let mut inv_contact_model_ray = Ray::default();
6359    /// assert!(inv_ray.intersect_model_to_ptr( &model, Some(Cull::Back), &mut inv_contact_model_ray)
6360    ///     ,"Ray should touch model");
6361    ///
6362    /// let contact_model_ray = transform.transform_ray(inv_contact_model_ray);
6363    /// assert_eq!(contact_model_ray,
6364    ///            Ray { position:  Vec3 { x: -0.3688636, y: 1.2613544, z: -1.3526915 },
6365    ///                  direction: Vec3 { x: -0.4004621, y: -0.016381653, z: 0.9161662 } });
6366    #[inline]
6367    #[allow(clippy::not_unsafe_ptr_arg_deref)]
6368    pub fn intersect_model_to_ptr(&self, model: &Model, cull: Option<Cull>, out_model_space_at: *mut Ray) -> bool {
6369        let cull = cull.unwrap_or(Cull::Back);
6370        unsafe { model_ray_intersect(model.0.as_ptr(), *self, cull, out_model_space_at) != 0 }
6371    }
6372}
6373
6374impl Display for Ray {
6375    /// Creates a text description of the Ray, in the format of “[position:X direction:X]”
6376    /// <https://stereokit.net/Pages/StereoKit/Ray/ToString.html>
6377    /// ### Examples
6378    /// ```
6379    /// use stereokit_rust::maths::{Vec3, Ray};
6380    ///
6381    /// let ray = Ray::new([1.1, 2.0, 3.0], [4.0, 5.0, 6.0]);
6382    /// assert_eq!(format!("{}", ray),
6383    ///            "[position:[x:1.1, y:2, z:3] direction:[x:4, y:5, z:6]]");
6384    /// ```
6385    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6386        write!(f, "[position:{} direction:{}]", self.position, self.direction)
6387    }
6388}