Skip to content

Commit 498e54c

Browse files
bors[bot]Supreeeme
andauthored
Merge #222
222: Add .rotated() method on Vector3 r=Bromeon a=Supreeeme Fixes #221 Co-authored-by: Supreeeme <[email protected]>
2 parents 096eccd + e5eb166 commit 498e54c

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

godot-core/src/builtin/vector3.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::builtin::Vector3i;
1515

1616
use super::glam_helpers::GlamConv;
1717
use super::glam_helpers::GlamType;
18-
use super::{real, RVec3};
18+
use super::{real, Basis, RVec3};
1919

2020
/// Vector used for 3D math using floating point coordinates.
2121
///
@@ -306,6 +306,15 @@ impl Vector3 {
306306
snapped(self.z, step.z),
307307
)
308308
}
309+
310+
/// Returns this vector rotated around `axis` by `angle` radians. `axis` must be normalized.
311+
///
312+
/// # Panics
313+
/// If `axis` is not normalized.
314+
pub fn rotated(self, axis: Self, angle: real) -> Self {
315+
assert!(axis.is_normalized());
316+
Basis::from_axis_angle(axis, angle) * self
317+
}
309318
}
310319

311320
/// Formats the vector like Godot: `(x, y, z)`.
@@ -369,3 +378,41 @@ impl GlamType for glam::Vec3A {
369378
impl GlamConv for Vector3 {
370379
type Glam = RVec3;
371380
}
381+
382+
#[cfg(test)]
383+
mod test {
384+
use super::*;
385+
use godot::builtin::real_consts::TAU;
386+
use godot::private::class_macros::assert_eq_approx;
387+
388+
fn vec3_equal_approx(a: Vector3, b: Vector3) -> bool {
389+
a.is_equal_approx(b)
390+
}
391+
392+
// Translated from Godot
393+
#[test]
394+
#[allow(clippy::excessive_precision)]
395+
fn rotation() {
396+
let vector = Vector3::new(1.2, 3.4, 5.6);
397+
assert_eq_approx!(
398+
vector.rotated(Vector3::new(0.0, 1.0, 0.0), TAU),
399+
vector,
400+
vec3_equal_approx
401+
);
402+
assert_eq_approx!(
403+
vector.rotated(Vector3::new(0.0, 1.0, 0.0), TAU / 4.0),
404+
Vector3::new(5.6, 3.4, -1.2),
405+
vec3_equal_approx
406+
);
407+
assert_eq_approx!(
408+
vector.rotated(Vector3::new(1.0, 0.0, 0.0), TAU / 3.0),
409+
Vector3::new(1.2, -6.54974226119285642, 0.1444863728670914),
410+
vec3_equal_approx
411+
);
412+
assert_eq_approx!(
413+
vector.rotated(Vector3::new(0.0, 0.0, 1.0), TAU / 2.0),
414+
vector.rotated(Vector3::new(0.0, 0.0, 1.0), TAU / -2.0),
415+
vec3_equal_approx
416+
);
417+
}
418+
}

0 commit comments

Comments
 (0)