From c86190def1a9cf70b6158d65cf24b68d9a7b887c Mon Sep 17 00:00:00 2001 From: David C <86097860+DvvCz@users.noreply.github.com> Date: Mon, 14 Aug 2023 13:43:01 -0700 Subject: [PATCH] Implement variadic versions of CFrame methods (#85) --- src/roblox/datatypes/types/cframe.rs | 43 +++++++++++++++++++--------- tests/roblox/datatypes/CFrame.luau | 3 ++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index a9b3c5e..3c6a550 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -2,7 +2,7 @@ use core::fmt; use std::ops; use glam::{EulerRot, Mat4, Quat, Vec3}; -use mlua::prelude::*; +use mlua::{prelude::*, Variadic}; use rbx_dom_weak::types::{CFrame as DomCFrame, Matrix3 as DomMatrix3, Vector3 as DomVector3}; use super::{super::*, Vector3}; @@ -210,29 +210,46 @@ impl LuaUserData for CFrame { translation, ))) }); - methods.add_method("ToWorldSpace", |_, this, rhs: LuaUserDataRef| { - Ok(*this * *rhs) - }); - methods.add_method("ToObjectSpace", |_, this, rhs: LuaUserDataRef| { - Ok(this.inverse() * *rhs) - }); + methods.add_method( + "ToWorldSpace", + |_, this, rhs: Variadic>| { + Ok(Variadic::from_iter(rhs.into_iter().map(|cf| *this * *cf))) + }, + ); + methods.add_method( + "ToObjectSpace", + |_, this, rhs: Variadic>| { + let inverse = this.inverse(); + Ok(Variadic::from_iter(rhs.into_iter().map(|cf| inverse * *cf))) + }, + ); methods.add_method( "PointToWorldSpace", - |_, this, rhs: LuaUserDataRef| Ok(*this * *rhs), + |_, this, rhs: Variadic>| { + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| *this * *v3))) + }, ); methods.add_method( "PointToObjectSpace", - |_, this, rhs: LuaUserDataRef| Ok(this.inverse() * *rhs), + |_, this, rhs: Variadic>| { + let inverse = this.inverse(); + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| inverse * *v3))) + }, ); methods.add_method( "VectorToWorldSpace", - |_, this, rhs: LuaUserDataRef| Ok((*this - Vector3(this.position())) * *rhs), + |_, this, rhs: Variadic>| { + let result = *this - Vector3(this.position()); + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3))) + }, ); methods.add_method( "VectorToObjectSpace", - |_, this, rhs: LuaUserDataRef| { - let inv = this.inverse(); - Ok((inv - Vector3(inv.position())) * *rhs) + |_, this, rhs: Variadic>| { + let inverse = this.inverse(); + let result = inverse - Vector3(inverse.position()); + + Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3))) }, ); #[rustfmt::skip] diff --git a/tests/roblox/datatypes/CFrame.luau b/tests/roblox/datatypes/CFrame.luau index 6ac32e0..85b40bb 100644 --- a/tests/roblox/datatypes/CFrame.luau +++ b/tests/roblox/datatypes/CFrame.luau @@ -103,6 +103,9 @@ local offset = CFrame.new(0, 0, -5) assert(offset:ToWorldSpace(offset).Z == offset.Z * 2) assert(offset:ToObjectSpace(offset).Z == 0) +assert(select("#", offset:ToWorldSpace(offset, offset, offset)) == 3) +assert(select("#", offset:ToObjectSpace(offset, offset, offset)) == 3) + local world = CFrame.fromOrientation(0, math.rad(90), 0) * CFrame.new(0, 0, -5) local world2 = CFrame.fromOrientation(0, -math.rad(90), 0) * CFrame.new(0, 0, -5) assertEq(CFrame.identity:ToObjectSpace(world), world)