Skip to content

Commit 7da3b4d

Browse files
committed
Add snapped to integer vectors
1 parent feff365 commit 7da3b4d

File tree

7 files changed

+63
-25
lines changed

7 files changed

+63
-25
lines changed

Diff for: godot-core/src/builtin/vectors/vector2i.rs

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ impl_vector_fns!(Vector2i, glam::IVec2, i32, (x, y));
4444
impl_vector2x_fns!(Vector2i, i32);
4545

4646
impl Vector2i {
47+
impl_integer_vector_fns!(x, y);
48+
4749
/// Constructs a new `Vector2i` from a [`Vector2`]. The floating point coordinates will be truncated.
4850
#[inline]
4951
pub const fn from_vector2(v: Vector2) -> Self {

Diff for: godot-core/src/builtin/vectors/vector3i.rs

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ impl_vector_fns!(Vector3i, glam::IVec3, i32, (x, y, z));
4747
impl_vector3x_fns!(Vector3i, i32);
4848

4949
impl Vector3i {
50+
impl_integer_vector_fns!(x, y, z);
51+
5052
/// Constructs a new `Vector3i` from a [`Vector3`]. The floating point coordinates will be truncated.
5153
#[inline]
5254
pub const fn from_vector3(v: Vector3) -> Self {

Diff for: godot-core/src/builtin/vectors/vector4i.rs

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ impl_vector_fns!(Vector4i, glam::IVec4, i32, (x, y, z, w));
4848
impl_vector4x_fns!(Vector4i, i32);
4949

5050
impl Vector4i {
51+
impl_integer_vector_fns!(x, y, z, w);
52+
5153
/// Constructs a new `Vector4i` from a [`Vector4`]. The floating point coordinates will be
5254
/// truncated.
5355
#[inline]

Diff for: godot-core/src/builtin/vectors/vector_macros.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,42 @@ macro_rules! impl_vector_fns {
457457
}
458458
}
459459

460+
/// Implements functions that are present only on integer vectors.
461+
macro_rules! impl_integer_vector_fns {
462+
(
463+
// Names of the components, for example `x, y`.
464+
$($comp:ident),*
465+
) => {
466+
/// A new vector with each component snapped to the closest multiple of the corresponding
467+
/// component in `step`.
468+
pub fn snapped(self, step: Self) -> Self {
469+
#[inline]
470+
fn snap_one(mut value: i32, step: i32) -> i32 {
471+
if step != 0 {
472+
let a = value + step / 2;
473+
474+
// manual implement `a.div_floor(step)` since Rust's native method is still unstable, as of 1.79.0
475+
let mut d = a / step;
476+
let r = a % step;
477+
if (r > 0 && step < 0) || (r < 0 && step > 0) {
478+
d -= 1;
479+
}
480+
481+
value = step * d;
482+
}
483+
484+
value
485+
}
486+
487+
Self::new(
488+
$(
489+
snap_one(self.$comp, step.$comp)
490+
),*
491+
)
492+
}
493+
};
494+
}
495+
460496
/// Implements functions that are present only on floating-point vectors.
461497
macro_rules! impl_float_vector_fns {
462498
(
@@ -612,7 +648,6 @@ macro_rules! impl_float_vector_fns {
612648

613649
/// A new vector with each component snapped to the closest multiple of the corresponding
614650
/// component in `step`.
615-
// TODO: also implement for integer vectors
616651
#[inline]
617652
pub fn snapped(self, step: Self) -> Self {
618653
Self::new(

Diff for: itest/rust/src/builtin_tests/geometry/vector_test/vector2i_test.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,10 @@ fn sign() {
102102
assert_eq!(b.sign(), b.as_inner().sign());
103103
}
104104

105-
// TODO: implement snapped for integer vectors
106-
// #[itest]
107-
// fn snapped() {
108-
// let a = Vector2i::new(12, 34);
109-
// let b = Vector2i::new(5, -5);
110-
111-
// assert_eq!(a.snapped(b), a.as_inner().snapped(b));
112-
// }
105+
#[itest]
106+
fn snapped() {
107+
let a = Vector2i::new(12, 34);
108+
let b = Vector2i::new(5, -5);
109+
110+
assert_eq!(a.snapped(b), a.as_inner().snapped(b));
111+
}

Diff for: itest/rust/src/builtin_tests/geometry/vector_test/vector3i_test.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,10 @@ fn sign() {
9999
assert_eq!(b.sign(), b.as_inner().sign());
100100
}
101101

102-
// TODO: implement snapped for integer vectors
103-
// #[itest]
104-
// fn snapped() {
105-
// let a = Vector3i::new(12, 34, 56);
106-
// let b = Vector3i::new(5, -5, 6);
107-
108-
// assert_eq!(a.snapped(b), a.as_inner().snapped(b));
109-
// }
102+
#[itest]
103+
fn snapped() {
104+
let a = Vector3i::new(12, 34, -56);
105+
let b = Vector3i::new(5, -5, 6);
106+
107+
assert_eq!(a.snapped(b), a.as_inner().snapped(b));
108+
}

Diff for: itest/rust/src/builtin_tests/geometry/vector_test/vector4i_test.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,10 @@ fn sign() {
103103
assert_eq!(b.sign(), b.as_inner().sign());
104104
}
105105

106-
// TODO: implement snapped for integer vectors
107-
// #[itest]
108-
// fn snapped() {
109-
// let a = Vector4i::new(12, 34, 56, 78);
110-
// let b = Vector4i::new(5, -5, 6, -6);
111-
112-
// assert_eq!(a.snapped(b), a.as_inner().snapped(b));
113-
// }
106+
#[itest]
107+
fn snapped() {
108+
let a = Vector4i::new(12, 34, 56, -78);
109+
let b = Vector4i::new(5, -5, 6, 6);
110+
111+
assert_eq!(a.snapped(b), a.as_inner().snapped(b));
112+
}

0 commit comments

Comments
 (0)