From 9d8463734e7f41ffbb0ffe91fe72833321280791 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sat, 16 Sep 2023 23:59:29 -0700 Subject: [PATCH 01/12] Add From for DomCFrame and From for CFrame tests --- src/roblox/datatypes/types/cframe.rs | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 18018ffc..ac2b5fec 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -414,3 +414,53 @@ fn look_at(from: Vec3, to: Vec3, up: Vec3) -> Mat4 { from.extend(1.0), ) } + +#[cfg(test)] +mod cframe_test { + use glam::{Mat4, Vec3}; + use rbx_dom_weak::types::{CFrame as DomCFrame, Matrix3 as DomMatrix3, Vector3 as DomVector3}; + + use super::CFrame; + + #[test] + fn dom_cframe_from_cframe() { + let dom_cframe = DomCFrame::new( + DomVector3::new(1.0, 2.0, 3.0), + DomMatrix3::new( + DomVector3::new(1.0, 2.0, 3.0), + DomVector3::new(1.0, 2.0, 3.0), + DomVector3::new(1.0, 2.0, 3.0), + ), + ); + + let cframe = CFrame(Mat4::from_cols( + Vec3::new(1.0, 2.0, 3.0).extend(0.0), + Vec3::new(1.0, 2.0, 3.0).extend(0.0), + Vec3::new(1.0, 2.0, 3.0).extend(0.0), + Vec3::new(1.0, 2.0, 3.0).extend(1.0), + )); + + assert_eq!(CFrame::from(dom_cframe), cframe) + } + + #[test] + fn cframe_from_dom_cframe() { + let cframe = CFrame(Mat4::from_cols( + Vec3::new(1.0, 2.0, 3.0).extend(0.0), + Vec3::new(1.0, 2.0, 3.0).extend(0.0), + Vec3::new(1.0, 2.0, 3.0).extend(0.0), + Vec3::new(1.0, 2.0, 3.0).extend(1.0), + )); + + let dom_cframe = DomCFrame::new( + DomVector3::new(1.0, 2.0, 3.0), + DomMatrix3::new( + DomVector3::new(1.0, 2.0, 3.0), + DomVector3::new(1.0, 2.0, 3.0), + DomVector3::new(1.0, 2.0, 3.0), + ), + ); + + assert_eq!(DomCFrame::from(cframe), dom_cframe) + } +} From 6d3487db6821c4c2618ac87809dd0eee50853e61 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:01:45 -0700 Subject: [PATCH 02/12] Return Mat3 from CFrame::orientation --- src/roblox/datatypes/types/cframe.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index ac2b5fec..5f590952 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -1,7 +1,7 @@ use core::fmt; use std::ops; -use glam::{EulerRot, Mat4, Quat, Vec3}; +use glam::{EulerRot, Mat3, Mat4, Quat, Vec3}; use mlua::{prelude::*, Variadic}; use rbx_dom_weak::types::{CFrame as DomCFrame, Matrix3 as DomMatrix3, Vector3 as DomVector3}; @@ -26,8 +26,8 @@ impl CFrame { self.0.w_axis.truncate() } - fn orientation(&self) -> (Vec3, Vec3, Vec3) { - ( + fn orientation(&self) -> Mat3 { + Mat3::from_cols( self.0.x_axis.truncate(), self.0.y_axis.truncate(), self.0.z_axis.truncate(), From 88fe76b4c717f58a50f88fba6228a59923379b9c Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:03:40 -0700 Subject: [PATCH 03/12] Transpose orientation before returning from GetComponents --- src/roblox/datatypes/types/cframe.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 5f590952..9c5f4539 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -264,12 +264,12 @@ impl LuaUserData for CFrame { #[rustfmt::skip] methods.add_method("GetComponents", |_, this, ()| { let pos = this.position(); - let (rx, ry, rz) = this.orientation(); + let transposed = this.orientation().transpose(); Ok(( - pos.x, pos.y, -pos.z, - rx.x, rx.y, rx.z, - ry.x, ry.y, ry.z, - rz.x, rz.y, rz.z, + pos.x, pos.y, pos.z, + transposed.x_axis.x, transposed.x_axis.y, transposed.x_axis.z, + transposed.y_axis.x, transposed.y_axis.y, transposed.y_axis.z, + transposed.z_axis.x, transposed.z_axis.y, transposed.z_axis.z, )) }); methods.add_method("ToEulerAnglesXYZ", |_, this, ()| { From ea1fa1648b4233b6e511348e1b5e7f20baef73c0 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:04:00 -0700 Subject: [PATCH 04/12] Transpose before returning XVector, YVector, and ZVector --- src/roblox/datatypes/types/cframe.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 9c5f4539..7c454a4c 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -183,12 +183,22 @@ impl LuaUserData for CFrame { fields.add_field_method_get("X", |_, this| Ok(this.position().x)); fields.add_field_method_get("Y", |_, this| Ok(this.position().y)); fields.add_field_method_get("Z", |_, this| Ok(this.position().z)); - fields.add_field_method_get("XVector", |_, this| Ok(Vector3(this.orientation().0))); - fields.add_field_method_get("YVector", |_, this| Ok(Vector3(this.orientation().1))); - fields.add_field_method_get("ZVector", |_, this| Ok(Vector3(this.orientation().2))); - fields.add_field_method_get("RightVector", |_, this| Ok(Vector3(this.orientation().0))); - fields.add_field_method_get("UpVector", |_, this| Ok(Vector3(this.orientation().1))); - fields.add_field_method_get("LookVector", |_, this| Ok(Vector3(-this.orientation().2))); + fields.add_field_method_get("XVector", |_, this| { + Ok(Vector3(this.orientation().transpose().x_axis)) + }); + fields.add_field_method_get("YVector", |_, this| { + Ok(Vector3(this.orientation().transpose().y_axis)) + }); + fields.add_field_method_get("ZVector", |_, this| { + Ok(Vector3(this.orientation().transpose().z_axis)) + }); + fields.add_field_method_get("RightVector", |_, this| { + Ok(Vector3(this.orientation().x_axis)) + }); + fields.add_field_method_get("UpVector", |_, this| Ok(Vector3(this.orientation().y_axis))); + fields.add_field_method_get("LookVector", |_, this| { + Ok(Vector3(-this.orientation().z_axis)) + }); } fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { From ec0b54794d9ecfbeace1152837e89ecebd3c2c7f Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:04:33 -0700 Subject: [PATCH 05/12] Use Mat3 in From for DomCFrame --- src/roblox/datatypes/types/cframe.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 7c454a4c..56341c57 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -394,13 +394,13 @@ impl From for CFrame { impl From for DomCFrame { fn from(v: CFrame) -> Self { - let (rx, ry, rz) = v.orientation(); + let orientation = v.orientation(); DomCFrame { position: DomVector3::from(Vector3(v.position())), orientation: DomMatrix3::new( - DomVector3::from(Vector3(rx)), - DomVector3::from(Vector3(ry)), - DomVector3::from(Vector3(rz)), + DomVector3::from(Vector3(orientation.x_axis)), + DomVector3::from(Vector3(orientation.y_axis)), + DomVector3::from(Vector3(orientation.z_axis)), ), } } From a4f7dcd8227bb59d0fe715fa5342cb749480c6b5 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:04:50 -0700 Subject: [PATCH 06/12] Transpose before outputting from Display --- src/roblox/datatypes/types/cframe.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 56341c57..2884df1a 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -331,14 +331,14 @@ impl LuaUserData for CFrame { impl fmt::Display for CFrame { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let pos = self.position(); - let (rx, ry, rz) = self.orientation(); + let transposed = self.orientation().transpose(); write!( f, "{}, {}, {}, {}", Vector3(pos), - Vector3(rx), - Vector3(ry), - Vector3(rz) + Vector3(transposed.x_axis), + Vector3(transposed.y_axis), + Vector3(transposed.z_axis) ) } } From f22adafeb5752d0f2d10f532d9ed5f8baf7562d1 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:05:10 -0700 Subject: [PATCH 07/12] Add 12-arg CFrame constructor test --- tests/roblox/datatypes/CFrame.luau | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/roblox/datatypes/CFrame.luau b/tests/roblox/datatypes/CFrame.luau index 85b40bbb..b4ed10bd 100644 --- a/tests/roblox/datatypes/CFrame.luau +++ b/tests/roblox/datatypes/CFrame.luau @@ -72,6 +72,8 @@ assertEq( CFrame.new(1, 2, 3) ) +assertEq(CFrame.new(1, 2, 3, 1, 0, 0, 0, 1, 0, 0, 0, 1), CFrame.new(1, 2, 3)) + -- Constants assertEq(CFrame.identity, CFrame.new()) From a2bc0579959b189475feff3f3d5a72dfdb5f0b1a Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:10:46 -0700 Subject: [PATCH 08/12] Pass columns to from_cols_array_2d in 12-arg CFrame constructor --- src/roblox/datatypes/types/cframe.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 2884df1a..83bf1752 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -140,9 +140,9 @@ impl LuaExportsTable<'_> for CFrame { 12 => match ArgsMatrix::from_lua_multi(args, lua) { Ok((x, y, z, r00, r01, r02, r10, r11, r12, r20, r21, r22)) => { Ok(CFrame(Mat4::from_cols_array_2d(&[ - [r00, r01, r02, 0.0], - [r10, r11, r12, 0.0], - [r20, r21, r22, 0.0], + [r00, r10, r20, 0.0], + [r01, r11, r21, 0.0], + [r02, r12, r22, 0.0], [x, y, z, 1.0], ]))) } From 09cbd97bce8bcd4a54b9f33add48ee354b026c58 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 00:16:06 -0700 Subject: [PATCH 09/12] Add CFrame:Angles test --- tests/roblox/datatypes/CFrame.luau | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/roblox/datatypes/CFrame.luau b/tests/roblox/datatypes/CFrame.luau index b4ed10bd..ba4979ca 100644 --- a/tests/roblox/datatypes/CFrame.luau +++ b/tests/roblox/datatypes/CFrame.luau @@ -125,6 +125,18 @@ assertEq( CFrame.lookAt(Vector3.new(0, 0, -5), Vector3.new(0, 0, -5) - Vector3.xAxis) ) +-- Angles + +assertEq( + CFrame.Angles(math.pi/2, math.pi/4, math.pi/4), + CFrame.new( + 0, 0, 0, + 0.49999997, -0.49999997, 0.707106769, + 0.49999994, -0.5, -0.707106769, + 0.707106769, 0.707106769, 0 + ) +) + -- TODO: More methods -- CFrames on instances From 14bea3438ce02f32b57e679ed43ad2890ce07739 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 01:29:09 -0700 Subject: [PATCH 10/12] Use x_axis, y_axis, and z_axis for XVector, YVector, and ZVector Turns out the Roblox docs are just totally wrong here --- src/roblox/datatypes/types/cframe.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 83bf1752..0172a822 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -183,15 +183,9 @@ impl LuaUserData for CFrame { fields.add_field_method_get("X", |_, this| Ok(this.position().x)); fields.add_field_method_get("Y", |_, this| Ok(this.position().y)); fields.add_field_method_get("Z", |_, this| Ok(this.position().z)); - fields.add_field_method_get("XVector", |_, this| { - Ok(Vector3(this.orientation().transpose().x_axis)) - }); - fields.add_field_method_get("YVector", |_, this| { - Ok(Vector3(this.orientation().transpose().y_axis)) - }); - fields.add_field_method_get("ZVector", |_, this| { - Ok(Vector3(this.orientation().transpose().z_axis)) - }); + fields.add_field_method_get("XVector", |_, this| Ok(Vector3(this.orientation().x_axis))); + fields.add_field_method_get("YVector", |_, this| Ok(Vector3(this.orientation().y_axis))); + fields.add_field_method_get("ZVector", |_, this| Ok(Vector3(this.orientation().z_axis))); fields.add_field_method_get("RightVector", |_, this| { Ok(Vector3(this.orientation().x_axis)) }); From a7a66c149980259d0268174d3ec9d96576ffe78c Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 14:01:39 -0700 Subject: [PATCH 11/12] Transpose orientation in DomCFrame<->CFrame conversions --- src/roblox/datatypes/types/cframe.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index 0172a822..a6dd571b 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -377,10 +377,11 @@ impl ops::Sub for CFrame { impl From for CFrame { fn from(v: DomCFrame) -> Self { + let transposed = v.orientation.transpose(); CFrame(Mat4::from_cols( - Vector3::from(v.orientation.x).0.extend(0.0), - Vector3::from(v.orientation.y).0.extend(0.0), - Vector3::from(v.orientation.z).0.extend(0.0), + Vector3::from(transposed.x).0.extend(0.0), + Vector3::from(transposed.y).0.extend(0.0), + Vector3::from(transposed.z).0.extend(0.0), Vector3::from(v.position).0.extend(1.0), )) } @@ -388,13 +389,13 @@ impl From for CFrame { impl From for DomCFrame { fn from(v: CFrame) -> Self { - let orientation = v.orientation(); + let transposed = v.orientation().transpose(); DomCFrame { position: DomVector3::from(Vector3(v.position())), orientation: DomMatrix3::new( - DomVector3::from(Vector3(orientation.x_axis)), - DomVector3::from(Vector3(orientation.y_axis)), - DomVector3::from(Vector3(orientation.z_axis)), + DomVector3::from(Vector3(transposed.x_axis)), + DomVector3::from(Vector3(transposed.y_axis)), + DomVector3::from(Vector3(transposed.z_axis)), ), } } @@ -438,9 +439,9 @@ mod cframe_test { ); let cframe = CFrame(Mat4::from_cols( - Vec3::new(1.0, 2.0, 3.0).extend(0.0), - Vec3::new(1.0, 2.0, 3.0).extend(0.0), - Vec3::new(1.0, 2.0, 3.0).extend(0.0), + Vec3::new(1.0, 1.0, 1.0).extend(0.0), + Vec3::new(2.0, 2.0, 2.0).extend(0.0), + Vec3::new(3.0, 3.0, 3.0).extend(0.0), Vec3::new(1.0, 2.0, 3.0).extend(1.0), )); @@ -459,9 +460,9 @@ mod cframe_test { let dom_cframe = DomCFrame::new( DomVector3::new(1.0, 2.0, 3.0), DomMatrix3::new( - DomVector3::new(1.0, 2.0, 3.0), - DomVector3::new(1.0, 2.0, 3.0), - DomVector3::new(1.0, 2.0, 3.0), + DomVector3::new(1.0, 1.0, 1.0), + DomVector3::new(2.0, 2.0, 2.0), + DomVector3::new(3.0, 3.0, 3.0), ), ); From a5bf283b1fc9929c0bf5766687b546606bd14197 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 17 Sep 2023 15:25:50 -0700 Subject: [PATCH 12/12] Align positional components with rotation --- src/roblox/datatypes/types/cframe.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/roblox/datatypes/types/cframe.rs b/src/roblox/datatypes/types/cframe.rs index a6dd571b..4d7cbdf6 100644 --- a/src/roblox/datatypes/types/cframe.rs +++ b/src/roblox/datatypes/types/cframe.rs @@ -270,10 +270,10 @@ impl LuaUserData for CFrame { let pos = this.position(); let transposed = this.orientation().transpose(); Ok(( - pos.x, pos.y, pos.z, - transposed.x_axis.x, transposed.x_axis.y, transposed.x_axis.z, - transposed.y_axis.x, transposed.y_axis.y, transposed.y_axis.z, - transposed.z_axis.x, transposed.z_axis.y, transposed.z_axis.z, + pos.x, pos.y, pos.z, + transposed.x_axis.x, transposed.x_axis.y, transposed.x_axis.z, + transposed.y_axis.x, transposed.y_axis.y, transposed.y_axis.z, + transposed.z_axis.x, transposed.z_axis.y, transposed.z_axis.z, )) }); methods.add_method("ToEulerAnglesXYZ", |_, this, ()| {