Skip to content

Commit 3e1fbad

Browse files
committed
Provide feature parity for Quaternion with Godot
More notable change is the renaming with deprecations for a couple methods. The new names are what Godot uses.
1 parent ff2dec6 commit 3e1fbad

File tree

1 file changed

+39
-4
lines changed

1 file changed

+39
-4
lines changed

godot-core/src/builtin/quaternion.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ pub struct Quaternion {
3030
}
3131

3232
impl Quaternion {
33+
/// The identity quaternion, representing no rotation. This has the same rotation as [`Basis::IDENTITY`].
34+
///
35+
/// If a [`Vector3`] is rotated (multiplied) by this quaternion, it does not change.
36+
pub const IDENTITY: Self = Self {
37+
x: 0.0,
38+
y: 0.0,
39+
z: 0.0,
40+
w: 1.0,
41+
};
42+
3343
pub fn new(x: real, y: real, z: real, w: real) -> Self {
3444
Self { x, y, z, w }
3545
}
@@ -54,9 +64,28 @@ impl Quaternion {
5464
Self::new(x, y, z, w)
5565
}
5666

57-
// TODO: Constructors.
58-
// pub fn from_vector_vector(arc_to: Vector3, arc_from: Vector3) -> Self {}
59-
// pub fn from_basis(basis: Basis) -> Self {}
67+
/// Constructs a Quaternion representing the shortest arc between `arc_from` and `arc_to`.
68+
///
69+
/// These can be imagined as two points intersecting a unit sphere's surface, with a radius of 1.0.
70+
///
71+
// This is an undocumented assumption of Godot's as well.
72+
/// The inputs must be unit vectors.
73+
///
74+
/// For near-singular cases (`arc_from`≈`arc_to` or `arc_from`≈-`arc_to`) the current implementation is only accurate to about
75+
/// 0.001, or better if `double-precision` is enabled.
76+
///
77+
/// *Godot equivalent: `Quaternion(arc_from: Vector3, arc_to: Vector3)`*
78+
pub fn from_rotation_arc(arc_from: Vector3, arc_to: Vector3) -> Self {
79+
debug_assert!(
80+
arc_from.is_normalized(),
81+
"input 1 (`arc_from`) in `Quaternion::from_rotation_arc` must be a unit vector"
82+
);
83+
debug_assert!(
84+
arc_to.is_normalized(),
85+
"input 2 (`arc_to`) in `Quaternion::from_rotation_arc` must be a unit vector"
86+
);
87+
<Self as GlamConv>::Glam::from_rotation_arc(arc_from.to_glam(), arc_to.to_glam()).to_front()
88+
}
6089

6190
pub fn angle_to(self, to: Self) -> real {
6291
self.glam2(&to, RQuat::angle_between)
@@ -66,7 +95,7 @@ impl Quaternion {
6695
self.glam2(&with, RQuat::dot)
6796
}
6897

69-
pub fn to_exp(self) -> Self {
98+
pub fn exp(self) -> Self {
7099
let mut v = Vector3::new(self.x, self.y, self.z);
71100
let theta = v.length();
72101
v = v.normalized();
@@ -78,6 +107,11 @@ impl Quaternion {
78107
}
79108
}
80109

110+
#[deprecated = "Moved to `Quaternion::exp()`"]
111+
pub fn to_exp(self) -> Self {
112+
self.exp()
113+
}
114+
81115
pub fn from_euler(euler: Vector3) -> Self {
82116
let half_a1 = euler.y * 0.5;
83117
let half_a2 = euler.x * 0.5;
@@ -113,6 +147,7 @@ impl Quaternion {
113147
}
114148
}
115149

150+
#[doc(alias = "get_euler")]
116151
pub fn to_euler(self, order: EulerOrder) -> Vector3 {
117152
Basis::from_quat(self).to_euler(order)
118153
}

0 commit comments

Comments
 (0)