Skip to content

Commit 38e8f9b

Browse files
godot-core: builtin: vector: provide component-wise min/max under unambiguous name
1 parent 2c071ae commit 38e8f9b

File tree

10 files changed

+206
-36
lines changed

10 files changed

+206
-36
lines changed

godot-core/src/builtin/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ mod real_mod {
212212
/// A 4-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
213213
pub type RVec4 = glam::Vec4;
214214

215-
/// A 2x2 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
215+
/// A 2x2 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
216216
pub type RMat2 = glam::Mat2;
217217
/// A 3x3 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
218218
pub type RMat3 = glam::Mat3;
@@ -279,7 +279,7 @@ mod real_mod {
279279
/// A 4-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
280280
pub type RVec4 = glam::DVec4;
281281

282-
/// A 2x2 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
282+
/// A 2x2 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
283283
pub type RMat2 = glam::DMat2;
284284
/// A 3x3 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
285285
pub type RMat3 = glam::DMat3;
@@ -302,6 +302,8 @@ pub use crate::real;
302302
pub(crate) use real_mod::*;
303303
pub use real_mod::{consts as real_consts, real};
304304

305+
pub(crate) use glam::{IVec2, IVec3, IVec4};
306+
305307
/// A macro to coerce float-literals into the real type. Mainly used where
306308
/// you'd normally use a suffix to specity the type, such as `115.0f32`.
307309
///

godot-core/src/builtin/transform2d.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ impl Mul<Rect2> for Transform2D {
333333
let ya = self.b * rhs.position.y;
334334
let yb = self.b * rhs.end().y;
335335

336-
let position = Vector2::min(xa, xb) + Vector2::min(ya, yb) + self.origin;
337-
let end = Vector2::max(xa, xb) + Vector2::max(ya, yb) + self.origin;
336+
let position = Vector2::coord_min(xa, xb) + Vector2::coord_min(ya, yb) + self.origin;
337+
let end = Vector2::coord_max(xa, xb) + Vector2::coord_max(ya, yb) + self.origin;
338338
Rect2::new(position, end - position)
339339
}
340340
}

godot-core/src/builtin/transform3d.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,14 @@ impl Mul<Aabb> for Transform3D {
311311
let za = self.basis.col_c() * rhs.position.z;
312312
let zb = self.basis.col_c() * rhs.end().z;
313313

314-
let position =
315-
Vector3::min(xa, xb) + Vector3::min(ya, yb) + Vector3::min(za, zb) + self.origin;
316-
let end = Vector3::max(xa, xb) + Vector3::max(ya, yb) + Vector3::max(za, zb) + self.origin;
314+
let position = Vector3::coord_min(xa, xb)
315+
+ Vector3::coord_min(ya, yb)
316+
+ Vector3::coord_min(za, zb)
317+
+ self.origin;
318+
let end = Vector3::coord_max(xa, xb)
319+
+ Vector3::coord_max(ya, yb)
320+
+ Vector3::coord_max(za, zb)
321+
+ self.origin;
317322
Aabb::new(position, end - position)
318323
}
319324
}

