diff --git a/doc/en/scripting/builtins/libvecn.md b/doc/en/scripting/builtins/libvecn.md index 0a42eec8..22552eb7 100644 --- a/doc/en/scripting/builtins/libvecn.md +++ b/doc/en/scripting/builtins/libvecn.md @@ -154,6 +154,12 @@ vec3.spherical_rand(radius: number) -- writes a random vector whose coordinates are uniformly distributed on a sphere of a given radius in dst vec3.spherical_rand(radius: number, dst: vec3) + +-- returns the direction angle of the vector v in degrees [0, 360] +vec2.angle(v: vec2) + +-- returns the direction angle of the vector {x, y} in degrees [0, 360] +vec2.angle(x: number, y: number) ``` diff --git a/doc/ru/scripting/builtins/libvecn.md b/doc/ru/scripting/builtins/libvecn.md index 104c389a..44cfa994 100644 --- a/doc/ru/scripting/builtins/libvecn.md +++ b/doc/ru/scripting/builtins/libvecn.md @@ -154,6 +154,12 @@ vec3.spherical_rand(radius: number) -- записывает случайный вектор, координаты которого равномерно распределены на сфере заданного радиуса в dst vec3.spherical_rand(radius: number, dst: vec3) + +-- возвращает угол направления вектора v в градусах [0, 360] +vec2.angle(v: vec2) + +-- возвращает угол направления вектора {x, y} в градусах [0, 360] +vec2.angle(x: number, y: number) ``` diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index de869aec..50587e2c 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -58,6 +58,8 @@ namespace lua { " expected)"); } } + + [[nodiscard]] inline uint check_argc(lua::State* L, int a, int b) { int argc = lua::gettop(L); if (argc == a || argc == b) { diff --git a/src/logic/scripting/lua/libvecn.cpp b/src/logic/scripting/lua/libvecn.cpp index 217c6314..fc69ad75 100644 --- a/src/logic/scripting/lua/libvecn.cpp +++ b/src/logic/scripting/lua/libvecn.cpp @@ -3,6 +3,16 @@ #include #include #include +#include + +template +inline T angle(glm::vec<2, T> vec) { + auto val = std::atan2(vec.y, vec.x); + if (val < 0.0) { + return val + glm::two_pi(); + } + return val; +} template class Op> static int l_binop(lua::State* L) { @@ -133,6 +143,16 @@ static int l_spherical_rand(lua::State* L) { return 0; } +static int l_vec2_angle(lua::State* L) { + uint argc = lua::check_argc(L, 1, 2); + if (argc == 1) { + return lua::pushnumber(L, glm::degrees(angle(lua::tovec2(L, 1)))); + } else { + return lua::pushnumber(L, glm::degrees(angle( + glm::vec2(lua::tonumber(L, 1), lua::tonumber(L, 2))))); + } +} + template static int l_tostring(lua::State* L) { lua::check_argc(L, 1); @@ -162,6 +182,7 @@ const luaL_Reg vec2lib [] = { {"inverse", lua::wrap>}, {"pow", lua::wrap>}, {"dot", lua::wrap>}, + {"angle", lua::wrap}, {NULL, NULL} };