@@ -11,13 +11,19 @@ const c = @cImport({
1111
1212const config = @import ("config" );
1313pub const lang = config .lang ;
14+ /// True if Luau built for 4-vectors
15+ pub const luau_vector_size = config .luau_vector_size ;
1416
1517/// This function is defined in luau.cpp and must be called to define the assertion printer
1618extern "c" fn zig_registerAssertionHandler () void ;
1719
1820/// This function is defined in luau.cpp and ensures Zig uses the correct free when compiling luau code
1921extern "c" fn zig_luau_free (ptr : * anyopaque ) void ;
2022
23+ // Workaround for Zig apparently always choosing the 3-vector variant of lua_pushvector(lua_State* L, float x, float y, float z)
24+ // despite compiling Luau with -DLUA_VECTOR_SIZE=4.
25+ extern "c" fn zig_lua_pushvector4 (L : ? * LuaState , x : f32 , y : f32 , z : f32 , w : f32 ) void ;
26+
2127const Allocator = std .mem .Allocator ;
2228
2329// Types
@@ -139,6 +145,7 @@ pub const LuaType = enum(i5) {
139145 boolean = c .LUA_TBOOLEAN ,
140146 light_userdata = c .LUA_TLIGHTUSERDATA ,
141147 number = c .LUA_TNUMBER ,
148+ vector = c .LUA_TVECTOR ,
142149 string = c .LUA_TSTRING ,
143150 table = c .LUA_TTABLE ,
144151 function = c .LUA_TFUNCTION ,
@@ -520,6 +527,11 @@ pub const Lua = struct {
520527 return c .lua_isuserdata (lua .state , index ) != 0 ;
521528 }
522529
530+ /// Returns true if the value at the given index is a vector
531+ pub fn isVector (lua : * Lua , index : i32 ) bool {
532+ return c .lua_isvector (lua .state , index );
533+ }
534+
523535 /// Returns true if the value at index1 is smaller than the value at index2, following the
524536 /// semantics of the Lua < operator.
525537 /// See https://www.lua.org/manual/5.4/manual.html#lua_lessthan
@@ -713,6 +725,17 @@ pub const Lua = struct {
713725 c .lua_pushvalue (lua .state , index );
714726 }
715727
728+ fn pushVector3 (lua : * Lua , x : f32 , y : f32 , z : f32 ) void {
729+ c .lua_pushvector (lua .state , x , y , z );
730+ }
731+
732+ fn pushVector4 (lua : * Lua , x : f32 , y : f32 , z : f32 , w : f32 ) void {
733+ zig_lua_pushvector4 (lua .state , x , y , z , w );
734+ }
735+
736+ /// Pushes a floating point 3-vector (or 4-vector if configured) `v` onto the stack
737+ pub const pushVector = if (luau_vector_size == 3 ) pushVector3 else pushVector4 ;
738+
716739 /// Returns true if the two values in indices `index1` and `index2` are primitively equal
717740 /// Bypasses __eq metamethods
718741 /// Returns false if not equal, or if any index is invalid
@@ -927,6 +950,22 @@ pub const Lua = struct {
927950 return error .Fail ;
928951 }
929952
953+ /// Converts the Lua value at the given `index` to a 3- or 4-vector.
954+ /// The Lua value must be a vector.
955+ pub fn toVector (lua : * Lua , index : i32 ) ! [luau_vector_size ]f32 {
956+ const res = c .lua_tovector (lua .state , index );
957+ if (res ) | r | {
958+ if (luau_vector_size == 3 ) {
959+ return [_ ]f32 { r [0 ], r [1 ], r [2 ] };
960+ } else if (luau_vector_size == 4 ) {
961+ return [_ ]f32 { r [0 ], r [1 ], r [2 ], r [3 ] };
962+ } else {
963+ @compileError ("luau_vector_size must be 3 or 4" );
964+ }
965+ }
966+ return error .Fail ;
967+ }
968+
930969 /// Returns the `LuaType` of the value at the given index
931970 /// Note that this is equivalent to lua_type but because type is a Zig primitive it is renamed to `typeOf`
932971 /// See https://www.lua.org/manual/5.1/manual.html#lua_type
0 commit comments