godot-core/src/builtin/vector2.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,26 @@ impl GlamType for RVec2 {
343343
impl GlamConv for Vector2 {
344344
type Glam = RVec2;
345345
}
346+
347+
#[cfg(test)]
348+
mod test {
349+
use crate::assert_eq_approx;
350+
351+
use super::*;
352+
353+
#[test]
354+
fn coord_min_max() {
355+
let a = Vector2::new(1.2, 3.4);
356+
let b = Vector2::new(0.1, 5.6);
357+
assert_eq_approx!(
358+
a.coord_min(b),
359+
Vector2::new(0.1, 3.4),
360+
Vector2::is_equal_approx
361+
);
362+
assert_eq_approx!(
363+
a.coord_max(b),
364+
Vector2::new(1.2, 5.6),
365+
Vector2::is_equal_approx
366+
);
367+
}
368+
}

godot-core/src/builtin/vector2i.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use sys::{ffi_methods, GodotFfi};
1111

1212
use crate::builtin::Vector2;
1313

14+
use super::glam_helpers::{GlamConv, GlamType};
15+
use super::IVec2;
16+
1417
/// Vector used for 2D math using integer coordinates.
1518
///
1619
/// 2-element structure that can be used to represent positions in 2D space or any other pair of
@@ -67,13 +70,13 @@ impl Vector2i {
6770
}
6871

6972
/// Converts the corresponding `glam` type to `Self`.
70-
fn from_glam(v: glam::IVec2) -> Self {
73+
fn from_glam(v: IVec2) -> Self {
7174
Self::new(v.x, v.y)
7275
}
7376

7477
/// Converts `self` to the corresponding `glam` type.
7578
fn to_glam(self) -> glam::IVec2 {
76-
glam::IVec2::new(self.x, self.y)
79+
IVec2::new(self.x, self.y)
7780
}
7881
}
7982

@@ -105,3 +108,32 @@ pub enum Vector2iAxis {
105108
impl GodotFfi for Vector2iAxis {
106109
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
107110
}
111+
112+
impl GlamType for IVec2 {
113+
type Mapped = Vector2i;
114+
115+
fn to_front(&self) -> Self::Mapped {
116+
Vector2i::new(self.x, self.y)
117+
}
118+
119+
fn from_front(mapped: &Self::Mapped) -> Self {
120+
IVec2::new(mapped.x, mapped.y)
121+
}
122+
}
123+
124+
impl GlamConv for Vector2i {
125+
type Glam = IVec2;
126+
}
127+
128+
#[cfg(test)]
129+
mod test {
130+
use super::*;
131+
132+
#[test]
133+
fn coord_min_max() {
134+
let a = Vector2i::new(1, 3);
135+
let b = Vector2i::new(0, 5);
136+
assert_eq!(a.coord_min(b), Vector2i::new(0, 3));
137+
assert_eq!(a.coord_max(b), Vector2i::new(1, 5));
138+
}
139+
}

godot-core/src/builtin/vector3.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,10 @@ impl GlamConv for Vector3 {
381381

382382
#[cfg(test)]
383383
mod test {
384+
use crate::assert_eq_approx;
385+
384386
use super::*;
385387
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-
}
391388

392389
// Translated from Godot
393390
#[test]
@@ -397,22 +394,38 @@ mod test {
397394
assert_eq_approx!(
398395
vector.rotated(Vector3::new(0.0, 1.0, 0.0), TAU),
399396
vector,
400-
vec3_equal_approx
397+
Vector3::is_equal_approx
401398
);
402399
assert_eq_approx!(
403400
vector.rotated(Vector3::new(0.0, 1.0, 0.0), TAU / 4.0),
404401
Vector3::new(5.6, 3.4, -1.2),
405-
vec3_equal_approx
402+
Vector3::is_equal_approx
406403
);
407404
assert_eq_approx!(
408405
vector.rotated(Vector3::new(1.0, 0.0, 0.0), TAU / 3.0),
409406
Vector3::new(1.2, -6.54974226119285642, 0.1444863728670914),
410-
vec3_equal_approx
407+
Vector3::is_equal_approx
411408
);
412409
assert_eq_approx!(
413410
vector.rotated(Vector3::new(0.0, 0.0, 1.0), TAU / 2.0),
414411
vector.rotated(Vector3::new(0.0, 0.0, 1.0), TAU / -2.0),
415-
vec3_equal_approx
412+
Vector3::is_equal_approx
413+
);
414+
}
415+
416+
#[test]
417+
fn coord_min_max() {
418+
let a = Vector3::new(1.2, 3.4, 5.6);
419+
let b = Vector3::new(0.1, 5.6, 2.3);
420+
assert_eq_approx!(
421+
a.coord_min(b),
422+
Vector3::new(0.1, 3.4, 2.3),
423+
Vector3::is_equal_approx
424+
);
425+
assert_eq_approx!(
426+
a.coord_max(b),
427+
Vector3::new(1.2, 5.6, 5.6),
428+
Vector3::is_equal_approx
416429
);
417430
}
418431
}

godot-core/src/builtin/vector3i.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use sys::{ffi_methods, GodotFfi};
1111

1212
use crate::builtin::Vector3;
1313

14+
use super::glam_helpers::{GlamConv, GlamType};
15+
use super::IVec3;
16+
1417
/// Vector used for 3D math using integer coordinates.
1518
///
1619
/// 3-element structure that can be used to represent positions in 3D space or any other triple of
@@ -76,13 +79,13 @@ impl Vector3i {
7679
}
7780

7881
/// Converts the corresponding `glam` type to `Self`.
79-
fn from_glam(v: glam::IVec3) -> Self {
82+
fn from_glam(v: IVec3) -> Self {
8083
Self::new(v.x, v.y, v.z)
8184
}
8285

8386
/// Converts `self` to the corresponding `glam` type.
84-
fn to_glam(self) -> glam::IVec3 {
85-
glam::IVec3::new(self.x, self.y, self.z)
87+
fn to_glam(self) -> IVec3 {
88+
IVec3::new(self.x, self.y, self.z)
8689
}
8790
}
8891

@@ -116,3 +119,32 @@ pub enum Vector3iAxis {
116119
impl GodotFfi for Vector3iAxis {
117120
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
118121
}
122+
123+
impl GlamType for IVec3 {
124+
type Mapped = Vector3i;
125+
126+
fn to_front(&self) -> Self::Mapped {
127+
Vector3i::new(self.x, self.y, self.z)
128+
}
129+
130+
fn from_front(mapped: &Self::Mapped) -> Self {
131+
IVec3::new(mapped.x, mapped.y, mapped.z)
132+
}
133+
}
134+
135+
impl GlamConv for Vector3i {
136+
type Glam = IVec3;
137+
}
138+
139+
#[cfg(test)]
140+
mod test {
141+
use super::*;
142+
143+
#[test]
144+
fn coord_min_max() {
145+
let a = Vector3i::new(1, 3, 5);
146+
let b = Vector3i::new(0, 5, 2);
147+
assert_eq!(a.coord_min(b), Vector3i::new(0, 3, 2));
148+
assert_eq!(a.coord_max(b), Vector3i::new(1, 5, 5));
149+
}
150+
}

godot-core/src/builtin/vector4.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::fmt;
99
use godot_ffi as sys;
1010
use sys::{ffi_methods, GodotFfi};
1111

12+
use crate::builtin::math::*;
1213
use crate::builtin::Vector4i;
1314

1415
use super::glam_helpers::{GlamConv, GlamType};
@@ -80,6 +81,13 @@ impl Vector4 {
8081
fn to_glam(self) -> RVec4 {
8182
RVec4::new(self.x, self.y, self.z, self.w)
8283
}
84+
85+
pub fn is_equal_approx(self, to: Self) -> bool {
86+
is_equal_approx(self.x, to.x)
87+
&& is_equal_approx(self.y, to.y)
88+
&& is_equal_approx(self.z, to.z)
89+
&& is_equal_approx(self.w, to.w)
90+
}
8391
}
8492

8593
/// Formats the vector like Godot: `(x, y, z, w)`.
@@ -126,3 +134,26 @@ impl GlamType for RVec4 {
126134
impl GlamConv for Vector4 {
127135
type Glam = RVec4;
128136
}
137+
138+
#[cfg(test)]
139+
mod test {
140+
use crate::assert_eq_approx;
141+
142+
use super::*;
143+
144+
#[test]
145+
fn coord_min_max() {
146+
let a = Vector4::new(1.2, 3.4, 5.6, 0.1);
147+
let b = Vector4::new(0.1, 5.6, 2.3, 1.2);
148+
assert_eq_approx!(
149+
a.coord_min(b),
150+
Vector4::new(0.1, 3.4, 2.3, 0.1),
151+
Vector4::is_equal_approx
152+
);
153+
assert_eq_approx!(
154+
a.coord_max(b),
155+
Vector4::new(1.2, 5.6, 5.6, 1.2),
156+
Vector4::is_equal_approx
157+
);
158+
}
159+
}

godot-core/src/builtin/vector4i.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use sys::{ffi_methods, GodotFfi};
1111

1212
use crate::builtin::Vector4;
1313

14+
use super::glam_helpers::{GlamConv, GlamType};
15+
use super::IVec4;
16+
1417
/// Vector used for 4D math using integer coordinates.
1518
///
1619
/// 4-element structure that can be used to represent 4D grid coordinates or sets of integers.
@@ -65,13 +68,13 @@ impl Vector4i {
6568
pub const ONE: Self = Self::splat(1);
6669

6770
/// Converts the corresponding `glam` type to `Self`.
68-
fn from_glam(v: glam::IVec4) -> Self {
71+
fn from_glam(v: IVec4) -> Self {
6972
Self::new(v.x, v.y, v.z, v.w)
7073
}
7174

7275
/// Converts `self` to the corresponding `glam` type.
73-
fn to_glam(self) -> glam::IVec4 {
74-
glam::IVec4::new(self.x, self.y, self.z, self.w)
76+
fn to_glam(self) -> IVec4 {
77+
IVec4::new(self.x, self.y, self.z, self.w)
7578
}
7679
}
7780

@@ -103,3 +106,32 @@ pub enum Vector4iAxis {
103106
impl GodotFfi for Vector4iAxis {
104107
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
105108
}
109+
110+
impl GlamType for IVec4 {
111+
type Mapped = Vector4i;
112+
113+
fn to_front(&self) -> Self::Mapped {
114+
Vector4i::new(self.x, self.y, self.z, self.w)
115+
}
116+
117+
fn from_front(mapped: &Self::Mapped) -> Self {
118+
IVec4::new(mapped.x, mapped.y, mapped.z, mapped.w)
119+
}
120+
}
121+
122+
impl GlamConv for Vector4i {
123+
type Glam = IVec4;
124+
}
125+
126+
#[cfg(test)]
127+
mod test {
128+
use super::*;
129+
130+
#[test]
131+
fn coord_min_max() {
132+
let a = Vector4i::new(1, 3, 5, 0);
133+
let b = Vector4i::new(0, 5, 2, 1);
134+
assert_eq!(a.coord_min(b), Vector4i::new(0, 3, 2, 0),);
135+
assert_eq!(a.coord_max(b), Vector4i::new(1, 5, 5, 1));
136+
}
137+
}

0 commit comments

Comments
 (0)