@@ -15,7 +15,7 @@ use crate::builtin::Vector3i;
15
15
16
16
use super :: glam_helpers:: GlamConv ;
17
17
use super :: glam_helpers:: GlamType ;
18
- use super :: { real, RVec3 } ;
18
+ use super :: { real, Basis , RVec3 } ;
19
19
20
20
/// Vector used for 3D math using floating point coordinates.
21
21
///
@@ -306,6 +306,15 @@ impl Vector3 {
306
306
snapped ( self . z , step. z ) ,
307
307
)
308
308
}
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
+ }
309
318
}
310
319
311
320
/// Formats the vector like Godot: `(x, y, z)`.
@@ -369,3 +378,41 @@ impl GlamType for glam::Vec3A {
369
378
impl GlamConv for Vector3 {
370
379
type Glam = RVec3 ;
371
380
}
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