1#![allow(clippy::unnecessary_cast)]
4
5use crate::{math::Real, physics_transform::PhysicsTransformConfig, prelude::*};
6use bevy::{
7 ecs::{lifecycle::HookContext, world::DeferredWorld},
8 prelude::*,
9};
10use bevy_curve::{Curve, Ease, FunctionCurve, Interval};
11use derive_more::From;
12
13#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
30#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
31#[cfg_attr(feature = "2d", doc = " Position::from_xy(0.0, 20.0),")]
37#[cfg_attr(feature = "3d", doc = " Position::from_xyz(0.0, 2.0, 0.0),")]
38#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
42#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
43#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
44#[reflect(Debug, Component, Default, PartialEq)]
45pub struct Position(pub RVector);
46
47impl Position {
48 pub const PLACEHOLDER: Self = Self(RVector::MAX);
52
53 pub fn new(position: RVector) -> Self {
55 Self(position)
56 }
57
58 #[cfg(feature = "2d")]
60 pub fn from_xy(x: Real, y: Real) -> Self {
61 Self(RVector::new(x, y))
62 }
63
64 #[cfg(feature = "3d")]
66 pub fn from_xyz(x: Real, y: Real, z: Real) -> Self {
67 Self(RVector::new(x, y, z))
68 }
69}
70
71impl From<GlobalTransform> for Position {
72 #[cfg(feature = "2d")]
73 fn from(value: GlobalTransform) -> Self {
74 Self::from_xy(value.translation().x.real(), value.translation().y.real())
75 }
76
77 #[cfg(feature = "3d")]
78 fn from(value: GlobalTransform) -> Self {
79 Self::from_xyz(
80 value.translation().x.real(),
81 value.translation().y.real(),
82 value.translation().z.real(),
83 )
84 }
85}
86
87impl From<&GlobalTransform> for Position {
88 #[cfg(feature = "2d")]
89 fn from(value: &GlobalTransform) -> Self {
90 Self::from_xy(value.translation().x.real(), value.translation().y.real())
91 }
92
93 #[cfg(feature = "3d")]
94 fn from(value: &GlobalTransform) -> Self {
95 Self::from_xyz(
96 value.translation().x.real(),
97 value.translation().y.real(),
98 value.translation().z.real(),
99 )
100 }
101}
102
103impl Ease for Position {
104 fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> {
105 FunctionCurve::new(Interval::UNIT, move |t| {
106 Position(RVector::lerp(start.0, end.0, t as Real))
107 })
108 }
109}
110
111#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
113#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
114#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
115#[reflect(Debug, Component, Default, PartialEq)]
116pub struct PreSolveDeltaPosition(pub Vector);
117
118#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
120#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
121#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
122#[reflect(Debug, Component, Default, PartialEq)]
123pub struct PreSolveDeltaRotation(pub Rot);
124
125#[derive(Reflect, Clone, Copy, Component, Debug, PartialEq)]
153#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
154#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
155#[reflect(Debug, Component, PartialEq)]
156#[cfg(feature = "2d")]
157pub struct Rotation {
158 pub cos: f32,
162 pub sin: f32,
166}
167
168#[cfg(feature = "2d")]
169impl Default for Rotation {
170 fn default() -> Self {
171 Self::IDENTITY
172 }
173}
174
175#[cfg(feature = "2d")]
176impl Rotation {
177 pub const PLACEHOLDER: Self = Self {
181 cos: f32::MAX,
182 sin: f32::MAX,
183 };
184
185 pub const IDENTITY: Self = Self { cos: 1.0, sin: 0.0 };
187
188 pub const PI: Self = Self {
190 cos: -1.0,
191 sin: 0.0,
192 };
193
194 pub const FRAC_PI_2: Self = Self { cos: 0.0, sin: 1.0 };
196
197 pub const FRAC_PI_3: Self = Self {
199 cos: 0.5,
200 sin: 0.866_025_4,
201 };
202
203 pub const FRAC_PI_4: Self = Self {
205 cos: core::f32::consts::FRAC_1_SQRT_2,
206 sin: core::f32::consts::FRAC_1_SQRT_2,
207 };
208
209 pub const FRAC_PI_6: Self = Self {
211 cos: 0.866_025_4,
212 sin: 0.5,
213 };
214
215 pub const FRAC_PI_8: Self = Self {
217 cos: 0.923_879_5,
218 sin: 0.382_683_43,
219 };
220
221 #[inline]
223 pub fn radians(radians: f32) -> Self {
224 #[cfg(feature = "enhanced-determinism")]
225 let (sin, cos) = (libm::sinf(radians), libm::cosf(radians));
226 #[cfg(not(feature = "enhanced-determinism"))]
227 let (sin, cos) = radians.sin_cos();
228
229 Self::from_sin_cos(sin, cos)
230 }
231
232 #[inline]
234 pub fn degrees(degrees: f32) -> Self {
235 Self::radians(degrees.to_radians())
236 }
237
238 #[deprecated(note = "renamed to just `radians` to match Bevy")]
240 pub fn from_radians(radians: f32) -> Self {
241 Self::radians(radians)
242 }
243
244 #[deprecated(note = "renamed to just `degrees` to match Bevy")]
246 pub fn from_degrees(degrees: f32) -> Self {
247 Self::degrees(degrees)
248 }
249
250 #[inline]
258 pub fn from_sin_cos(sin: f32, cos: f32) -> Self {
259 let rotation = Self { sin, cos };
260 debug_assert!(
261 rotation.is_normalized(),
262 "the given sine and cosine produce an invalid rotation: {rotation:?}"
263 );
264 rotation
265 }
266
267 #[inline]
269 pub fn as_radians(self) -> f32 {
270 #[cfg(feature = "enhanced-determinism")]
271 {
272 libm::atan2f(self.sin, self.cos)
273 }
274 #[cfg(not(feature = "enhanced-determinism"))]
275 {
276 f32::atan2(self.sin, self.cos)
277 }
278 }
279
280 #[inline]
282 pub fn as_degrees(self) -> f32 {
283 self.as_radians().to_degrees()
284 }
285
286 #[inline]
288 pub const fn sin_cos(self) -> (f32, f32) {
289 (self.sin, self.cos)
290 }
291
292 #[inline]
298 #[doc(alias = "norm")]
299 pub fn length(self) -> f32 {
300 Vec2::new(self.sin, self.cos).length()
301 }
302
303 #[inline]
312 #[doc(alias = "norm2")]
313 pub fn length_squared(self) -> f32 {
314 Vec2::new(self.sin, self.cos).length_squared()
315 }
316
317 #[inline]
321 pub fn length_recip(self) -> f32 {
322 Vec2::new(self.sin, self.cos).length_recip()
323 }
324
325 #[inline]
328 pub fn chord_length(self) -> f32 {
329 (2.0 * (1.0 - self.cos)).max(0.0).sqrt()
337 }
338
339 #[inline]
349 #[must_use]
350 pub fn try_normalize(self) -> Option<Self> {
351 let recip = self.length_recip();
352 if recip.is_finite() && recip > 0.0 {
353 Some(Self::from_sin_cos(self.sin * recip, self.cos * recip))
354 } else {
355 None
356 }
357 }
358
359 #[inline]
370 #[must_use]
371 pub fn normalize(self) -> Self {
372 let length_recip = self.length_recip();
373 Self::from_sin_cos(self.sin * length_recip, self.cos * length_recip)
374 }
375
376 #[inline]
380 #[must_use]
381 pub fn fast_renormalize(self) -> Self {
382 let length_squared = self.length_squared();
385 let approx_inv_length = 0.5 * (3.0 - length_squared);
386 Self::from_sin_cos(self.sin * approx_inv_length, self.cos * approx_inv_length)
387 }
388
389 #[inline]
391 pub fn is_finite(self) -> bool {
392 self.sin.is_finite() && self.cos.is_finite()
393 }
394
395 #[inline]
397 pub fn is_nan(self) -> bool {
398 self.sin.is_nan() || self.cos.is_nan()
399 }
400
401 #[inline]
405 pub fn is_normalized(self) -> bool {
406 (self.length_squared() - 1.0).abs() <= 2e-4
410 }
411
412 #[inline]
414 pub fn is_near_identity(self) -> bool {
415 let threshold_angle_sin = 0.000_049_692_047; self.cos > 0.0 && self.sin.abs() < threshold_angle_sin
418 }
419
420 #[inline]
422 pub fn angle_between(self, other: Self) -> f32 {
423 (other * self.inverse()).as_radians()
424 }
425
426 #[inline]
429 #[must_use]
430 #[doc(alias = "conjugate")]
431 pub fn inverse(self) -> Self {
432 Self {
433 cos: self.cos,
434 sin: -self.sin,
435 }
436 }
437
438 #[inline]
439 #[must_use]
440 pub fn add_angle_fast(&self, radians: f32) -> Self {
443 let (sin, cos) = (self.sin + radians * self.cos, self.cos - radians * self.sin);
444 let magnitude_squared = sin * sin + cos * cos;
445 let magnitude_recip = if magnitude_squared > 0.0 {
446 magnitude_squared.sqrt().recip()
447 } else {
448 0.0
449 };
450 Rotation::from_sin_cos(sin * magnitude_recip, cos * magnitude_recip)
451 }
452
453 #[inline]
492 pub fn nlerp(self, end: Self, s: f32) -> Self {
493 Self {
494 sin: self.sin.lerp(end.sin, s),
495 cos: self.cos.lerp(end.cos, s),
496 }
497 .try_normalize()
498 .unwrap_or(self)
502 }
503
504 #[inline]
530 pub fn slerp(self, end: Self, s: f32) -> Self {
531 self * Self::radians(self.angle_between(end) * s)
532 }
533}
534
535#[cfg(feature = "2d")]
536impl From<f32> for Rotation {
537 fn from(rotation: f32) -> Self {
539 Self::radians(rotation)
540 }
541}
542
543#[cfg(feature = "2d")]
544impl From<Rotation> for Mat2 {
545 fn from(rot: Rotation) -> Self {
547 Mat2::from_cols_array(&[rot.cos, rot.sin, -rot.sin, rot.cos])
548 }
549}
550
551#[cfg(feature = "2d")]
552impl From<Mat2> for Rotation {
553 fn from(mat: Mat2) -> Self {
555 let cos = mat.x_axis.x;
556 let sin = mat.x_axis.y;
557 Self::from_sin_cos(sin, cos)
558 }
559}
560
561#[cfg(feature = "2d")]
562impl From<Rot2> for Rotation {
563 fn from(rot: Rot2) -> Self {
565 Self::from_sin_cos(rot.sin, rot.cos)
566 }
567}
568
569#[cfg(feature = "2d")]
570impl From<Rotation> for Rot2 {
571 fn from(rot: Rotation) -> Self {
573 Self::from_sin_cos(rot.sin, rot.cos)
574 }
575}
576
577#[cfg(feature = "2d")]
578impl core::ops::Mul for Rotation {
579 type Output = Self;
580
581 fn mul(self, rhs: Self) -> Self::Output {
582 Self {
583 cos: self.cos * rhs.cos - self.sin * rhs.sin,
584 sin: self.sin * rhs.cos + self.cos * rhs.sin,
585 }
586 }
587}
588
589#[cfg(feature = "2d")]
590impl core::ops::MulAssign for Rotation {
591 fn mul_assign(&mut self, rhs: Self) {
592 *self = *self * rhs;
593 }
594}
595
596#[cfg(feature = "2d")]
597impl core::ops::Mul<Vec2> for Rotation {
598 type Output = Vec2;
599
600 fn mul(self, rhs: Vec2) -> Self::Output {
602 Vec2::new(
603 rhs.x * self.cos - rhs.y * self.sin,
604 rhs.x * self.sin + rhs.y * self.cos,
605 )
606 }
607}
608
609#[cfg(feature = "2d")]
610impl core::ops::Mul<Vec3> for Rotation {
611 type Output = Vec3;
612
613 fn mul(self, rhs: Vec3) -> Self::Output {
614 Vec3::new(
615 rhs.x * self.cos - rhs.y * self.sin,
616 rhs.x * self.sin + rhs.y * self.cos,
617 rhs.z,
618 )
619 }
620}
621
622#[cfg(feature = "2d")]
623impl core::ops::Mul<&Vec3> for Rotation {
624 type Output = Vec3;
625
626 fn mul(self, rhs: &Vec3) -> Self::Output {
627 self * *rhs
628 }
629}
630
631#[cfg(feature = "2d")]
632impl core::ops::Mul<&mut Vec3> for Rotation {
633 type Output = Vec3;
634
635 fn mul(self, rhs: &mut Vec3) -> Self::Output {
636 self * *rhs
637 }
638}
639
640#[cfg(feature = "2d")]
641impl core::ops::Mul<Vec3> for &Rotation {
642 type Output = Vec3;
643
644 fn mul(self, rhs: Vec3) -> Self::Output {
645 *self * rhs
646 }
647}
648
649#[cfg(feature = "2d")]
650impl core::ops::Mul<&Vec3> for &Rotation {
651 type Output = Vec3;
652
653 fn mul(self, rhs: &Vec3) -> Self::Output {
654 *self * *rhs
655 }
656}
657
658#[cfg(feature = "2d")]
659impl core::ops::Mul<&mut Vec3> for &Rotation {
660 type Output = Vec3;
661
662 fn mul(self, rhs: &mut Vec3) -> Self::Output {
663 *self * *rhs
664 }
665}
666
667#[cfg(feature = "2d")]
668impl core::ops::Mul<Vec3> for &mut Rotation {
669 type Output = Vec3;
670
671 fn mul(self, rhs: Vec3) -> Self::Output {
672 *self * rhs
673 }
674}
675
676#[cfg(feature = "2d")]
677impl core::ops::Mul<&Vec3> for &mut Rotation {
678 type Output = Vec3;
679
680 fn mul(self, rhs: &Vec3) -> Self::Output {
681 *self * *rhs
682 }
683}
684
685#[cfg(feature = "2d")]
686impl core::ops::Mul<&mut Vec3> for &mut Rotation {
687 type Output = Vec3;
688
689 fn mul(self, rhs: &mut Vec3) -> Self::Output {
690 *self * *rhs
691 }
692}
693
694impl Ease for Rotation {
695 fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> {
696 FunctionCurve::new(Interval::UNIT, move |t| Rotation::slerp(start, end, t))
697 }
698}
699
700#[cfg(feature = "3d")]
725#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq)]
726#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
727#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
728#[reflect(Debug, Component, Default, PartialEq)]
729pub struct Rotation(pub Quat);
730
731#[cfg(feature = "3d")]
732impl Rotation {
733 pub const PLACEHOLDER: Self = Self(Quat::from_xyzw(f32::MAX, f32::MAX, f32::MAX, f32::MAX));
737
738 pub const IDENTITY: Self = Self(Quat::IDENTITY);
740
741 #[inline]
744 pub fn chord_length(self) -> f32 {
745 2.0 * self.xyz().length()
751 }
752
753 #[inline]
755 pub fn angle_between(self, other: Self) -> f32 {
756 self.0.angle_between(other.0)
757 }
758
759 #[inline]
761 #[must_use]
762 pub fn inverse(&self) -> Self {
763 Self(self.0.inverse())
764 }
765
766 #[inline]
778 pub fn nlerp(self, end: Self, t: f32) -> Self {
779 Self(self.0.lerp(end.0, t))
780 }
781
782 #[inline]
793 pub fn slerp(self, end: Self, t: f32) -> Self {
794 Self(self.0.slerp(end.0, t))
795 }
796
797 #[inline]
801 #[must_use]
802 pub fn fast_renormalize(self) -> Self {
803 let length_squared = self.length_squared();
806 let approx_inv_length = 0.5 * (3.0 - length_squared);
807 Self(self.0 * approx_inv_length)
808 }
809}
810
811#[cfg(feature = "3d")]
812impl core::ops::Mul<Vec3> for Rotation {
813 type Output = Vec3;
814
815 fn mul(self, vector: Vec3) -> Self::Output {
816 self.0 * vector
817 }
818}
819
820#[cfg(feature = "3d")]
821impl core::ops::Mul for Rotation {
822 type Output = Rotation;
823
824 fn mul(self, rhs: Self) -> Self::Output {
825 Self(self.0 * rhs.0)
826 }
827}
828
829#[cfg(feature = "3d")]
830impl core::ops::MulAssign for Rotation {
831 fn mul_assign(&mut self, rhs: Self) {
832 self.0 *= rhs.0;
833 }
834}
835
836#[cfg(feature = "3d")]
837impl core::ops::Mul<Quat> for Rotation {
838 type Output = Quat;
839
840 fn mul(self, quaternion: Quat) -> Self::Output {
841 self.0 * quaternion
842 }
843}
844
845#[cfg(feature = "3d")]
846impl core::ops::Mul<Quat> for &Rotation {
847 type Output = Quat;
848
849 fn mul(self, quaternion: Quat) -> Self::Output {
850 self.0 * quaternion
851 }
852}
853
854#[cfg(feature = "3d")]
855impl core::ops::Mul<Quat> for &mut Rotation {
856 type Output = Quat;
857
858 fn mul(self, quaternion: Quat) -> Self::Output {
859 self.0 * quaternion
860 }
861}
862
863#[cfg(feature = "3d")]
864impl core::ops::Mul<Rotation> for Quat {
865 type Output = Rotation;
866
867 fn mul(self, rotation: Rotation) -> Self::Output {
868 Rotation(self * rotation.0)
869 }
870}
871
872#[cfg(feature = "3d")]
873impl core::ops::Mul<Rotation> for &Quat {
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 &mut Quat {
883 type Output = Rotation;
884
885 fn mul(self, rotation: Rotation) -> Self::Output {
886 Rotation(*self * rotation.0)
887 }
888}
889
890impl core::ops::Mul<Dir> for Rotation {
891 type Output = Dir;
892
893 fn mul(self, direction: Dir) -> Self::Output {
894 Dir::new_unchecked(self * *direction)
895 }
896}
897
898impl core::ops::Mul<Vector> for &Rotation {
899 type Output = Vector;
900
901 fn mul(self, vector: Vector) -> Self::Output {
902 *self * vector
903 }
904}
905
906impl core::ops::Mul<Dir> for &Rotation {
907 type Output = Dir;
908
909 fn mul(self, direction: Dir) -> Self::Output {
910 Dir::new_unchecked(self * *direction)
911 }
912}
913
914impl core::ops::Mul<Vector> for &mut Rotation {
915 type Output = Vector;
916
917 fn mul(self, vector: Vector) -> Self::Output {
918 *self * vector
919 }
920}
921
922impl core::ops::Mul<Dir> for &mut Rotation {
923 type Output = Dir;
924
925 fn mul(self, direction: Dir) -> Self::Output {
926 Dir::new_unchecked(self * *direction)
927 }
928}
929
930impl core::ops::Mul<&Vector> for Rotation {
931 type Output = Vector;
932
933 fn mul(self, vector: &Vector) -> Self::Output {
934 self * *vector
935 }
936}
937
938impl core::ops::Mul<&Dir> for Rotation {
939 type Output = Dir;
940
941 fn mul(self, direction: &Dir) -> Self::Output {
942 Dir::new_unchecked(self * **direction)
943 }
944}
945
946impl core::ops::Mul<&mut Vector> for Rotation {
947 type Output = Vector;
948
949 fn mul(self, vector: &mut Vector) -> Self::Output {
950 self * *vector
951 }
952}
953
954impl core::ops::Mul<&mut Dir> for Rotation {
955 type Output = Dir;
956
957 fn mul(self, direction: &mut Dir) -> Self::Output {
958 Dir::new_unchecked(self * **direction)
959 }
960}
961
962impl core::ops::Mul<&Vector> for &Rotation {
963 type Output = Vector;
964
965 fn mul(self, vector: &Vector) -> Self::Output {
966 *self * *vector
967 }
968}
969
970impl core::ops::Mul<&Dir> for &Rotation {
971 type Output = Dir;
972
973 fn mul(self, direction: &Dir) -> Self::Output {
974 Dir::new_unchecked(self * **direction)
975 }
976}
977
978impl core::ops::Mul<&Vector> for &mut Rotation {
979 type Output = Vector;
980
981 fn mul(self, vector: &Vector) -> Self::Output {
982 *self * *vector
983 }
984}
985
986impl core::ops::Mul<&Dir> for &mut Rotation {
987 type Output = Dir;
988
989 fn mul(self, direction: &Dir) -> Self::Output {
990 Dir::new_unchecked(self * **direction)
991 }
992}
993
994impl core::ops::Mul<&mut Vector> for &Rotation {
995 type Output = Vector;
996
997 fn mul(self, vector: &mut Vector) -> Self::Output {
998 *self * *vector
999 }
1000}
1001
1002impl core::ops::Mul<&mut Dir> for &Rotation {
1003 type Output = Dir;
1004
1005 fn mul(self, direction: &mut Dir) -> Self::Output {
1006 Dir::new_unchecked(self * **direction)
1007 }
1008}
1009
1010impl core::ops::Mul<&mut Vector> for &mut Rotation {
1011 type Output = Vector;
1012
1013 fn mul(self, vector: &mut Vector) -> Self::Output {
1014 *self * *vector
1015 }
1016}
1017
1018impl core::ops::Mul<&mut Dir> for &mut Rotation {
1019 type Output = Dir;
1020
1021 fn mul(self, direction: &mut Dir) -> Self::Output {
1022 Dir::new_unchecked(self * **direction)
1023 }
1024}
1025
1026#[cfg(feature = "2d")]
1027impl From<Rotation> for f32 {
1028 fn from(rot: Rotation) -> Self {
1029 rot.as_radians()
1030 }
1031}
1032
1033#[cfg(feature = "2d")]
1034impl From<Rotation> for Quat {
1035 fn from(rot: Rotation) -> Self {
1036 let z = rot.sin.signum() * ((1.0 - rot.cos) / 2.0).abs().sqrt();
1037 let w = ((1.0 + rot.cos) / 2.0).abs().sqrt();
1038 Quat::from_xyzw(0.0, 0.0, z, w)
1039 }
1040}
1041
1042#[cfg(feature = "3d")]
1043impl From<Rotation> for Quat {
1044 fn from(rot: Rotation) -> Self {
1045 rot.0
1046 }
1047}
1048
1049impl From<Transform> for Rotation {
1050 fn from(value: Transform) -> Self {
1051 Self::from(value.rotation)
1052 }
1053}
1054
1055impl From<GlobalTransform> for Rotation {
1056 fn from(value: GlobalTransform) -> Self {
1057 Self::from(value.compute_transform().rotation)
1058 }
1059}
1060
1061impl From<&GlobalTransform> for Rotation {
1062 fn from(value: &GlobalTransform) -> Self {
1063 Self::from(value.compute_transform().rotation)
1064 }
1065}
1066
1067#[cfg(feature = "2d")]
1068impl From<Quat> for Rotation {
1069 fn from(quat: Quat) -> Self {
1070 let angle = quat.to_euler(EulerRot::XYZ).2;
1071 Self::radians(angle)
1072 }
1073}
1074
1075#[cfg(feature = "3d")]
1076impl From<Quat> for Rotation {
1077 fn from(quat: Quat) -> Self {
1078 Self(Quat::from_xyzw(quat.x, quat.y, quat.z, quat.w))
1079 }
1080}
1081
1082pub(crate) fn init_physics_transform(world: &mut DeferredWorld, ctx: &HookContext) {
1083 let entity_ref = world.entity(ctx.entity);
1084
1085 let (mut position, is_pos_placeholder) = entity_ref
1087 .get::<Position>()
1088 .map_or((default(), true), |p| (*p, *p == Position::PLACEHOLDER));
1089 let (mut rotation, is_rot_placeholder) = entity_ref
1090 .get::<Rotation>()
1091 .map_or((default(), true), |r| (*r, *r == Rotation::PLACEHOLDER));
1092
1093 if is_pos_placeholder {
1094 position.0 = RVector::ZERO;
1095 }
1096 if is_rot_placeholder {
1097 rotation = Rotation::IDENTITY;
1098 }
1099
1100 let is_not_placeholder = !is_pos_placeholder || !is_rot_placeholder;
1102
1103 let config = world
1104 .get_resource::<PhysicsTransformConfig>()
1105 .cloned()
1106 .unwrap_or_default();
1107
1108 let mut parent_global_transform = GlobalTransform::default();
1109
1110 let mut curr_parent = world.get::<ChildOf>(ctx.entity);
1112 while let Some(parent) = curr_parent {
1113 if let Some(parent_transform) = world.get::<Transform>(parent.0) {
1114 parent_global_transform = *parent_transform * parent_global_transform;
1115 }
1116 curr_parent = world.get::<ChildOf>(parent.0);
1117 }
1118
1119 let transform = world.get::<Transform>(ctx.entity).copied();
1120 let global_transform = transform.map(|transform| {
1121 let global_transform = parent_global_transform * GlobalTransform::from(transform);
1122 *world.get_mut::<GlobalTransform>(ctx.entity).unwrap() = global_transform;
1124 global_transform
1125 });
1126
1127 if is_not_placeholder && config.position_to_transform {
1130 if parent_global_transform != GlobalTransform::default() {
1132 #[cfg(feature = "2d")]
1133 let Some(transform) = transform else {
1134 return;
1135 };
1136
1137 #[cfg(feature = "2d")]
1140 let new_transform =
1141 {
1142 let (parent_translation, parent_scale) = (
1143 parent_global_transform.translation(),
1144 parent_global_transform.scale(),
1145 );
1146 GlobalTransform::from(
1147 Transform::from_translation(position.f32().extend(
1148 parent_translation.z + transform.translation.z * parent_scale.z,
1149 ))
1150 .with_rotation(Quat::from(rotation)),
1151 )
1152 .reparented_to(&parent_global_transform)
1153 };
1154 #[cfg(feature = "3d")]
1155 let new_transform = GlobalTransform::from(
1156 Transform::from_translation(position.f32()).with_rotation(rotation.0),
1157 )
1158 .reparented_to(&parent_global_transform);
1159
1160 if let Some(mut transform) = world.get_mut::<Transform>(ctx.entity) {
1162 transform.translation = new_transform.translation;
1163 transform.rotation = new_transform.rotation;
1164 }
1165 } else if let Some(mut transform) = world.get_mut::<Transform>(ctx.entity) {
1166 #[cfg(feature = "2d")]
1168 {
1169 if !is_pos_placeholder {
1170 transform.translation = position.f32().extend(transform.translation.z);
1171 }
1172 if !is_rot_placeholder {
1173 transform.rotation = Quat::from(rotation);
1174 }
1175 }
1176 #[cfg(feature = "3d")]
1177 {
1178 if !is_pos_placeholder {
1179 transform.translation = position.f32();
1180 }
1181 if !is_rot_placeholder {
1182 transform.rotation = rotation.0;
1183 }
1184 }
1185 }
1186 }
1187
1188 if !config.transform_to_position {
1189 if is_pos_placeholder && let Some(mut position) = world.get_mut::<Position>(ctx.entity) {
1190 position.0 = RVector::ZERO;
1191 }
1192 if is_rot_placeholder && let Some(mut rotation) = world.get_mut::<Rotation>(ctx.entity) {
1193 *rotation = Rotation::IDENTITY;
1194 }
1195 } else if is_pos_placeholder || is_rot_placeholder {
1196 if let Some(global_transform) = global_transform {
1200 let (_, global_rotation, global_translation) =
1202 global_transform.to_scale_rotation_translation();
1203 #[cfg(feature = "2d")]
1204 {
1205 position.0 = global_translation.truncate().real();
1206 rotation = Rotation::from(global_rotation);
1207 }
1208 #[cfg(feature = "3d")]
1209 {
1210 position.0 = global_translation.real();
1211 rotation.0 = global_rotation;
1212 }
1213 } else {
1214 if is_pos_placeholder {
1216 position.0 = RVector::ZERO;
1217 }
1218 if is_rot_placeholder {
1219 rotation = Rotation::IDENTITY;
1220 }
1221 }
1222
1223 let mut entity_mut = world.entity_mut(ctx.entity);
1225
1226 if let Some(mut pos) = entity_mut
1228 .get_mut::<Position>()
1229 .filter(|pos| **pos == Position::PLACEHOLDER)
1230 {
1231 *pos = position;
1232 }
1233 if let Some(mut rot) = entity_mut
1235 .get_mut::<Rotation>()
1236 .filter(|rot| **rot == Rotation::PLACEHOLDER)
1237 {
1238 *rot = rotation;
1239 }
1240 }
1241}