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 ;
5
4
6
5
#[ derive( Copy , Clone , Debug , PartialEq ) ]
7
6
#[ repr( C ) ]
@@ -16,6 +15,8 @@ pub struct Quat {
16
15
///
17
16
/// See the official [`Godot documentation`](https://docs.godotengine.org/en/stable/classes/class_quat.html).
18
17
impl 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.
19
20
pub const IDENTITY : Self = Self :: new ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
20
21
21
22
/// Constructs a quaternion defined by the given values.
@@ -35,7 +36,7 @@ impl Quat {
35
36
/// (X angle, Y angle, Z angle).
36
37
#[ inline]
37
38
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 ) )
39
40
}
40
41
41
42
/// Constructs a quaternion that will rotate around the given axis by the specified angle. The
@@ -66,34 +67,15 @@ impl Quat {
66
67
/// corresponding to the rotation represented by the unit quaternion. Returned vector contains
67
68
/// the rotation angles in the format (X angle, Y angle, Z angle).
68
69
#[ 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 ( )
97
79
}
98
80
99
81
/// Returns the inverse of the quaternion.
@@ -136,21 +118,6 @@ impl Quat {
136
118
Self :: gd ( self . glam ( ) . normalize ( ) )
137
119
}
138
120
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
-
154
121
/// Returns the result of the spherical linear interpolation between this quaternion and to by
155
122
/// amount weight.
156
123
///
@@ -243,11 +210,10 @@ mod test {
243
210
}
244
211
245
212
#[ test]
246
- fn get_euler ( ) {
213
+ fn to_euler ( ) {
247
214
let quat = Quat :: new ( 0.485489 , 0.142796 , -0.862501 , 0.001113 ) ;
248
215
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) ) ;
251
217
}
252
218
253
219
#[ test]
0 commit comments