1- use super :: { Basis , IsEqualApprox , Vector3 , CMP_EPSILON } ;
2- use core:: f32:: consts:: FRAC_PI_2 ;
3- use core:: ops:: Mul ;
4- use glam:: Mat3 ;
1+ use super :: { Basis , IsEqualApprox , Vector3 } ;
2+ use glam:: { Mat3 , EulerRot } ;
3+ use std:: ops:: Mul ;
54
65#[ derive( Copy , Clone , Debug , PartialEq ) ]
76#[ repr( C ) ]
@@ -16,6 +15,8 @@ pub struct Quat {
1615///
1716/// See the official [`Godot documentation`](https://docs.godotengine.org/en/stable/classes/class_quat.html).
1817impl Quat {
18+ /// The identity quaternion, representing no rotation. Equivalent to an identity [`Basis`] matrix.
19+ /// If a vector is transformed by an identity quaternion, it will not change.
1920 pub const IDENTITY : Self = Self :: new ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
2021
2122 /// Constructs a quaternion defined by the given values.
@@ -35,7 +36,7 @@ impl Quat {
3536 /// (X angle, Y angle, Z angle).
3637 #[ inline]
3738 pub fn from_euler ( euler : Vector3 ) -> Self {
38- Self :: gd ( glam:: Quat :: from_rotation_ypr ( euler. y , euler. x , euler. z ) )
39+ Self :: gd ( glam:: Quat :: from_euler ( EulerRot :: YXZ , euler. y , euler. x , euler. z ) )
3940 }
4041
4142 /// Constructs a quaternion that will rotate around the given axis by the specified angle. The
@@ -66,34 +67,15 @@ impl Quat {
6667 /// corresponding to the rotation represented by the unit quaternion. Returned vector contains
6768 /// the rotation angles in the format (X angle, Y angle, Z angle).
6869 #[ inline]
69- pub fn get_euler ( self ) -> Vector3 {
70- let basis = Mat3 :: from_quat ( self . glam ( ) ) ;
71- let elm = basis. to_cols_array_2d ( ) ;
72- // Copied from Basis::get_euler_yxz
73- let m12 = elm[ 1 ] [ 2 ] ;
74- if m12 < 1.0 - CMP_EPSILON as f32 {
75- if m12 > CMP_EPSILON as f32 - 1.0 {
76- #[ allow( clippy:: float_cmp) ] // Godot also used direct comparison
77- if elm[ 1 ] [ 0 ] == 0.0
78- && elm[ 0 ] [ 1 ] == 0.0
79- && elm[ 0 ] [ 2 ] == 0.0
80- && elm[ 2 ] [ 0 ] == 0.0
81- && elm[ 0 ] [ 0 ] == 1.0
82- {
83- Vector3 :: new ( ( -m12) . atan2 ( elm[ 1 ] [ 1 ] ) , 0.0 , 0.0 )
84- } else {
85- Vector3 :: new (
86- ( -m12) . asin ( ) ,
87- elm[ 0 ] [ 2 ] . atan2 ( elm[ 2 ] [ 2 ] ) ,
88- elm[ 1 ] [ 0 ] . atan2 ( elm[ 1 ] [ 1 ] ) ,
89- )
90- }
91- } else {
92- Vector3 :: new ( FRAC_PI_2 , elm[ 0 ] [ 1 ] . atan2 ( elm[ 0 ] [ 0 ] ) , 0.0 )
93- }
94- } else {
95- Vector3 :: new ( -FRAC_PI_2 , ( -elm[ 0 ] [ 1 ] ) . atan2 ( elm[ 0 ] [ 0 ] ) , 0.0 )
96- }
70+ pub fn to_euler ( self ) -> Vector3 {
71+ let basis = Mat3 :: from_quat ( self . glam ( ) ) ;
72+ let basis = basis. to_cols_array_2d ( ) ;
73+ let basis = [
74+ Vector3 :: new ( basis[ 0 ] [ 0 ] , basis[ 1 ] [ 0 ] , basis[ 2 ] [ 0 ] ) ,
75+ Vector3 :: new ( basis[ 0 ] [ 1 ] , basis[ 1 ] [ 1 ] , basis[ 2 ] [ 1 ] ) ,
76+ Vector3 :: new ( basis[ 0 ] [ 2 ] , basis[ 1 ] [ 2 ] , basis[ 2 ] [ 2 ] ) ,
77+ ] ;
78+ Basis :: from_elements ( basis) . to_euler ( )
9779 }
9880
9981 /// Returns the inverse of the quaternion.
@@ -136,21 +118,6 @@ impl Quat {
136118 Self :: gd ( self . glam ( ) . normalize ( ) )
137119 }
138120
139- /// Sets the quaternion to a rotation which rotates around axis by the specified angle, in
140- /// radians. The axis must be a normalized vector.
141- #[ inline]
142- pub fn set_axis_angle ( & mut self , axis : Vector3 , angle : f32 ) {
143- * self = Self :: from_axis_angle ( axis, angle)
144- }
145-
146- /// Sets the quaternion to a rotation specified by Euler angles (in the YXZ convention: when
147- /// decomposing, first Z, then X, and Y last), given in the vector format as (X angle, Y angle,
148- /// Z angle).
149- #[ inline]
150- pub fn set_euler ( & mut self , euler : Vector3 ) {
151- * self = Self :: from_euler ( euler) ;
152- }
153-
154121 /// Returns the result of the spherical linear interpolation between this quaternion and to by
155122 /// amount weight.
156123 ///
@@ -243,11 +210,10 @@ mod test {
243210 }
244211
245212 #[ test]
246- fn get_euler ( ) {
213+ fn to_euler ( ) {
247214 let quat = Quat :: new ( 0.485489 , 0.142796 , -0.862501 , 0.001113 ) ;
248215 let expect = Vector3 :: new ( 0.25 , -1.043185 , 3.00001 ) ;
249- dbg ! ( quat. get_euler( ) ) ;
250- assert ! ( quat. get_euler( ) . is_equal_approx( expect) ) ;
216+ assert ! ( quat. to_euler( ) . is_equal_approx( expect) ) ;
251217 }
252218
253219 #[ test]
0 commit comments