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}