diff --git a/crates/lune-roblox/src/datatypes/types/vector2.rs b/crates/lune-roblox/src/datatypes/types/vector2.rs index 343fb706..2248530c 100644 --- a/crates/lune-roblox/src/datatypes/types/vector2.rs +++ b/crates/lune-roblox/src/datatypes/types/vector2.rs @@ -52,6 +52,9 @@ impl LuaUserData for Vector2 { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { // Methods + methods.add_method("Angle", |_, this, rhs: LuaUserDataRef| { + Ok(this.0.angle_between(rhs.0)) + }); methods.add_method("Cross", |_, this, rhs: LuaUserDataRef| { let this_v3 = Vec3::new(this.0.x, this.0.y, 0f32); let rhs_v3 = Vec3::new(rhs.0.x, rhs.0.y, 0f32); @@ -60,6 +63,14 @@ impl LuaUserData for Vector2 { methods.add_method("Dot", |_, this, rhs: LuaUserDataRef| { Ok(this.0.dot(rhs.0)) }); + methods.add_method( + "FuzzyEq", + |_, this, (rhs, epsilon): (LuaUserDataRef, f32)| { + let eq_x = (rhs.0.x - this.0.x).abs() <= epsilon; + let eq_y = (rhs.0.y - this.0.y).abs() <= epsilon; + Ok(eq_x && eq_y) + }, + ); methods.add_method( "Lerp", |_, this, (rhs, alpha): (LuaUserDataRef, f32)| { @@ -72,6 +83,10 @@ impl LuaUserData for Vector2 { methods.add_method("Min", |_, this, rhs: LuaUserDataRef| { Ok(Vector2(this.0.min(rhs.0))) }); + methods.add_method("Abs", |_, this, ()| Ok(Vector2(this.0.abs()))); + methods.add_method("Ceil", |_, this, ()| Ok(Vector2(this.0.ceil()))); + methods.add_method("Floor", |_, this, ()| Ok(Vector2(this.0.floor()))); + methods.add_method("Sign", |_, this, ()| Ok(Vector2(this.0.signum()))); // Metamethods methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); diff --git a/crates/lune-roblox/src/datatypes/types/vector3.rs b/crates/lune-roblox/src/datatypes/types/vector3.rs index 11bcd4a4..c976c543 100644 --- a/crates/lune-roblox/src/datatypes/types/vector3.rs +++ b/crates/lune-roblox/src/datatypes/types/vector3.rs @@ -133,6 +133,10 @@ impl LuaUserData for Vector3 { methods.add_method("Min", |_, this, rhs: LuaUserDataRef| { Ok(Vector3(this.0.min(rhs.0))) }); + methods.add_method("Abs", |_, this, ()| Ok(Vector3(this.0.abs()))); + methods.add_method("Ceil", |_, this, ()| Ok(Vector3(this.0.ceil()))); + methods.add_method("Floor", |_, this, ()| Ok(Vector3(this.0.floor()))); + methods.add_method("Sign", |_, this, ()| Ok(Vector3(this.0.signum()))); // Metamethods methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq); methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string); diff --git a/tests/roblox/datatypes/Vector2.luau b/tests/roblox/datatypes/Vector2.luau index 1ed391ee..523ba942 100644 --- a/tests/roblox/datatypes/Vector2.luau +++ b/tests/roblox/datatypes/Vector2.luau @@ -42,4 +42,14 @@ assert(Vector2.new(2, 4) / 2 == Vector2.new(1, 2)) assert(Vector2.new(7, 15) // Vector2.new(3, 7) == Vector2.new(2, 2)) assert(Vector2.new(3, 7) // 2 == Vector2.new(1, 3)) --- TODO: Vector math +-- Vector math methods +assert(Vector2.new(-1, -2):Abs() == Vector2.new(1, 2)) +assert(Vector2.new(-1.7, 2):Sign() == Vector2.new(-1, 1)) +assert(Vector2.new(-1.9, 2.1):Ceil() == Vector2.new(-1, 3)) +assert(Vector2.new(-1.1, 2.99):Floor() == Vector2.new(-2, 2)) + +assert(Vector2.new(1, 2):FuzzyEq(Vector2.new(1 - 1e-6, 2 + 1e-6), 1e-5)) +assert(not Vector2.new(1, 2):FuzzyEq(Vector2.new(1.2, 2), 0.1)) + +local angle = Vector2.new(1, 1):Angle(Vector2.new(-1, 1)) +assert(math.abs(angle - (math.pi / 2)) < 1e-5) diff --git a/tests/roblox/datatypes/Vector3.luau b/tests/roblox/datatypes/Vector3.luau index 4a4b7453..723e3abf 100644 --- a/tests/roblox/datatypes/Vector3.luau +++ b/tests/roblox/datatypes/Vector3.luau @@ -45,4 +45,10 @@ assert(Vector3.new(2, 4, 8) / 2 == Vector3.new(1, 2, 4)) assert(Vector3.new(7, 11, 15) // Vector3.new(3, 5, 7) == Vector3.new(2, 2, 2)) assert(Vector3.new(3, 5, 7) // 2 == Vector3.new(1, 2, 3)) --- TODO: Vector math +-- Vector math methods +assert(Vector3.new(-1, -2, -3):Abs() == Vector3.new(1, 2, 3)) +assert(Vector3.new(-1.7, 2, -3):Sign() == Vector3.new(-1, 1, -1)) +assert(Vector3.new(-1.9, 2.1, 3.5):Ceil() == Vector3.new(-1, 3, 4)) +assert(Vector3.new(-1.1, 2.99, 3.5):Floor() == Vector3.new(-2, 2, 3)) + +assert(Vector3.new(1, 2, 3):FuzzyEq(Vector3.new(1 - 1e-6, 2 + 1e-6, 3 + 1e-6), 1e-5))