vector_traits/
cgmath_impl.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2023, 2025 lacklustr@protonmail.com https://github.com/eadf
3
4// This file is part of vector-traits.
5
6#[cfg(test)]
7mod tests;
8
9use crate::{cgmath, prelude::*};
10use approx::{AbsDiffEq, UlpsEq};
11use cgmath::{EuclideanSpace, MetricSpace, SquareMatrix, Transform};
12use std::borrow::Borrow;
13
14#[derive(Debug, Copy, Clone)]
15pub struct Aabb2<T> {
16    min: cgmath::Vector2<T>,
17    max: cgmath::Vector2<T>,
18}
19
20macro_rules! impl_aabb2 {
21    ($vec_type:ty, $scalar_type:ty) => {
22        impl Default for Aabb2<$scalar_type> {
23            fn default() -> Self {
24                Self {
25                    min: <$vec_type>::splat(<$scalar_type>::INFINITY),
26                    max: <$vec_type>::splat(<$scalar_type>::NEG_INFINITY),
27                }
28            }
29        }
30
31        impl crate::prelude::Aabb2 for Aabb2<$scalar_type> {
32            type Vector = $vec_type;
33
34            fn from_point(point: Self::Vector) -> Self {
35                Self {
36                    min: point,
37                    max: point,
38                }
39            }
40
41            #[inline(always)]
42            fn from_corners(min: Self::Vector, max: Self::Vector) -> Self {
43                let mut rv = Self { min: max, max };
44                rv.add_point(min);
45                rv
46            }
47
48            #[inline(always)]
49            fn from_center_and_half_extents(
50                center: Self::Vector,
51                half_extents: Self::Vector,
52            ) -> Self {
53                Self {
54                    min: center - half_extents,
55                    max: center + half_extents,
56                }
57            }
58
59            #[inline(always)]
60            fn from_center_and_size(center: Self::Vector, size: Self::Vector) -> Self {
61                let half_extents = size / 2.0;
62                Self::from_center_and_half_extents(center, half_extents)
63            }
64
65            fn from_points<I>(points: I) -> Self
66            where
67                I: IntoIterator,
68                I::Item: Borrow<Self::Vector>,
69            {
70                let mut aabb = Self::default();
71                for point in points {
72                    let point = *point.borrow();
73                    aabb.min = aabb.min.min(point);
74                    aabb.max = aabb.max.max(point);
75                }
76                aabb
77            }
78
79            #[inline(always)]
80            fn max(&self) -> Self::Vector {
81                self.max
82            }
83            #[inline(always)]
84            fn min(&self) -> Self::Vector {
85                self.min
86            }
87            #[inline(always)]
88            fn add_point(&mut self, pos: Self::Vector) {
89                self.max = self.max.max(pos);
90                self.min = self.min.min(pos);
91            }
92            #[inline(always)]
93            fn is_empty(&self) -> bool {
94                self.max.x < self.min.x
95            }
96            #[inline(always)]
97            fn add_aabb(&mut self, other: &Self) {
98                self.max = self.max.max(other.max);
99                self.min = self.min.min(other.min);
100            }
101            #[inline(always)]
102            fn fast_pad(&mut self, delta: Self::Vector) {
103                self.max += delta;
104                self.min -= delta;
105            }
106            #[inline]
107            fn pad(&mut self, delta: Self::Vector) {
108                let center = self.center();
109                let half_extent = (self.max - self.min) * 0.5;
110                let new_half_extent = (half_extent + delta).max(Self::Vector::ZERO);
111                self.max = center + new_half_extent;
112                self.min = center - new_half_extent;
113            }
114            #[inline(always)]
115            fn contains_point_inclusive(&self, point: Self::Vector) -> bool {
116                point.x >= self.min.x
117                    && point.x <= self.max.x
118                    && point.y >= self.min.y
119                    && point.y <= self.max.y
120            }
121            #[inline(always)]
122            fn center(&self) -> Self::Vector {
123                (self.max + self.min) * 0.5
124            }
125            #[inline(always)]
126            fn extents(&self) -> (Self::Vector, Self::Vector, Self::Vector) {
127                (self.min, self.max, self.max - self.min)
128            }
129
130            #[inline(always)]
131            fn contains_aabb_inclusive(&self, other: &Self) -> bool {
132                self.min.x <= other.min.x
133                    && other.max.x <= self.max.x
134                    && self.min.y <= other.min.y
135                    && other.max.y <= self.max.y
136            }
137
138            #[inline(always)]
139            fn convex_hull(&self) -> Vec<Self::Vector> {
140                crate::trait_impl::aabb_to_vec::<Aabb2<$scalar_type>>(*self)
141            }
142
143            #[inline(always)]
144            fn apply<F>(&mut self, f: F)
145            where
146                F: Fn(Self::Vector) -> Self::Vector,
147            {
148                if !self.is_empty() {
149                    let new_min = f(self.min);
150                    let new_max = f(self.max);
151                    self.min = new_min.min(new_max);
152                    self.max = new_max.max(new_min);
153                }
154            }
155        }
156
157        impl From<Aabb2<$scalar_type>> for Vec<$vec_type> {
158            #[inline(always)]
159            fn from(other: Aabb2<$scalar_type>) -> Self {
160                crate::trait_impl::aabb_to_vec(other)
161            }
162        }
163
164        impl PartialEq for Aabb2<$scalar_type>
165        where
166            Aabb2<$scalar_type>: crate::prelude::Aabb2,
167        {
168            #[inline(always)]
169            fn eq(&self, other: &Self) -> bool {
170                crate::trait_impl::aabb2_partial_eq(self, other)
171            }
172        }
173    };
174}
175
176impl_aabb2!(cgmath::Vector2<f64>, f64);
177impl_aabb2!(cgmath::Vector2<f32>, f32);
178
179#[derive(Debug, Copy, Clone)]
180pub struct Aabb3<T> {
181    min: cgmath::Vector3<T>,
182    max: cgmath::Vector3<T>,
183}
184
185macro_rules! impl_aabb3 {
186    ($vec_type:ty, $scalar_type:ty) => {
187        impl Default for Aabb3<$scalar_type> {
188            fn default() -> Self {
189                Self {
190                    min: <$vec_type>::splat(<$scalar_type>::INFINITY),
191                    max: <$vec_type>::splat(<$scalar_type>::NEG_INFINITY),
192                }
193            }
194        }
195
196        impl crate::prelude::Aabb3 for Aabb3<$scalar_type> {
197            type Vector = $vec_type;
198
199            fn from_point(point: Self::Vector) -> Self {
200                Self {
201                    min: point,
202                    max: point,
203                }
204            }
205
206            #[inline(always)]
207            fn from_corners(min: Self::Vector, max: Self::Vector) -> Self {
208                let mut rv = Self { min: max, max };
209                rv.add_point(min);
210                rv
211            }
212
213            #[inline(always)]
214            fn from_center_and_half_extents(
215                center: Self::Vector,
216                half_extents: Self::Vector,
217            ) -> Self {
218                Self {
219                    min: center - half_extents,
220                    max: center + half_extents,
221                }
222            }
223
224            #[inline(always)]
225            fn from_center_and_size(center: Self::Vector, size: Self::Vector) -> Self {
226                let half_extents = size / 2.0;
227                Self::from_center_and_half_extents(center, half_extents)
228            }
229
230            fn from_points<I>(points: I) -> Self
231            where
232                I: IntoIterator,
233                I::Item: Borrow<Self::Vector>,
234            {
235                let mut aabb = Self::default();
236                for point in points {
237                    let point = *point.borrow();
238                    aabb.min = aabb.min.min(point);
239                    aabb.max = aabb.max.max(point);
240                }
241                aabb
242            }
243
244            #[inline(always)]
245            fn max(&self) -> Self::Vector {
246                self.max
247            }
248            #[inline(always)]
249            fn min(&self) -> Self::Vector {
250                self.min
251            }
252            #[inline(always)]
253            fn add_point(&mut self, pos: Self::Vector) {
254                self.max = self.max.max(pos);
255                self.min = self.min.min(pos);
256            }
257            #[inline(always)]
258            fn is_empty(&self) -> bool {
259                self.max.x < self.min.x
260            }
261            #[inline(always)]
262            fn add_aabb(&mut self, other: &Self) {
263                self.max = self.max.max(other.max);
264                self.min = self.min.min(other.min);
265            }
266            #[inline(always)]
267            fn fast_pad(&mut self, delta: Self::Vector) {
268                self.max += delta;
269                self.min -= delta;
270            }
271            #[inline]
272            fn pad(&mut self, delta: Self::Vector) {
273                let center = self.center();
274                let half_extent = (self.max - self.min) * 0.5;
275                let new_half_extent = (half_extent + delta).max(Self::Vector::ZERO);
276                self.max = center + new_half_extent;
277                self.min = center - new_half_extent;
278            }
279            #[inline(always)]
280            fn contains_point_inclusive(&self, point: Self::Vector) -> bool {
281                point.x >= self.min.x
282                    && point.x <= self.max.x
283                    && point.y >= self.min.y
284                    && point.y <= self.max.y
285                    && point.z >= self.min.z
286                    && point.z <= self.max.z
287            }
288            #[inline(always)]
289            fn center(&self) -> Self::Vector {
290                (self.max + self.min) * 0.5
291            }
292            #[inline(always)]
293            fn extents(&self) -> (Self::Vector, Self::Vector, Self::Vector) {
294                (self.min, self.max, self.max - self.min)
295            }
296
297            #[inline(always)]
298            fn contains_aabb_inclusive(&self, other: &Self) -> bool {
299                self.min.x <= other.min.x
300                    && other.max.x <= self.max.x
301                    && self.min.y <= other.min.y
302                    && other.max.y <= self.max.y
303                    && self.min.z <= other.min.z
304                    && other.max.z <= self.max.z
305            }
306            #[inline(always)]
307            fn get_plane(&self) -> Option<Plane> {
308                Plane::get_plane::<Self>(self)
309            }
310            #[inline(always)]
311            fn get_plane_relaxed(&self, epsilon: $scalar_type, max_ulps: u32) -> Option<Plane> {
312                Plane::get_plane_relaxed::<$vec_type>(self, epsilon, max_ulps)
313            }
314            #[inline(always)]
315            fn apply<F>(&mut self, f: F)
316            where
317                F: Fn(Self::Vector) -> Self::Vector,
318            {
319                if !self.is_empty() {
320                    let new_min = f(self.min);
321                    let new_max = f(self.max);
322                    self.min = new_min.min(new_max);
323                    self.max = new_max.max(new_min);
324                }
325            }
326        }
327
328        impl PartialEq for Aabb3<$scalar_type>
329        where
330            Aabb3<$scalar_type>: crate::prelude::Aabb3,
331        {
332            #[inline(always)]
333            fn eq(&self, other: &Self) -> bool {
334                crate::trait_impl::aabb3_partial_eq(self, other)
335            }
336        }
337    };
338}
339
340impl_aabb3!(cgmath::Vector3<f64>, f64);
341impl_aabb3!(cgmath::Vector3<f32>, f32);
342
343macro_rules! impl_cgmath_vector2 {
344    ($scalar_type:ty) => {
345        impl HasXY for crate::cgmath::Vector2<$scalar_type> {
346            type Scalar =
347                <crate::cgmath::Vector2<$scalar_type> as crate::cgmath::VectorSpace>::Scalar;
348
349            #[inline(always)]
350            fn new_2d(x: Self::Scalar, y: Self::Scalar) -> Self {
351                <crate::cgmath::Vector2<$scalar_type>>::new(x, y)
352            }
353            #[inline(always)]
354            fn x(self) -> Self::Scalar {
355                self.x
356            }
357            #[inline(always)]
358            fn set_x(&mut self, val: Self::Scalar) {
359                self.x = val
360            }
361            #[inline(always)]
362            fn x_mut(&mut self) -> &mut Self::Scalar {
363                &mut self.x
364            }
365            #[inline(always)]
366            fn y(self) -> Self::Scalar {
367                self.y
368            }
369            #[inline(always)]
370            fn set_y(&mut self, val: Self::Scalar) {
371                self.y = val
372            }
373            #[inline(always)]
374            fn y_mut(&mut self) -> &mut Self::Scalar {
375                &mut self.y
376            }
377        }
378
379        impl GenericVector2 for crate::cgmath::Vector2<$scalar_type> {
380            const ZERO: Self = Self::new(0.0, 0.0);
381            const ONE: Self = Self::new(1.0, 1.0);
382
383            type Vector3 = crate::cgmath::Vector3<$scalar_type>;
384            type Affine = crate::cgmath::Matrix3<$scalar_type>;
385            type Aabb = Aabb2<$scalar_type>;
386
387            #[inline(always)]
388            fn new(x: Self::Scalar, y: Self::Scalar) -> Self {
389                <crate::cgmath::Vector2<$scalar_type>>::new(x, y)
390            }
391            #[inline(always)]
392            fn splat(value: Self::Scalar) -> Self {
393                Self::new(value, value)
394            }
395            #[inline(always)]
396            fn to_3d(self, z: Self::Scalar) -> Self::Vector3 {
397                <cgmath::Vector3<$scalar_type>>::new(self.x, self.y, z)
398            }
399            #[inline(always)]
400            fn magnitude(self) -> Self::Scalar {
401                cgmath::InnerSpace::magnitude(self)
402            }
403            #[inline(always)]
404            fn magnitude_sq(self) -> Self::Scalar {
405                cgmath::InnerSpace::magnitude2(self)
406            }
407            #[inline(always)]
408            fn dot(self, rhs: Self) -> Self::Scalar {
409                <cgmath::Vector2<$scalar_type> as cgmath::InnerSpace>::dot(self, rhs)
410            }
411            #[inline(always)]
412            fn normalize(self) -> Self {
413                <cgmath::Vector2<$scalar_type> as cgmath::InnerSpace>::normalize(self)
414            }
415            #[inline(always)]
416            fn perp_dot(self, other: Self) -> Self::Scalar {
417                self.x * other.y - self.y * other.x
418            }
419            #[inline(always)]
420            fn try_normalize(self, epsilon: Self::Scalar) -> Option<Self> {
421                let l_sq = cgmath::InnerSpace::magnitude2(self);
422                (l_sq > epsilon * epsilon).then(|| self / l_sq.sqrt())
423            }
424            #[inline(always)]
425            fn distance(self, rhs: Self) -> Self::Scalar {
426                <cgmath::Vector2<$scalar_type> as cgmath::MetricSpace>::distance(self, rhs)
427            }
428            #[inline(always)]
429            fn distance_sq(self, rhs: Self) -> Self::Scalar {
430                <cgmath::Vector2<$scalar_type>>::distance2(self, rhs)
431            }
432            #[inline(always)]
433            fn min(self, rhs: Self) -> Self {
434                <cgmath::Vector2<$scalar_type>>::new(self.x.min(rhs.x), self.y.min(rhs.y))
435            }
436            #[inline(always)]
437            fn max(self, rhs: Self) -> Self {
438                <cgmath::Vector2<$scalar_type>>::new(self.x.max(rhs.x), self.y.max(rhs.y))
439            }
440            #[inline(always)]
441            fn clamp(self, min: Self, max: Self) -> Self {
442                <cgmath::Vector2<$scalar_type>>::new(
443                    self.x.clamp(min.x, max.x),
444                    self.y.clamp(min.y, max.y),
445                )
446            }
447            #[inline(always)]
448            fn is_finite(self) -> bool {
449                self.x.is_finite() && self.y.is_finite()
450            }
451        }
452
453        impl Approx for cgmath::Vector2<$scalar_type> {
454            #[inline(always)]
455            fn is_ulps_eq(
456                self,
457                other: Self,
458                epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
459                max_ulps: u32,
460            ) -> bool {
461                self.x.ulps_eq(&other.x, epsilon, max_ulps)
462                    && self.y.ulps_eq(&other.y, epsilon, max_ulps)
463            }
464            #[inline(always)]
465            fn is_abs_diff_eq(
466                self,
467                other: Self,
468                epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
469            ) -> bool {
470                self.x.abs_diff_eq(&other.x, epsilon) && self.y.abs_diff_eq(&other.y, epsilon)
471            }
472        }
473    };
474}
475
476impl_cgmath_vector2!(f32);
477impl_cgmath_vector2!(f64);
478
479macro_rules! impl_cgmath_vector3 {
480    ($scalar_type:ty) => {
481        impl HasXY for cgmath::Vector3<$scalar_type> {
482            type Scalar = <cgmath::Vector3<$scalar_type> as cgmath::VectorSpace>::Scalar;
483
484            #[inline(always)]
485            fn new_2d(x: Self::Scalar, y: Self::Scalar) -> Self {
486                <cgmath::Vector3<$scalar_type>>::new(x, y, Self::Scalar::ZERO)
487            }
488            #[inline(always)]
489            fn x(self) -> Self::Scalar {
490                self.x
491            }
492            #[inline(always)]
493            fn set_x(&mut self, val: Self::Scalar) {
494                self.x = val
495            }
496            #[inline(always)]
497            fn x_mut(&mut self) -> &mut Self::Scalar {
498                &mut self.x
499            }
500            #[inline(always)]
501            fn y(self) -> Self::Scalar {
502                self.y
503            }
504            #[inline(always)]
505            fn set_y(&mut self, val: Self::Scalar) {
506                self.y = val
507            }
508            #[inline(always)]
509            fn y_mut(&mut self) -> &mut Self::Scalar {
510                &mut self.y
511            }
512        }
513
514        impl HasXYZ for cgmath::Vector3<$scalar_type> {
515            #[inline(always)]
516            fn new_3d(x: Self::Scalar, y: Self::Scalar, z: Self::Scalar) -> Self {
517                <cgmath::Vector3<$scalar_type>>::new(x, y, z)
518            }
519            #[inline(always)]
520            fn z(self) -> Self::Scalar {
521                self.z
522            }
523            #[inline(always)]
524            fn set_z(&mut self, val: Self::Scalar) {
525                self.z = val
526            }
527            #[inline(always)]
528            fn z_mut(&mut self) -> &mut Self::Scalar {
529                &mut self.z
530            }
531        }
532
533        impl GenericVector3 for cgmath::Vector3<$scalar_type> {
534            const ZERO: Self = Self::new(0.0, 0.0, 0.0);
535            const ONE: Self = Self::new(1.0, 1.0, 1.0);
536
537            type Vector2 = cgmath::Vector2<$scalar_type>;
538            type Affine = cgmath::Matrix4<$scalar_type>;
539            type Aabb = Aabb3<$scalar_type>;
540
541            #[inline(always)]
542            fn new(x: Self::Scalar, y: Self::Scalar, z: Self::Scalar) -> Self {
543                <cgmath::Vector3<$scalar_type>>::new(x, y, z)
544            }
545            #[inline(always)]
546            fn splat(value: Self::Scalar) -> Self {
547                Self::new(value, value, value)
548            }
549            #[inline(always)]
550            fn to_2d(self) -> Self::Vector2 {
551                Self::Vector2::new(self.x, self.y)
552            }
553            #[inline(always)]
554            fn magnitude(self) -> Self::Scalar {
555                cgmath::InnerSpace::magnitude(self)
556            }
557            #[inline(always)]
558            fn magnitude_sq(self) -> Self::Scalar {
559                cgmath::InnerSpace::magnitude2(self)
560            }
561            #[inline(always)]
562            fn normalize(self) -> Self {
563                cgmath::InnerSpace::normalize(self)
564            }
565            #[inline(always)]
566            fn try_normalize(self, epsilon: Self::Scalar) -> Option<Self> {
567                let l_sq = cgmath::InnerSpace::magnitude2(self);
568                (l_sq > epsilon * epsilon).then(|| self / l_sq.sqrt())
569            }
570            #[inline(always)]
571            fn dot(self, rhs: Self) -> Self::Scalar {
572                <cgmath::Vector3<$scalar_type> as cgmath::InnerSpace>::dot(self, rhs)
573            }
574            #[inline(always)]
575            fn cross(self, rhs: Self) -> Self {
576                <cgmath::Vector3<$scalar_type>>::cross(self, rhs)
577            }
578            #[inline(always)]
579            fn distance(self, rhs: Self) -> Self::Scalar {
580                <cgmath::Vector3<$scalar_type> as cgmath::MetricSpace>::distance(self, rhs)
581            }
582            #[inline(always)]
583            fn distance_sq(self, rhs: Self) -> Self::Scalar {
584                <cgmath::Vector3<$scalar_type>>::distance2(self, rhs)
585            }
586            #[inline(always)]
587            fn min(self, rhs: Self) -> Self {
588                <cgmath::Vector3<$scalar_type>>::new(
589                    self.x.min(rhs.x),
590                    self.y.min(rhs.y),
591                    self.z.min(rhs.z),
592                )
593            }
594            #[inline(always)]
595            fn max(self, rhs: Self) -> Self {
596                <cgmath::Vector3<$scalar_type>>::new(
597                    self.x.max(rhs.x),
598                    self.y.max(rhs.y),
599                    self.z.max(rhs.z),
600                )
601            }
602            #[inline(always)]
603            fn clamp(self, min: Self, max: Self) -> Self {
604                <cgmath::Vector3<$scalar_type>>::new(
605                    self.x.clamp(min.x, max.x),
606                    self.y.clamp(min.y, max.y),
607                    self.z.clamp(min.z, max.z),
608                )
609            }
610            #[inline(always)]
611            fn is_finite(self) -> bool {
612                self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
613            }
614        }
615
616        impl Approx for cgmath::Vector3<$scalar_type> {
617            #[inline(always)]
618            fn is_ulps_eq(
619                self,
620                other: Self,
621                epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
622                max_ulps: u32,
623            ) -> bool {
624                self.x.ulps_eq(&other.x, epsilon, max_ulps)
625                    && self.y.ulps_eq(&other.y, epsilon, max_ulps)
626                    && self.z.ulps_eq(&other.z, epsilon, max_ulps)
627            }
628            #[inline(always)]
629            fn is_abs_diff_eq(
630                self,
631                other: Self,
632                epsilon: <Self::Scalar as AbsDiffEq>::Epsilon,
633            ) -> bool {
634                self.x.abs_diff_eq(&other.x, epsilon)
635                    && self.y.abs_diff_eq(&other.y, epsilon)
636                    && self.z.abs_diff_eq(&other.z, epsilon)
637            }
638        }
639    };
640}
641
642impl_cgmath_vector3!(f32);
643impl_cgmath_vector3!(f64);
644
645macro_rules! impl_matrix3_cgmath {
646    ($scalar_type:ty) => {
647        impl Affine2D for cgmath::Matrix3<$scalar_type>
648        where
649            cgmath::Vector2<$scalar_type>: GenericVector2<Scalar = $scalar_type> + HasXY,
650        {
651            type Vector2 = cgmath::Vector2<$scalar_type>;
652            #[inline(always)]
653            fn from_cols_array(array: &[$scalar_type; 9]) -> Self {
654                cgmath::Matrix3::<$scalar_type>::from_cols(
655                    cgmath::Vector3::<$scalar_type>::new_3d(array[0], array[1], array[2]),
656                    cgmath::Vector3::<$scalar_type>::new_3d(array[3], array[4], array[5]),
657                    cgmath::Vector3::<$scalar_type>::new_3d(array[6], array[7], array[8]),
658                )
659            }
660
661            #[inline(always)]
662            fn identity() -> Self {
663                <cgmath::Matrix3<$scalar_type> as cgmath::SquareMatrix>::identity()
664            }
665
666            #[inline(always)]
667            fn transform_vector2(
668                &self,
669                vec: cgmath::Vector2<$scalar_type>,
670            ) -> cgmath::Vector2<$scalar_type> {
671                let vec3 = cgmath::Vector3::new(vec.x, vec.y, 0.0);
672                let transformed = self * vec3;
673                cgmath::Vector2::<$scalar_type>::new(transformed.x, transformed.y)
674            }
675
676            #[inline(always)]
677            fn transform_point2(
678                &self,
679                point: cgmath::Vector2<$scalar_type>,
680            ) -> cgmath::Vector2<$scalar_type> {
681                let p: cgmath::Point2<$scalar_type> =
682                    cgmath::Point2::<$scalar_type>::from_vec(point);
683                self.transform_point(p).to_vec()
684            }
685
686            #[inline(always)]
687            fn try_inverse(&self) -> Option<Self> {
688                self.invert()
689            }
690        }
691    };
692}
693
694// Usage
695impl_matrix3_cgmath!(f32);
696impl_matrix3_cgmath!(f64);
697
698macro_rules! impl_matrix4_cgmath {
699    ($scalar_type:ty) => {
700        impl Affine3D for cgmath::Matrix4<$scalar_type>
701        where
702            cgmath::Vector3<$scalar_type>: GenericVector3<Scalar = $scalar_type> + HasXY,
703        {
704            type Vector3 = cgmath::Vector3<$scalar_type>;
705
706            #[inline(always)]
707            fn from_cols_array(array: &[$scalar_type; 16]) -> Self {
708                cgmath::Matrix4::<$scalar_type>::from_cols(
709                    cgmath::Vector4::<$scalar_type>::new(array[0], array[1], array[2], array[3]),
710                    cgmath::Vector4::<$scalar_type>::new(array[4], array[5], array[6], array[7]),
711                    cgmath::Vector4::<$scalar_type>::new(array[8], array[9], array[10], array[11]),
712                    cgmath::Vector4::<$scalar_type>::new(
713                        array[12], array[13], array[14], array[15],
714                    ),
715                )
716            }
717
718            #[inline(always)]
719            fn identity() -> Self {
720                <cgmath::Matrix4<$scalar_type> as cgmath::SquareMatrix>::identity()
721            }
722
723            #[inline(always)]
724            fn transform_vector3(
725                &self,
726                vec: cgmath::Vector3<$scalar_type>,
727            ) -> cgmath::Vector3<$scalar_type> {
728                let vec4 = cgmath::Vector4::new(vec.x, vec.y, vec.z, 0.0);
729                let transformed = self * vec4;
730                cgmath::Vector3::<$scalar_type>::new(transformed.x, transformed.y, transformed.z)
731            }
732
733            #[inline(always)]
734            fn transform_point3(
735                &self,
736                point: cgmath::Vector3<$scalar_type>,
737            ) -> cgmath::Vector3<$scalar_type> {
738                let p: cgmath::Point3<$scalar_type> =
739                    cgmath::Point3::<$scalar_type>::from_vec(point);
740                self.transform_point(p).to_vec()
741            }
742
743            #[inline(always)]
744            fn try_inverse(&self) -> Option<Self> {
745                self.invert()
746            }
747
748            #[inline(always)]
749            fn from_plane_to_xy(source_plane: Plane) -> Self {
750                crate::trait_impl::from_plane_to_xy::<cgmath::Vector3<$scalar_type>>(source_plane)
751            }
752
753            #[inline(always)]
754            fn from_translation(translation: Self::Vector3) -> Self {
755                cgmath::Matrix4::<$scalar_type>::from_translation(translation)
756            }
757
758            #[inline(always)]
759            fn from_scale(scale: Self::Vector3) -> Self {
760                cgmath::Matrix4::<$scalar_type>::from_nonuniform_scale(scale.x, scale.y, scale.z)
761            }
762        }
763    };
764}
765
766// Usage
767impl_matrix4_cgmath!(f32);
768impl_matrix4_cgmath!(f64);