Skip to content

Commit c48eff9

Browse files
committed
Incorporate feedback, add Mul<Quat> for Quat
1 parent 1f27e29 commit c48eff9

File tree

1 file changed

+33
-12
lines changed
  • gdnative-core/src/core_types

1 file changed

+33
-12
lines changed

gdnative-core/src/core_types/quat.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ impl Quat {
106106
}
107107

108108
/// Returns a copy of the quaternion, normalized to unit length.
109+
///
110+
/// Normalization is necessary before transforming vectors through `xform()` or `*`.
109111
#[inline]
110112
pub fn normalized(self) -> Self {
111113
Self::gd(self.glam().normalize())
@@ -123,21 +125,17 @@ impl Quat {
123125
// Copied from Godot's Quat::slerp as glam::lerp version diverges too much
124126

125127
// calc cosine
126-
let cosom = self.dot(b);
128+
let cos = self.dot(b);
127129

128130
// adjust signs (if necessary)
129-
let (cosom, b) = if cosom < 0.0 {
130-
(-cosom, -b)
131-
} else {
132-
(cosom, b)
133-
};
131+
let (cos, b) = if cos < 0.0 { (-cos, -b) } else { (cos, b) };
134132

135133
// calculate coefficients
136-
let scale = if (1.0 - cosom) > CMP_EPSILON as f32 {
134+
let scale = if 1.0 - cos > CMP_EPSILON as f32 {
137135
// standard case (slerp)
138-
let omega = cosom.acos();
139-
let sinom = omega.sin();
140-
(((1.0 - t) * omega).sin() / sinom, (t * omega).sin() / sinom)
136+
let omega = cos.acos();
137+
let sin = omega.sin();
138+
(((1.0 - t) * omega).sin() / sin, (t * omega).sin() / sin)
141139
} else {
142140
// "from" and "to" quaternions are very close
143141
// ... so we can do a linear interpolation
@@ -179,7 +177,9 @@ impl Quat {
179177
}
180178
}
181179

182-
/// Returns a vector transformed (multiplied) by this quaternion.
180+
/// Returns a vector transformed (multiplied) by this quaternion. This is the same as `mul`
181+
///
182+
/// **Note:** The quaternion must be normalized.
183183
#[inline]
184184
pub fn xform(self, v: Vector3) -> Vector3 {
185185
self * v
@@ -200,12 +200,25 @@ impl Mul<Vector3> for Quat {
200200
type Output = Vector3;
201201

202202
#[inline]
203+
/// Returns a vector transformed (multiplied) by this quaternion. This is the same as `xform`
204+
///
205+
/// **Note:** The quaternion must be normalized.
203206
fn mul(self, with: Vector3) -> Vector3 {
204207
debug_assert!(self.is_normalized(), "Quaternion is not normalized");
205208
Vector3::gd(self.glam() * with.glam())
206209
}
207210
}
208211

212+
impl Mul<Self> for Quat {
213+
type Output = Self;
214+
215+
#[inline]
216+
/// Returns another quaternion transformed (multiplied) by this quaternion.
217+
fn mul(self, with: Self) -> Self {
218+
Self::gd(self.glam() * with.glam())
219+
}
220+
}
221+
209222
impl Neg for Quat {
210223
type Output = Quat;
211224

@@ -246,13 +259,21 @@ mod test {
246259
}
247260

248261
#[test]
249-
fn mul() {
262+
fn mul_vec() {
250263
let quat = Quat::new(0.485489, 0.142796, -0.862501, 0.001113);
251264
let vec = Vector3::new(2.2, 0.8, 1.65);
252265
let expect = Vector3::new(-2.43176, -0.874777, -1.234427);
253266
assert!(expect.is_equal_approx(quat * vec));
254267
}
255268

269+
#[test]
270+
fn mul_quat() {
271+
let a = Quat::new(-0.635115, -0.705592, 0.314052, 0.011812);
272+
let b = Quat::new(0.485489, 0.142796, -0.862501, 0.001113);
273+
let e = Quat::new(0.568756, -0.394417, 0.242027, 0.67998);
274+
assert!(e.is_equal_approx(a * b));
275+
}
276+
256277
#[test]
257278
fn slerp() {
258279
let q = Quat::new(-0.635115, -0.705592, 0.314052, 0.011812);

0 commit comments

Comments
 (0)