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
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
708impl_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
780impl_matrix4_cgmath!(f32);
782impl_matrix4_cgmath!(f64);