#include "api_lua.hpp" #include #include template class Operation> static int l_binop(lua::State* L) { uint argc = lua::gettop(L); if (argc != 2 && argc != 3) { throw std::runtime_error("invalid arguments number (2 or 3 expected)"); } const auto& a = lua::tovec(L, 1); if (lua::isnumber(L, 2)) { // scalar second operand overload const auto& b = lua::tonumber(L, 2); Operation op; if (argc == 2) { lua::createtable(L, n, 0); for (uint i = 0; i < n; i++) { lua::pushnumber(L, op(a[i], b)); lua::rawseti(L, i+1); } return 1; } else { return lua::setvec(L, 3, op(a, glm::vec(b))); } } else { const auto& b = lua::tovec(L, 2); Operation op; if (argc == 2) { lua::createtable(L, n, 0); for (uint i = 0; i < n; i++) { lua::pushnumber(L, op(a[i], b[i])); lua::rawseti(L, i+1); } return 1; } else { return lua::setvec(L, 3, op(a, b)); } } } template(*func)(const glm::vec&)> static int l_unaryop(lua::State* L) { uint argc = lua::gettop(L); const auto& vec = func(lua::tovec(L, 1)); switch (argc) { case 1: lua::createtable(L, n, 0); for (uint i = 0; i < n; i++) { lua::pushnumber(L, vec[i]); lua::rawseti(L, i+1); } return 1; case 2: return lua::setvec(L, 2, vec); default: { throw std::runtime_error("invalid arguments number (1 or 2 expected)"); } } } template&)> static int l_scalar_op(lua::State* L) { if (lua::gettop(L) != 1) { throw std::runtime_error("invalid arguments number (1 expected)"); } return lua::pushnumber(L, func(lua::tovec(L, 1)/*vector a*/)); } template static int l_pow(lua::State* L) { if (lua::gettop(L) != 2) { throw std::runtime_error("invalid arguments number (2 expected)"); } const auto& a = lua::tovec(L, 1); //vector const auto& b = lua::tonumber(L, 2); //scalar (pow) glm::vec result_vector; for (int i = 0; i < n; i++) { result_vector[i] = pow(a[i], b); } return lua::setvec(L, 1, result_vector); } template static int l_dot(lua::State* L) { if (lua::gettop(L) != 2) { throw std::runtime_error("invalid arguments number (2 expected)"); } return lua::pushnumber(L, glm::dot(lua::tovec(L, 1), // vector a lua::tovec(L, 2) // vector b )); } template static int l_round(lua::State* L) { if (lua::gettop(L)!= 1) { throw std::runtime_error("invalid arguments number (1 expected)"); } const auto& vec = lua::tovec(L, 1); glm::vec rounded_vector; for (int i = 0; i < n; i++) { rounded_vector[i] = std::round(vec[i]); } return lua::setvec(L, 1, rounded_vector); } template static int l_tostring(lua::State* L) { const auto& vec = lua::tovec(L, 1); if (lua::gettop(L) != 1) { throw std::runtime_error("invalid arguments number (1 expected)"); } std::stringstream ss; ss << "vec" << std::to_string(n) << "{"; for (int i = 0; i < n; i++) { if (i > 0) { ss << ", "; } ss << vec[i]; } ss << "}"; return lua::pushstring(L, ss.str()); } const luaL_Reg vec2lib [] = { {"add", lua::wrap>}, {"sub", lua::wrap>}, {"mul", lua::wrap>}, {"div", lua::wrap>}, {"norm", lua::wrap>}, {"len", lua::wrap>}, {"abs", lua::wrap>}, {"tostring", lua::wrap>}, {"pow", lua::wrap>}, {"dot", lua::wrap>}, {"round", lua::wrap>}, {NULL, NULL} }; const luaL_Reg vec3lib [] = { {"add", lua::wrap>}, {"sub", lua::wrap>}, {"mul", lua::wrap>}, {"div", lua::wrap>}, {"norm", lua::wrap>}, {"len", lua::wrap>}, {"abs", lua::wrap>}, {"tostring", lua::wrap>}, {"pow", lua::wrap>}, {"dot", lua::wrap>}, {"round", lua::wrap>}, {NULL, NULL} }; const luaL_Reg vec4lib [] = { {"add", lua::wrap>}, {"sub", lua::wrap>}, {"mul", lua::wrap>}, {"div", lua::wrap>}, {"abs", lua::wrap>}, {"norm", lua::wrap>}, {"len", lua::wrap>}, {"tostring", lua::wrap>}, {"pow", lua::wrap>}, {"dot", lua::wrap>}, {"round", lua::wrap>}, {NULL, NULL} };