Skip to content

Commit

Permalink
godot-core: builtin: vector: provide component-wise min/max under una…
Browse files Browse the repository at this point in the history
…mbiguous name
  • Loading branch information
yannick-was-taken committed Apr 10, 2023
1 parent 2c071ae commit 38e8f9b
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 36 deletions.
6 changes: 4 additions & 2 deletions godot-core/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ mod real_mod {
/// A 4-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
pub type RVec4 = glam::Vec4;

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

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

pub(crate) use glam::{IVec2, IVec3, IVec4};

/// A macro to coerce float-literals into the real type. Mainly used where
/// you'd normally use a suffix to specity the type, such as `115.0f32`.
///
Expand Down
4 changes: 2 additions & 2 deletions godot-core/src/builtin/transform2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ impl Mul<Rect2> for Transform2D {
let ya = self.b * rhs.position.y;
let yb = self.b * rhs.end().y;

let position = Vector2::min(xa, xb) + Vector2::min(ya, yb) + self.origin;
let end = Vector2::max(xa, xb) + Vector2::max(ya, yb) + self.origin;
let position = Vector2::coord_min(xa, xb) + Vector2::coord_min(ya, yb) + self.origin;
let end = Vector2::coord_max(xa, xb) + Vector2::coord_max(ya, yb) + self.origin;
Rect2::new(position, end - position)
}
}
Expand Down
11 changes: 8 additions & 3 deletions godot-core/src/builtin/transform3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,14 @@ impl Mul<Aabb> for Transform3D {
let za = self.basis.col_c() * rhs.position.z;
let zb = self.basis.col_c() * rhs.end().z;

let position =
Vector3::min(xa, xb) + Vector3::min(ya, yb) + Vector3::min(za, zb) + self.origin;
let end = Vector3::max(xa, xb) + Vector3::max(ya, yb) + Vector3::max(za, zb) + self.origin;
let position = Vector3::coord_min(xa, xb)
+ Vector3::coord_min(ya, yb)
+ Vector3::coord_min(za, zb)
+ self.origin;
let end = Vector3::coord_max(xa, xb)
+ Vector3::coord_max(ya, yb)
+ Vector3::coord_max(za, zb)
+ self.origin;
Aabb::new(position, end - position)
}
}
Expand Down
23 changes: 23 additions & 0 deletions godot-core/src/builtin/vector2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,26 @@ impl GlamType for RVec2 {
impl GlamConv for Vector2 {
type Glam = RVec2;
}

#[cfg(test)]
mod test {
use crate::assert_eq_approx;

use super::*;

#[test]
fn coord_min_max() {
let a = Vector2::new(1.2, 3.4);
let b = Vector2::new(0.1, 5.6);
assert_eq_approx!(
a.coord_min(b),
Vector2::new(0.1, 3.4),
Vector2::is_equal_approx
);
assert_eq_approx!(
a.coord_max(b),
Vector2::new(1.2, 5.6),
Vector2::is_equal_approx
);
}
}
36 changes: 34 additions & 2 deletions godot-core/src/builtin/vector2i.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use sys::{ffi_methods, GodotFfi};

use crate::builtin::Vector2;

use super::glam_helpers::{GlamConv, GlamType};
use super::IVec2;

/// Vector used for 2D math using integer coordinates.
///
/// 2-element structure that can be used to represent positions in 2D space or any other pair of
Expand Down Expand Up @@ -67,13 +70,13 @@ impl Vector2i {
}

/// Converts the corresponding `glam` type to `Self`.
fn from_glam(v: glam::IVec2) -> Self {
fn from_glam(v: IVec2) -> Self {
Self::new(v.x, v.y)
}

/// Converts `self` to the corresponding `glam` type.
fn to_glam(self) -> glam::IVec2 {
glam::IVec2::new(self.x, self.y)
IVec2::new(self.x, self.y)
}
}

Expand Down Expand Up @@ -105,3 +108,32 @@ pub enum Vector2iAxis {
impl GodotFfi for Vector2iAxis {
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
}

impl GlamType for IVec2 {
type Mapped = Vector2i;

fn to_front(&self) -> Self::Mapped {
Vector2i::new(self.x, self.y)
}

fn from_front(mapped: &Self::Mapped) -> Self {
IVec2::new(mapped.x, mapped.y)
}
}

impl GlamConv for Vector2i {
type Glam = IVec2;
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn coord_min_max() {
let a = Vector2i::new(1, 3);
let b = Vector2i::new(0, 5);
assert_eq!(a.coord_min(b), Vector2i::new(0, 3));
assert_eq!(a.coord_max(b), Vector2i::new(1, 5));
}
}
31 changes: 22 additions & 9 deletions godot-core/src/builtin/vector3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,13 +381,10 @@ impl GlamConv for Vector3 {

#[cfg(test)]
mod test {
use crate::assert_eq_approx;

use super::*;
use godot::builtin::real_consts::TAU;
use godot::private::class_macros::assert_eq_approx;

fn vec3_equal_approx(a: Vector3, b: Vector3) -> bool {
a.is_equal_approx(b)
}

// Translated from Godot
#[test]
Expand All @@ -397,22 +394,38 @@ mod test {
assert_eq_approx!(
vector.rotated(Vector3::new(0.0, 1.0, 0.0), TAU),
vector,
vec3_equal_approx
Vector3::is_equal_approx
);
assert_eq_approx!(
vector.rotated(Vector3::new(0.0, 1.0, 0.0), TAU / 4.0),
Vector3::new(5.6, 3.4, -1.2),
vec3_equal_approx
Vector3::is_equal_approx
);
assert_eq_approx!(
vector.rotated(Vector3::new(1.0, 0.0, 0.0), TAU / 3.0),
Vector3::new(1.2, -6.54974226119285642, 0.1444863728670914),
vec3_equal_approx
Vector3::is_equal_approx
);
assert_eq_approx!(
vector.rotated(Vector3::new(0.0, 0.0, 1.0), TAU / 2.0),
vector.rotated(Vector3::new(0.0, 0.0, 1.0), TAU / -2.0),
vec3_equal_approx
Vector3::is_equal_approx
);
}

#[test]
fn coord_min_max() {
let a = Vector3::new(1.2, 3.4, 5.6);
let b = Vector3::new(0.1, 5.6, 2.3);
assert_eq_approx!(
a.coord_min(b),
Vector3::new(0.1, 3.4, 2.3),
Vector3::is_equal_approx
);
assert_eq_approx!(
a.coord_max(b),
Vector3::new(1.2, 5.6, 5.6),
Vector3::is_equal_approx
);
}
}
38 changes: 35 additions & 3 deletions godot-core/src/builtin/vector3i.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use sys::{ffi_methods, GodotFfi};

use crate::builtin::Vector3;

use super::glam_helpers::{GlamConv, GlamType};
use super::IVec3;

/// Vector used for 3D math using integer coordinates.
///
/// 3-element structure that can be used to represent positions in 3D space or any other triple of
Expand Down Expand Up @@ -76,13 +79,13 @@ impl Vector3i {
}

/// Converts the corresponding `glam` type to `Self`.
fn from_glam(v: glam::IVec3) -> Self {
fn from_glam(v: IVec3) -> Self {
Self::new(v.x, v.y, v.z)
}

/// Converts `self` to the corresponding `glam` type.
fn to_glam(self) -> glam::IVec3 {
glam::IVec3::new(self.x, self.y, self.z)
fn to_glam(self) -> IVec3 {
IVec3::new(self.x, self.y, self.z)
}
}

Expand Down Expand Up @@ -116,3 +119,32 @@ pub enum Vector3iAxis {
impl GodotFfi for Vector3iAxis {
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
}

impl GlamType for IVec3 {
type Mapped = Vector3i;

fn to_front(&self) -> Self::Mapped {
Vector3i::new(self.x, self.y, self.z)
}

fn from_front(mapped: &Self::Mapped) -> Self {
IVec3::new(mapped.x, mapped.y, mapped.z)
}
}

impl GlamConv for Vector3i {
type Glam = IVec3;
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn coord_min_max() {
let a = Vector3i::new(1, 3, 5);
let b = Vector3i::new(0, 5, 2);
assert_eq!(a.coord_min(b), Vector3i::new(0, 3, 2));
assert_eq!(a.coord_max(b), Vector3i::new(1, 5, 5));
}
}
31 changes: 31 additions & 0 deletions godot-core/src/builtin/vector4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::fmt;
use godot_ffi as sys;
use sys::{ffi_methods, GodotFfi};

use crate::builtin::math::*;
use crate::builtin::Vector4i;

use super::glam_helpers::{GlamConv, GlamType};
Expand Down Expand Up @@ -80,6 +81,13 @@ impl Vector4 {
fn to_glam(self) -> RVec4 {
RVec4::new(self.x, self.y, self.z, self.w)
}

pub fn is_equal_approx(self, to: Self) -> bool {
is_equal_approx(self.x, to.x)
&& is_equal_approx(self.y, to.y)
&& is_equal_approx(self.z, to.z)
&& is_equal_approx(self.w, to.w)
}
}

/// Formats the vector like Godot: `(x, y, z, w)`.
Expand Down Expand Up @@ -126,3 +134,26 @@ impl GlamType for RVec4 {
impl GlamConv for Vector4 {
type Glam = RVec4;
}

#[cfg(test)]
mod test {
use crate::assert_eq_approx;

use super::*;

#[test]
fn coord_min_max() {
let a = Vector4::new(1.2, 3.4, 5.6, 0.1);
let b = Vector4::new(0.1, 5.6, 2.3, 1.2);
assert_eq_approx!(
a.coord_min(b),
Vector4::new(0.1, 3.4, 2.3, 0.1),
Vector4::is_equal_approx
);
assert_eq_approx!(
a.coord_max(b),
Vector4::new(1.2, 5.6, 5.6, 1.2),
Vector4::is_equal_approx
);
}
}
38 changes: 35 additions & 3 deletions godot-core/src/builtin/vector4i.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use sys::{ffi_methods, GodotFfi};

use crate::builtin::Vector4;

use super::glam_helpers::{GlamConv, GlamType};
use super::IVec4;

/// Vector used for 4D math using integer coordinates.
///
/// 4-element structure that can be used to represent 4D grid coordinates or sets of integers.
Expand Down Expand Up @@ -65,13 +68,13 @@ impl Vector4i {
pub const ONE: Self = Self::splat(1);

/// Converts the corresponding `glam` type to `Self`.
fn from_glam(v: glam::IVec4) -> Self {
fn from_glam(v: IVec4) -> Self {
Self::new(v.x, v.y, v.z, v.w)
}

/// Converts `self` to the corresponding `glam` type.
fn to_glam(self) -> glam::IVec4 {
glam::IVec4::new(self.x, self.y, self.z, self.w)
fn to_glam(self) -> IVec4 {
IVec4::new(self.x, self.y, self.z, self.w)
}
}

Expand Down Expand Up @@ -103,3 +106,32 @@ pub enum Vector4iAxis {
impl GodotFfi for Vector4iAxis {
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
}

impl GlamType for IVec4 {
type Mapped = Vector4i;

fn to_front(&self) -> Self::Mapped {
Vector4i::new(self.x, self.y, self.z, self.w)
}

fn from_front(mapped: &Self::Mapped) -> Self {
IVec4::new(mapped.x, mapped.y, mapped.z, mapped.w)
}
}

impl GlamConv for Vector4i {
type Glam = IVec4;
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn coord_min_max() {
let a = Vector4i::new(1, 3, 5, 0);
let b = Vector4i::new(0, 5, 2, 1);
assert_eq!(a.coord_min(b), Vector4i::new(0, 3, 2, 0),);
assert_eq!(a.coord_max(b), Vector4i::new(1, 5, 5, 1));
}
}
Loading

0 comments on commit 38e8f9b

Please sign in to comment.