1#[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
694impl_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
766impl_matrix4_cgmath!(f32);
768impl_matrix4_cgmath!(f64);