Skip to content

Commit 4a31626

Browse files
Add Mul operator for Quaternion + Vector3.
1 parent cdf6c5c commit 4a31626

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

godot-core/src/builtin/quaternion.rs

+13
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,19 @@ impl Mul<Quaternion> for Quaternion {
281281
}
282282
}
283283

284+
impl Mul<Vector3> for Quaternion {
285+
type Output = Vector3;
286+
287+
/// Multiplies a quaternion to a vector, which functionally rotates this
288+
/// vector as a 3D point by this quaternion
289+
///
290+
/// # Panics
291+
/// If the quaternion is not normalized
292+
fn mul(self, rhs: Vector3) -> Self::Output {
293+
Vector3::from_glam(self.to_glam().mul_vec3(rhs.to_glam()))
294+
}
295+
}
296+
284297
// SAFETY:
285298
// This type is represented as `Self` in Godot, so `*mut Self` is sound.
286299
unsafe impl GodotFfi for Quaternion {

godot-core/src/builtin/vectors/vector_macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -419,14 +419,14 @@ macro_rules! impl_vector_fns {
419419
}
420420

421421
/// Converts the corresponding `glam` type to `Self`.
422-
fn from_glam(v: $GlamVector) -> Self {
422+
pub(crate) fn from_glam(v: $GlamVector) -> Self {
423423
Self::new(
424424
$( v.$comp ),*
425425
)
426426
}
427427

428428
/// Converts `self` to the corresponding `glam` type.
429-
fn to_glam(self) -> $GlamVector {
429+
pub(crate) fn to_glam(self) -> $GlamVector {
430430
<$GlamVector>::new(
431431
$( self.$comp ),*
432432
)

itest/rust/src/builtin_tests/geometry/quaternion_test.rs

+24
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,28 @@ fn quaternion_spherical_cubic_interpolate_in_time() {
178178
);
179179
assert_eq!(outcome, Quaternion::default())
180180
}
181+
182+
#[itest]
183+
fn quaternion_mul1() {
184+
use godot::builtin::real;
185+
use std::f32::consts::PI;
186+
187+
let q = Quaternion::from_axis_angle(Vector3::UP, PI / 2.0 as real);
188+
let rotated = q * Vector3::new(1.0, 4.2, 0.0);
189+
assert_eq_approx!(rotated.x, 0.0);
190+
assert_eq_approx!(rotated.y, 4.2);
191+
assert_eq_approx!(rotated.z, -1.0);
192+
}
193+
194+
#[itest]
195+
fn quaternion_mul2() {
196+
use godot::builtin::real;
197+
use std::f32::consts::PI;
198+
199+
let q = Quaternion::from_axis_angle(-Vector3::UP, PI / 2.0 as real);
200+
let rotated = q * Vector3::new(1.0, 4.2, 2.0);
201+
assert_eq_approx!(rotated.x, -2.0);
202+
assert_eq_approx!(rotated.y, 4.2);
203+
assert_eq_approx!(rotated.z, 1.0);
204+
}
181205
// TODO more tests

0 commit comments

Comments
 (0)