From c7a843bc634060fb1ef8f59adb9188613cfe4922 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 17 Jun 2024 10:12:33 +0300 Subject: [PATCH] add mat4 library --- src/logic/scripting/lua/api_lua.hpp | 1 + src/logic/scripting/lua/libmat4.cpp | 49 ++++++++++++++++++++++++++ src/logic/scripting/lua/lua_engine.cpp | 1 + src/logic/scripting/lua/lua_util.hpp | 43 ++++++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 src/logic/scripting/lua/libmat4.cpp diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index 81c20644..83130ec2 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -17,6 +17,7 @@ extern const luaL_Reg inputlib []; extern const luaL_Reg inventorylib []; extern const luaL_Reg itemlib []; extern const luaL_Reg jsonlib []; +extern const luaL_Reg mat4lib []; extern const luaL_Reg packlib []; extern const luaL_Reg playerlib []; extern const luaL_Reg timelib []; diff --git a/src/logic/scripting/lua/libmat4.cpp b/src/logic/scripting/lua/libmat4.cpp new file mode 100644 index 00000000..0cc1d727 --- /dev/null +++ b/src/logic/scripting/lua/libmat4.cpp @@ -0,0 +1,49 @@ +#include "api_lua.hpp" + +#include +#include + +static int l_idt(lua::State* L) { + return lua::pushmat4(L, glm::mat4(1.0f)); +} + +static int l_scale(lua::State* L) { + uint argc = lua::gettop(L); + switch (argc) { + case 1: { + auto scale = lua::tovec3(L, 1); + return lua::pushmat4(L, glm::scale(glm::mat4(1.0f), scale)); + } + case 2: { + auto matrix = lua::tomat4(L, 1); + auto scale = lua::tovec3(L, 2); + return lua::pushmat4(L, glm::scale(matrix, scale)); + } + default: { + throw std::runtime_error("invalid number of arguments (1 or 2 expected)"); + } + } + return 0; +} + +static int l_tostring(lua::State* L) { + auto matrix = lua::tomat4(L, 1); + std::stringstream ss; + ss << "mat4 {\n"; + for (uint y = 0; y < 4; y++) { + for (uint x = 0; x < 4; x++) { + ss << "\t" << matrix[y][x]; + } + ss << "\n"; + } + ss << "}"; + return lua::pushstring(L, ss.str()); +} + +const luaL_Reg mat4lib [] = { + {"idt", lua::wrap}, + {"scale", lua::wrap}, + {"tostring", lua::wrap}, + {NULL, NULL} +}; + diff --git a/src/logic/scripting/lua/lua_engine.cpp b/src/logic/scripting/lua/lua_engine.cpp index 75ef541f..a64216a6 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -37,6 +37,7 @@ static void create_libs(lua::State* L) { openlib(L, "inventory", inventorylib); openlib(L, "item", itemlib); openlib(L, "json", jsonlib); + openlib(L, "mat4", mat4lib); openlib(L, "pack", packlib); openlib(L, "player", playerlib); openlib(L, "time", timelib); diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index af58ea11..ef681290 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -195,6 +195,17 @@ namespace lua { rawseti(L, 4); return 1; } + inline int pushmat4(lua::State* L, glm::mat4 matrix) { + createtable(L, 16, 0); + for (uint y = 0; y < 4; y++) { + for (uint x = 0; x < 4; x++) { + uint i = y * 4 + x; + pushnumber(L, matrix[y][x]); + rawseti(L, i+1); + } + } + return 1; + } inline int pushcfunction(lua::State* L, lua_CFunction func) { lua_pushcfunction(L, func); return 1; @@ -310,6 +321,38 @@ namespace lua { return glm::vec2(x, y); } + inline glm::vec3 tovec3(lua::State* L, int idx) { + pushvalue(L, idx); + if (!istable(L, idx) || objlen(L, idx) < 3) { + throw std::runtime_error("value must be an array of three numbers"); + } + rawgeti(L, 1); + auto x = tonumber(L, -1); pop(L); + rawgeti(L, 2); + auto y = tonumber(L, -1); pop(L); + rawgeti(L, 3); + auto z = tonumber(L, -1); pop(L); + pop(L); + return glm::vec3(x, y, z); + } + + inline glm::mat4 tomat4(lua::State* L, int idx) { + pushvalue(L, idx); + if (!istable(L, idx) || objlen(L, idx) < 16) { + throw std::runtime_error("value must be an array of 16 numbers"); + } + glm::mat4 matrix; + for (uint y = 0; y < 4; y++) { + for (uint x = 0; x < 4; x++) { + uint i = y * 4 + x; + rawgeti(L, i+1); + matrix[y][x] = static_cast(tonumber(L, -1)); + pop(L); + } + } + return matrix; + } + inline glm::vec4 tocolor(lua::State* L, int idx) { pushvalue(L, idx); if (!istable(L, -1) || objlen(L, idx) < 4) {