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