Skip to content

Commit 3a5e921

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 3a5e921

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

godot-core/src/builtin/quaternion.rs

Lines changed: 33 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,22 @@ 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!(arc_from.is_normalized(), "input 1 (`arc_from`) in `Quaternion::from_rotation_arc` must be a unit vector");
80+
debug_assert!(arc_to.is_normalized(), "input 2 (`arc_to`) in `Quaternion::from_rotation_arc` must be a unit vector");
81+
<Self as GlamConv>::Glam::from_rotation_arc(arc_from.to_glam(), arc_to.to_glam()).to_front()
82+
}
6083

6184
pub fn angle_to(self, to: Self) -> real {
6285
self.glam2(&to, RQuat::angle_between)
@@ -66,7 +89,7 @@ impl Quaternion {
6689
self.glam2(&with, RQuat::dot)
6790
}
6891

69-
pub fn to_exp(self) -> Self {
92+
pub fn exp(self) -> Self {
7093
let mut v = Vector3::new(self.x, self.y, self.z);
7194
let theta = v.length();
7295
v = v.normalized();
@@ -78,6 +101,11 @@ impl Quaternion {
78101
}
79102
}
80103

104+
#[deprecated = "Moved to `Quaternion::exp()`"]
105+
pub fn to_exp(self) -> Self {
106+
self.exp()
107+
}
108+
81109
pub fn from_euler(euler: Vector3) -> Self {
82110
let half_a1 = euler.y * 0.5;
83111
let half_a2 = euler.x * 0.5;
@@ -113,6 +141,7 @@ impl Quaternion {
113141
}
114142
}
115143

144+
#[doc(alias = "get_euler")]
116145
pub fn to_euler(self, order: EulerOrder) -> Vector3 {
117146
Basis::from_quat(self).to_euler(order)
118147
}

0 commit comments

Comments
 (0)