1#![allow(clippy::unnecessary_cast)]
4
5use crate::{physics_transform::PhysicsTransformConfig, prelude::*};
6use bevy::{
7 ecs::{lifecycle::HookContext, world::DeferredWorld},
8 math::DQuat,
9 prelude::*,
10};
11use derive_more::From;
12
13#[cfg(feature = "2d")]
14use crate::math::Matrix;
15
16#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
33#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
34#[cfg_attr(feature = "2d", doc = " Position::from_xy(0.0, 20.0),")]
40#[cfg_attr(feature = "3d", doc = " Position::from_xyz(0.0, 2.0, 0.0),")]
41#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
45#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
46#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
47#[reflect(Debug, Component, Default, PartialEq)]
48pub struct Position(pub Vector);
49
50impl Position {
51 pub const PLACEHOLDER: Self = Self(Vector::MAX);
55
56 pub fn new(position: Vector) -> Self {
58 Self(position)
59 }
60
61 #[cfg(feature = "2d")]
63 pub fn from_xy(x: Scalar, y: Scalar) -> Self {
64 Self(Vector::new(x, y))
65 }
66
67 #[cfg(feature = "3d")]
69 pub fn from_xyz(x: Scalar, y: Scalar, z: Scalar) -> Self {
70 Self(Vector::new(x, y, z))
71 }
72}
73
74impl From<GlobalTransform> for Position {
75 #[cfg(feature = "2d")]
76 fn from(value: GlobalTransform) -> Self {
77 Self::from_xy(
78 value.translation().adjust_precision().x,
79 value.translation().adjust_precision().y,
80 )
81 }
82
83 #[cfg(feature = "3d")]
84 fn from(value: GlobalTransform) -> Self {
85 Self::from_xyz(
86 value.translation().adjust_precision().x,
87 value.translation().adjust_precision().y,
88 value.translation().adjust_precision().z,
89 )
90 }
91}
92
93impl From<&GlobalTransform> for Position {
94 #[cfg(feature = "2d")]
95 fn from(value: &GlobalTransform) -> Self {
96 Self::from_xy(
97 value.translation().adjust_precision().x,
98 value.translation().adjust_precision().y,
99 )
100 }
101
102 #[cfg(feature = "3d")]
103 fn from(value: &GlobalTransform) -> Self {
104 Self::from_xyz(
105 value.translation().adjust_precision().x,
106 value.translation().adjust_precision().y,
107 value.translation().adjust_precision().z,
108 )
109 }
110}
111
112impl Ease for Position {
113 fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> {
114 FunctionCurve::new(Interval::UNIT, move |t| {
115 Position(Vector::lerp(start.0, end.0, t as Scalar))
116 })
117 }
118}
119
120#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
122#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
123#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
124#[reflect(Debug, Component, Default, PartialEq)]
125pub struct PreSolveDeltaPosition(pub Vector);
126
127#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
129#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
130#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
131#[reflect(Debug, Component, Default, PartialEq)]
132pub struct PreSolveDeltaRotation(pub Rotation);
133
134#[cfg(feature = "2d")]
136#[allow(dead_code)]
137pub(crate) type RotationValue = Scalar;
138#[cfg(feature = "3d")]
140#[allow(dead_code)]
141pub(crate) type RotationValue = Quaternion;
142
143#[derive(Reflect, Clone, Copy, Component, Debug, PartialEq)]
171#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
172#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
173#[reflect(Debug, Component, PartialEq)]
174#[cfg(feature = "2d")]
175pub struct Rotation {
176 pub cos: Scalar,
180 pub sin: Scalar,
184}
185
186#[cfg(feature = "2d")]
187impl Default for Rotation {
188 fn default() -> Self {
189 Self::IDENTITY
190 }
191}
192
193#[cfg(feature = "2d")]
194impl Rotation {
195 pub const PLACEHOLDER: Self = Self {
199 cos: Scalar::MAX,
200 sin: Scalar::MAX,
201 };
202
203 pub const IDENTITY: Self = Self { cos: 1.0, sin: 0.0 };
205
206 pub const PI: Self = Self {
208 cos: -1.0,
209 sin: 0.0,
210 };
211
212 pub const FRAC_PI_2: Self = Self { cos: 0.0, sin: 1.0 };
214
215 pub const FRAC_PI_3: Self = Self {
217 cos: 0.5,
218 sin: 0.866_025_4,
219 };
220
221 pub const FRAC_PI_4: Self = Self {
223 cos: FRAC_1_SQRT_2,
224 sin: FRAC_1_SQRT_2,
225 };
226
227 pub const FRAC_PI_6: Self = Self {
229 cos: 0.866_025_4,
230 sin: 0.5,
231 };
232
233 pub const FRAC_PI_8: Self = Self {
235 cos: 0.923_879_5,
236 sin: 0.382_683_43,
237 };
238
239 #[inline]
241 pub fn radians(radians: Scalar) -> Self {
242 #[cfg(feature = "enhanced-determinism")]
243 let (sin, cos) = (
244 libm::sin(radians as f64) as Scalar,
245 libm::cos(radians as f64) as Scalar,
246 );
247 #[cfg(not(feature = "enhanced-determinism"))]
248 let (sin, cos) = radians.sin_cos();
249
250 Self::from_sin_cos(sin, cos)
251 }
252
253 #[inline]
255 pub fn degrees(degrees: Scalar) -> Self {
256 Self::radians(degrees.to_radians())
257 }
258
259 #[deprecated(note = "renamed to just `radians` to match Bevy")]
261 pub fn from_radians(radians: Scalar) -> Self {
262 Self::radians(radians)
263 }
264
265 #[deprecated(note = "renamed to just `degrees` to match Bevy")]
267 pub fn from_degrees(degrees: Scalar) -> Self {
268 Self::degrees(degrees)
269 }
270
271 #[inline]
279 pub fn from_sin_cos(sin: Scalar, cos: Scalar) -> Self {
280 let rotation = Self { sin, cos };
281 debug_assert!(
282 rotation.is_normalized(),
283 "the given sine and cosine produce an invalid rotation"
284 );
285 rotation
286 }
287
288 #[inline]
290 pub fn as_radians(self) -> Scalar {
291 #[cfg(feature = "enhanced-determinism")]
292 {
293 libm::atan2(self.sin as f64, self.cos as f64) as Scalar
294 }
295 #[cfg(not(feature = "enhanced-determinism"))]
296 {
297 Scalar::atan2(self.sin, self.cos)
298 }
299 }
300
301 #[inline]
303 pub fn as_degrees(self) -> Scalar {
304 self.as_radians().to_degrees()
305 }
306
307 #[inline]
309 pub const fn sin_cos(self) -> (Scalar, Scalar) {
310 (self.sin, self.cos)
311 }
312
313 #[deprecated(note = "use the `Mul` impl instead, like `rot * vec`")]
315 pub fn rotate(&self, vec: Vector) -> Vector {
316 self * vec
317 }
318
319 #[inline]
325 #[doc(alias = "norm")]
326 pub fn length(self) -> Scalar {
327 Vector::new(self.sin, self.cos).length()
328 }
329
330 #[inline]
339 #[doc(alias = "norm2")]
340 pub fn length_squared(self) -> Scalar {
341 Vector::new(self.sin, self.cos).length_squared()
342 }
343
344 #[inline]
348 pub fn length_recip(self) -> Scalar {
349 Vector::new(self.sin, self.cos).length_recip()
350 }
351
352 #[inline]
362 #[must_use]
363 pub fn try_normalize(self) -> Option<Self> {
364 let recip = self.length_recip();
365 if recip.is_finite() && recip > 0.0 {
366 Some(Self::from_sin_cos(self.sin * recip, self.cos * recip))
367 } else {
368 None
369 }
370 }
371
372 #[inline]
383 #[must_use]
384 pub fn normalize(self) -> Self {
385 let length_recip = self.length_recip();
386 Self::from_sin_cos(self.sin * length_recip, self.cos * length_recip)
387 }
388
389 #[inline]
393 #[must_use]
394 pub fn fast_renormalize(self) -> Self {
395 let length_squared = self.length_squared();
398 let approx_inv_length = 0.5 * (3.0 - length_squared);
399 Self::from_sin_cos(self.sin * approx_inv_length, self.cos * approx_inv_length)
400 }
401
402 #[inline]
404 pub fn is_finite(self) -> bool {
405 self.sin.is_finite() && self.cos.is_finite()
406 }
407
408 #[inline]
410 pub fn is_nan(self) -> bool {
411 self.sin.is_nan() || self.cos.is_nan()
412 }
413
414 #[inline]
418 pub fn is_normalized(self) -> bool {
419 (self.length_squared() - 1.0).abs() <= 2e-4
423 }
424
425 #[inline]
427 pub fn is_near_identity(self) -> bool {
428 let threshold_angle_sin = 0.000_049_692_047; self.cos > 0.0 && self.sin.abs() < threshold_angle_sin
431 }
432
433 #[inline]
435 pub fn angle_between(self, other: Self) -> Scalar {
436 (other * self.inverse()).as_radians()
437 }
438
439 #[inline]
442 #[must_use]
443 #[doc(alias = "conjugate")]
444 pub fn inverse(self) -> Self {
445 Self {
446 cos: self.cos,
447 sin: -self.sin,
448 }
449 }
450
451 #[inline]
452 #[must_use]
453 pub fn add_angle_fast(&self, radians: Scalar) -> Self {
456 let (sin, cos) = (self.sin + radians * self.cos, self.cos - radians * self.sin);
457 let magnitude_squared = sin * sin + cos * cos;
458 let magnitude_recip = if magnitude_squared > 0.0 {
459 magnitude_squared.sqrt().recip()
460 } else {
461 0.0
462 };
463 Rotation::from_sin_cos(sin * magnitude_recip, cos * magnitude_recip)
464 }
465
466 #[inline]
505 pub fn nlerp(self, end: Self, s: Scalar) -> Self {
506 Self {
507 sin: self.sin.lerp(end.sin, s),
508 cos: self.cos.lerp(end.cos, s),
509 }
510 .try_normalize()
511 .unwrap_or(self)
515 }
516
517 #[inline]
543 pub fn slerp(self, end: Self, s: Scalar) -> Self {
544 self * Self::radians(self.angle_between(end) * s)
545 }
546}
547
548#[cfg(feature = "2d")]
549impl From<Scalar> for Rotation {
550 fn from(rotation: Scalar) -> Self {
552 Self::radians(rotation)
553 }
554}
555
556#[cfg(feature = "2d")]
557impl From<Rotation> for Matrix {
558 fn from(rot: Rotation) -> Self {
560 Matrix::from_cols_array(&[rot.cos, rot.sin, -rot.sin, rot.cos])
561 }
562}
563
564#[cfg(feature = "2d")]
565impl From<Matrix> for Rotation {
566 fn from(mat: Matrix) -> Self {
568 let cos = mat.x_axis.x;
569 let sin = mat.x_axis.y;
570 Self::from_sin_cos(sin, cos)
571 }
572}
573
574#[cfg(feature = "2d")]
575impl From<Rot2> for Rotation {
576 fn from(rot: Rot2) -> Self {
578 Self::from_sin_cos(rot.sin as Scalar, rot.cos as Scalar)
579 }
580}
581
582#[cfg(feature = "2d")]
583impl From<Rotation> for Rot2 {
584 fn from(rot: Rotation) -> Self {
586 Self::from_sin_cos(rot.sin as f32, rot.cos as f32)
587 }
588}
589
590#[cfg(feature = "2d")]
591impl core::ops::Mul for Rotation {
592 type Output = Self;
593
594 fn mul(self, rhs: Self) -> Self::Output {
595 Self {
596 cos: self.cos * rhs.cos - self.sin * rhs.sin,
597 sin: self.sin * rhs.cos + self.cos * rhs.sin,
598 }
599 }
600}
601
602#[cfg(feature = "2d")]
603impl core::ops::MulAssign for Rotation {
604 fn mul_assign(&mut self, rhs: Self) {
605 *self = *self * rhs;
606 }
607}
608
609#[cfg(feature = "2d")]
610impl core::ops::Mul<Vector> for Rotation {
611 type Output = Vector;
612
613 fn mul(self, rhs: Vector) -> Self::Output {
615 Vector::new(
616 rhs.x * self.cos - rhs.y * self.sin,
617 rhs.x * self.sin + rhs.y * self.cos,
618 )
619 }
620}
621
622#[cfg(feature = "2d")]
623impl core::ops::Mul<Vector3> for Rotation {
624 type Output = Vector3;
625
626 fn mul(self, rhs: Vector3) -> Self::Output {
627 Vector3::new(
628 rhs.x * self.cos - rhs.y * self.sin,
629 rhs.x * self.sin + rhs.y * self.cos,
630 rhs.z,
631 )
632 }
633}
634
635#[cfg(feature = "2d")]
636impl core::ops::Mul<&Vector3> for Rotation {
637 type Output = Vector3;
638
639 fn mul(self, rhs: &Vector3) -> Self::Output {
640 self * *rhs
641 }
642}
643
644#[cfg(feature = "2d")]
645impl core::ops::Mul<&mut Vector3> for Rotation {
646 type Output = Vector3;
647
648 fn mul(self, rhs: &mut Vector3) -> Self::Output {
649 self * *rhs
650 }
651}
652
653#[cfg(feature = "2d")]
654impl core::ops::Mul<Vector3> for &Rotation {
655 type Output = Vector3;
656
657 fn mul(self, rhs: Vector3) -> Self::Output {
658 *self * rhs
659 }
660}
661
662#[cfg(feature = "2d")]
663impl core::ops::Mul<&Vector3> for &Rotation {
664 type Output = Vector3;
665
666 fn mul(self, rhs: &Vector3) -> Self::Output {
667 *self * *rhs
668 }
669}
670
671#[cfg(feature = "2d")]
672impl core::ops::Mul<&mut Vector3> for &Rotation {
673 type Output = Vector3;
674
675 fn mul(self, rhs: &mut Vector3) -> Self::Output {
676 *self * *rhs
677 }
678}
679
680#[cfg(feature = "2d")]
681impl core::ops::Mul<Vector3> for &mut Rotation {
682 type Output = Vector3;
683
684 fn mul(self, rhs: Vector3) -> Self::Output {
685 *self * rhs
686 }
687}
688
689#[cfg(feature = "2d")]
690impl core::ops::Mul<&Vector3> for &mut Rotation {
691 type Output = Vector3;
692
693 fn mul(self, rhs: &Vector3) -> Self::Output {
694 *self * *rhs
695 }
696}
697
698#[cfg(feature = "2d")]
699impl core::ops::Mul<&mut Vector3> for &mut Rotation {
700 type Output = Vector3;
701
702 fn mul(self, rhs: &mut Vector3) -> Self::Output {
703 *self * *rhs
704 }
705}
706
707impl Ease for Rotation {
708 fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> {
709 FunctionCurve::new(Interval::UNIT, move |t| {
710 Rotation::slerp(start, end, t as Scalar)
711 })
712 }
713}
714
715#[cfg(feature = "3d")]
741#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq)]
742#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
743#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
744#[reflect(Debug, Component, Default, PartialEq)]
745pub struct Rotation(pub Quaternion);
746
747#[cfg(feature = "3d")]
748impl Rotation {
749 pub const PLACEHOLDER: Self = Self(Quaternion::from_xyzw(
753 Scalar::MAX,
754 Scalar::MAX,
755 Scalar::MAX,
756 Scalar::MAX,
757 ));
758
759 pub const IDENTITY: Self = Self(Quaternion::IDENTITY);
761
762 #[inline]
764 pub fn angle_between(self, other: Self) -> Scalar {
765 self.0.angle_between(other.0)
766 }
767
768 #[inline]
770 #[must_use]
771 pub fn inverse(&self) -> Self {
772 Self(self.0.inverse())
773 }
774
775 #[inline]
787 pub fn nlerp(self, end: Self, t: Scalar) -> Self {
788 Self(self.0.lerp(end.0, t))
789 }
790
791 #[inline]
802 pub fn slerp(self, end: Self, t: Scalar) -> Self {
803 Self(self.0.slerp(end.0, t))
804 }
805
806 #[inline]
810 #[must_use]
811 pub fn fast_renormalize(self) -> Self {
812 let length_squared = self.length_squared();
815 let approx_inv_length = 0.5 * (3.0 - length_squared);
816 Self(self.0 * approx_inv_length)
817 }
818}
819
820#[cfg(feature = "3d")]
821impl core::ops::Mul<Vector> for Rotation {
822 type Output = Vector;
823
824 fn mul(self, vector: Vector) -> Self::Output {
825 self.0 * vector
826 }
827}
828
829#[cfg(feature = "3d")]
830impl core::ops::Mul for Rotation {
831 type Output = Rotation;
832
833 fn mul(self, rhs: Self) -> Self::Output {
834 Self(self.0 * rhs.0)
835 }
836}
837
838#[cfg(feature = "3d")]
839impl core::ops::MulAssign for Rotation {
840 fn mul_assign(&mut self, rhs: Self) {
841 self.0 *= rhs.0;
842 }
843}
844
845#[cfg(feature = "3d")]
846impl core::ops::Mul<Quaternion> for Rotation {
847 type Output = Quaternion;
848
849 fn mul(self, quaternion: Quaternion) -> Self::Output {
850 self.0 * quaternion
851 }
852}
853
854#[cfg(feature = "3d")]
855impl core::ops::Mul<Quaternion> for &Rotation {
856 type Output = Quaternion;
857
858 fn mul(self, quaternion: Quaternion) -> Self::Output {
859 self.0 * quaternion
860 }
861}
862
863#[cfg(feature = "3d")]
864impl core::ops::Mul<Quaternion> for &mut Rotation {
865 type Output = Quaternion;
866
867 fn mul(self, quaternion: Quaternion) -> Self::Output {
868 self.0 * quaternion
869 }
870}
871
872#[cfg(feature = "3d")]
873impl core::ops::Mul<Rotation> for Quaternion {
874 type Output = Rotation;
875
876 fn mul(self, rotation: Rotation) -> Self::Output {
877 Rotation(self * rotation.0)
878 }
879}
880
881#[cfg(feature = "3d")]
882impl core::ops::Mul<Rotation> for &Quaternion {
883 type Output = Rotation;
884
885 fn mul(self, rotation: Rotation) -> Self::Output {
886 Rotation(*self * rotation.0)
887 }
888}
889
890#[cfg(feature = "3d")]
891impl core::ops::Mul<Rotation> for &mut Quaternion {
892 type Output = Rotation;
893
894 fn mul(self, rotation: Rotation) -> Self::Output {
895 Rotation(*self * rotation.0)
896 }
897}
898
899impl core::ops::Mul<Dir> for Rotation {
900 type Output = Dir;
901
902 fn mul(self, direction: Dir) -> Self::Output {
903 Dir::new_unchecked((self * direction.adjust_precision()).f32())
904 }
905}
906
907impl core::ops::Mul<Vector> for &Rotation {
908 type Output = Vector;
909
910 fn mul(self, vector: Vector) -> Self::Output {
911 *self * vector
912 }
913}
914
915impl core::ops::Mul<Dir> for &Rotation {
916 type Output = Dir;
917
918 fn mul(self, direction: Dir) -> Self::Output {
919 Dir::new_unchecked((*self * direction.adjust_precision()).f32())
920 }
921}
922
923impl core::ops::Mul<Vector> for &mut Rotation {
924 type Output = Vector;
925
926 fn mul(self, vector: Vector) -> Self::Output {
927 *self * vector
928 }
929}
930
931impl core::ops::Mul<Dir> for &mut Rotation {
932 type Output = Dir;
933
934 fn mul(self, direction: Dir) -> Self::Output {
935 Dir::new_unchecked((*self * direction.adjust_precision()).f32())
936 }
937}
938
939impl core::ops::Mul<&Vector> for Rotation {
940 type Output = Vector;
941
942 fn mul(self, vector: &Vector) -> Self::Output {
943 self * *vector
944 }
945}
946
947impl core::ops::Mul<&Dir> for Rotation {
948 type Output = Dir;
949
950 fn mul(self, direction: &Dir) -> Self::Output {
951 Dir::new_unchecked((self * direction.adjust_precision()).f32())
952 }
953}
954
955impl core::ops::Mul<&mut Vector> for Rotation {
956 type Output = Vector;
957
958 fn mul(self, vector: &mut Vector) -> Self::Output {
959 self * *vector
960 }
961}
962
963impl core::ops::Mul<&mut Dir> for Rotation {
964 type Output = Dir;
965
966 fn mul(self, direction: &mut Dir) -> Self::Output {
967 Dir::new_unchecked((self * direction.adjust_precision()).f32())
968 }
969}
970
971impl core::ops::Mul<&Vector> for &Rotation {
972 type Output = Vector;
973
974 fn mul(self, vector: &Vector) -> Self::Output {
975 *self * *vector
976 }
977}
978
979impl core::ops::Mul<&Dir> for &Rotation {
980 type Output = Dir;
981
982 fn mul(self, direction: &Dir) -> Self::Output {
983 Dir::new_unchecked((*self * direction.adjust_precision()).f32())
984 }
985}
986
987impl core::ops::Mul<&Vector> for &mut Rotation {
988 type Output = Vector;
989
990 fn mul(self, vector: &Vector) -> Self::Output {
991 *self * *vector
992 }
993}
994
995impl core::ops::Mul<&Dir> for &mut Rotation {
996 type Output = Dir;
997
998 fn mul(self, direction: &Dir) -> Self::Output {
999 Dir::new_unchecked((*self * direction.adjust_precision()).f32())
1000 }
1001}
1002
1003impl core::ops::Mul<&mut Vector> for &Rotation {
1004 type Output = Vector;
1005
1006 fn mul(self, vector: &mut Vector) -> Self::Output {
1007 *self * *vector
1008 }
1009}
1010
1011impl core::ops::Mul<&mut Dir> for &Rotation {
1012 type Output = Dir;
1013
1014 fn mul(self, direction: &mut Dir) -> Self::Output {
1015 Dir::new_unchecked((*self * direction.adjust_precision()).f32())
1016 }
1017}
1018
1019impl core::ops::Mul<&mut Vector> for &mut Rotation {
1020 type Output = Vector;
1021
1022 fn mul(self, vector: &mut Vector) -> Self::Output {
1023 *self * *vector
1024 }
1025}
1026
1027impl core::ops::Mul<&mut Dir> for &mut Rotation {
1028 type Output = Dir;
1029
1030 fn mul(self, direction: &mut Dir) -> Self::Output {
1031 Dir::new_unchecked((*self * direction.adjust_precision()).f32())
1032 }
1033}
1034
1035#[cfg(feature = "2d")]
1036impl From<Rotation> for Scalar {
1037 fn from(rot: Rotation) -> Self {
1038 rot.as_radians()
1039 }
1040}
1041
1042#[cfg(feature = "2d")]
1043impl From<Rotation> for Quaternion {
1044 fn from(rot: Rotation) -> Self {
1045 let z = rot.sin.signum() * ((1.0 - rot.cos) / 2.0).abs().sqrt();
1046 let w = ((1.0 + rot.cos) / 2.0).abs().sqrt();
1047 Quaternion::from_xyzw(0.0, 0.0, z, w)
1048 }
1049}
1050
1051#[cfg(feature = "3d")]
1052impl From<Rotation> for Quaternion {
1053 fn from(rot: Rotation) -> Self {
1054 rot.0
1055 }
1056}
1057
1058impl From<Transform> for Rotation {
1059 fn from(value: Transform) -> Self {
1060 Self::from(value.rotation)
1061 }
1062}
1063
1064impl From<GlobalTransform> for Rotation {
1065 fn from(value: GlobalTransform) -> Self {
1066 Self::from(value.compute_transform().rotation)
1067 }
1068}
1069
1070impl From<&GlobalTransform> for Rotation {
1071 fn from(value: &GlobalTransform) -> Self {
1072 Self::from(value.compute_transform().rotation)
1073 }
1074}
1075
1076#[cfg(feature = "2d")]
1077impl From<Quat> for Rotation {
1078 fn from(quat: Quat) -> Self {
1079 let angle = quat.to_euler(EulerRot::XYZ).2;
1080 Self::radians(angle as Scalar)
1081 }
1082}
1083
1084#[cfg(feature = "2d")]
1085impl From<DQuat> for Rotation {
1086 fn from(quat: DQuat) -> Self {
1087 let angle = quat.to_euler(EulerRot::XYZ).2;
1088 Self::radians(angle as Scalar)
1089 }
1090}
1091
1092#[cfg(feature = "3d")]
1093impl From<Quat> for Rotation {
1094 fn from(quat: Quat) -> Self {
1095 Self(Quaternion::from_xyzw(
1096 quat.x as Scalar,
1097 quat.y as Scalar,
1098 quat.z as Scalar,
1099 quat.w as Scalar,
1100 ))
1101 }
1102}
1103
1104#[cfg(feature = "3d")]
1105impl From<DQuat> for Rotation {
1106 fn from(quat: DQuat) -> Self {
1107 Self(Quaternion::from_xyzw(
1108 quat.x as Scalar,
1109 quat.y as Scalar,
1110 quat.z as Scalar,
1111 quat.w as Scalar,
1112 ))
1113 }
1114}
1115
1116pub(crate) fn init_physics_transform(world: &mut DeferredWorld, ctx: &HookContext) {
1117 let entity_ref = world.entity(ctx.entity);
1118
1119 let (mut position, is_pos_placeholder) = entity_ref
1121 .get::<Position>()
1122 .map_or((default(), true), |p| (*p, *p == Position::PLACEHOLDER));
1123 let (mut rotation, is_rot_placeholder) = entity_ref
1124 .get::<Rotation>()
1125 .map_or((default(), true), |r| (*r, *r == Rotation::PLACEHOLDER));
1126
1127 if is_pos_placeholder {
1128 position.0 = Vector::ZERO;
1129 }
1130 if is_rot_placeholder {
1131 rotation = Rotation::IDENTITY;
1132 }
1133
1134 let is_not_placeholder = !is_pos_placeholder || !is_rot_placeholder;
1136
1137 let config = world
1138 .get_resource::<PhysicsTransformConfig>()
1139 .cloned()
1140 .unwrap_or_default();
1141
1142 let mut parent_global_transform = GlobalTransform::default();
1143
1144 let mut curr_parent = world.get::<ChildOf>(ctx.entity);
1146 while let Some(parent) = curr_parent {
1147 if let Some(parent_transform) = world.get::<Transform>(parent.0) {
1148 parent_global_transform = *parent_transform * parent_global_transform;
1149 }
1150 curr_parent = world.get::<ChildOf>(parent.0);
1151 }
1152
1153 let transform = world.get::<Transform>(ctx.entity).copied();
1154 let global_transform = transform.map(|transform| {
1155 let global_transform = parent_global_transform * GlobalTransform::from(transform);
1156 *world.get_mut::<GlobalTransform>(ctx.entity).unwrap() = global_transform;
1158 global_transform
1159 });
1160
1161 if is_not_placeholder && config.position_to_transform {
1164 if parent_global_transform != GlobalTransform::default() {
1166 #[cfg(feature = "2d")]
1167 let Some(transform) = transform else {
1168 return;
1169 };
1170
1171 #[cfg(feature = "2d")]
1174 let new_transform =
1175 {
1176 let (parent_translation, parent_scale) = (
1177 parent_global_transform.translation(),
1178 parent_global_transform.scale(),
1179 );
1180 GlobalTransform::from(
1181 Transform::from_translation(position.f32().extend(
1182 parent_translation.z + transform.translation.z * parent_scale.z,
1183 ))
1184 .with_rotation(Quaternion::from(rotation).f32()),
1185 )
1186 .reparented_to(&parent_global_transform)
1187 };
1188 #[cfg(feature = "3d")]
1189 let new_transform = GlobalTransform::from(
1190 Transform::from_translation(position.f32()).with_rotation(rotation.f32()),
1191 )
1192 .reparented_to(&parent_global_transform);
1193
1194 if let Some(mut transform) = world.get_mut::<Transform>(ctx.entity) {
1196 transform.translation = new_transform.translation;
1197 transform.rotation = new_transform.rotation;
1198 }
1199 } else if let Some(mut transform) = world.get_mut::<Transform>(ctx.entity) {
1200 #[cfg(feature = "2d")]
1202 {
1203 if !is_pos_placeholder {
1204 transform.translation = position.f32().extend(transform.translation.z);
1205 }
1206 if !is_rot_placeholder {
1207 transform.rotation = Quaternion::from(rotation).f32();
1208 }
1209 }
1210 #[cfg(feature = "3d")]
1211 {
1212 if !is_pos_placeholder {
1213 transform.translation = position.f32();
1214 }
1215 if !is_rot_placeholder {
1216 transform.rotation = rotation.f32();
1217 }
1218 }
1219 }
1220 }
1221
1222 if !config.transform_to_position {
1223 if is_pos_placeholder && let Some(mut position) = world.get_mut::<Position>(ctx.entity) {
1224 position.0 = Vector::ZERO;
1225 }
1226 if is_rot_placeholder && let Some(mut rotation) = world.get_mut::<Rotation>(ctx.entity) {
1227 *rotation = Rotation::IDENTITY;
1228 }
1229 } else if is_pos_placeholder || is_rot_placeholder {
1230 if let Some(global_transform) = global_transform {
1234 let (_, global_rotation, global_translation) =
1236 global_transform.to_scale_rotation_translation();
1237 #[cfg(feature = "2d")]
1238 {
1239 position.0 = global_translation.truncate().adjust_precision();
1240 rotation = Rotation::from(global_rotation.adjust_precision());
1241 }
1242 #[cfg(feature = "3d")]
1243 {
1244 position.0 = global_translation.adjust_precision();
1245 rotation.0 = global_rotation.adjust_precision();
1246 }
1247 } else {
1248 if is_pos_placeholder {
1250 position.0 = Vector::ZERO;
1251 }
1252 if is_rot_placeholder {
1253 rotation = Rotation::IDENTITY;
1254 }
1255 }
1256
1257 let mut entity_mut = world.entity_mut(ctx.entity);
1259
1260 if let Some(mut pos) = entity_mut
1262 .get_mut::<Position>()
1263 .filter(|pos| **pos == Position::PLACEHOLDER)
1264 {
1265 *pos = position;
1266 }
1267 if let Some(mut rot) = entity_mut
1269 .get_mut::<Rotation>()
1270 .filter(|rot| **rot == Rotation::PLACEHOLDER)
1271 {
1272 *rot = rotation;
1273 }
1274 }
1275}