Skip to content

Commit b863148

Browse files
committed
Incorporate feedback
* s/core::/std:: * Add documentation to IDENTITY constant * s/get_euler/to_euler * Use Basis::to_euler for to_euler instead. Incidentally, this fixes the precision issue in to_the euler test. * Remove set_axis_angle and set_euler * Make Basis::to_quat private. The implementation could perhaps be moved to Quat::from_basis instead?
1 parent bcf3f40 commit b863148

File tree

1 file changed

+17
-51
lines changed
  • gdnative-core/src/core_types

1 file changed

+17
-51
lines changed

gdnative-core/src/core_types/quat.rs

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
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).
1817
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.
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

Comments
 (0)