From e0cb57a10acee5a91060ae6d391f249ef91ffc93 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 22 Jul 2024 19:05:27 +0300 Subject: [PATCH] add quat Lua library --- doc/en/scripting.md | 12 +++++++ doc/en/scripting/builtins/libmat4.md | 13 ------- doc/en/scripting/builtins/libquat.md | 34 ++++++++++++++++++ doc/ru/scripting.md | 12 +++++++ doc/ru/scripting/builtins/libmat4.md | 13 ------- doc/ru/scripting/builtins/libquat.md | 34 ++++++++++++++++++ src/logic/scripting/lua/api_lua.hpp | 1 + src/logic/scripting/lua/libquat.cpp | 50 ++++++++++++++++++++++++++ src/logic/scripting/lua/lua_engine.cpp | 1 + src/logic/scripting/lua/lua_util.hpp | 9 ++++- 10 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 doc/en/scripting/builtins/libquat.md create mode 100644 doc/ru/scripting/builtins/libquat.md create mode 100644 src/logic/scripting/lua/libquat.cpp diff --git a/doc/en/scripting.md b/doc/en/scripting.md index a25b1ebe..2ae09e3b 100644 --- a/doc/en/scripting.md +++ b/doc/en/scripting.md @@ -13,11 +13,23 @@ Subsections: - [entities](scripting/builtins/libentities.md) - [cameras](scripting/builtins/libcameras.md) - [mat4](scripting/builtins/libmat4.md) + - [quat](scripting/builtins/libquat.md) - [vec2, vec3, vec4](scripting/builtins/libvecn.md) - [Module core:bit_converter](scripting/modules/core_bit_converter.md) - [Module core:data_buffer](scripting/modules/core_data_buffer.md) - [Module core:vector2, core:vector3](scripting/modules/core_vector2_vector3.md) +## Type annotations + +The documentation for Lua libraries uses type annotations, +not part of Lua syntax. + +- vector - an array of three or four numbers +- vec2 - array of two numbers +- vec3 - array of three numbers +- vec4 - array of four numbers +- quat - array of four numbers - quaternion +- matrix - array of 16 numbers - matrix ## Core functions diff --git a/doc/en/scripting/builtins/libmat4.md b/doc/en/scripting/builtins/libmat4.md index e81696bd..e652d2aa 100644 --- a/doc/en/scripting/builtins/libmat4.md +++ b/doc/en/scripting/builtins/libmat4.md @@ -4,19 +4,6 @@ Most functions have several options for argument lists (overloads). -## Data types - -Type conventions will be used on this page. -- vector - an array of three or four numbers -- vec3 - array of three numbers -- vec4 - array of four numbers -- quat - array of four numbers - quaternion -- matrix - array of 16 numbers - matrix - -> [!WARNING] -> -> Type annotations are part of the documentation and are not present in Lua. - ## Identity matrix - *mat4.idt(...)* ```lua diff --git a/doc/en/scripting/builtins/libquat.md b/doc/en/scripting/builtins/libquat.md new file mode 100644 index 00000000..f7cc7a0f --- /dev/null +++ b/doc/en/scripting/builtins/libquat.md @@ -0,0 +1,34 @@ +# *quat* library + +Quaternions manipulation library. + +## Quaternion from matrix - *mat4.from_quat(...)* + +```lua +-- creates a quaternion based on the rotation matrix +quat.from_mat4(m: matrix) + +-- writes a quaternion from the rotation matrix to dst +quat.from_mat4(m: matrix, dst: quat) +``` + +## Spherical linear interpolation - *quat.slerp(...)* + +The interpolation always take the short path and the rotation is performed at constant speed. + +```lua +-- creates a quaternion as an interpolation between a and b, +-- where t is interpolation factor +quat.slerp(a: quat, b: quat, t: number) + +-- writes a quaternion as an interpolation between a and b to dst, +-- where t is interpolation factor +quat.slerp(a: quat, b: quat, t: number, dst: quat) +``` + +## Casting to string - *quat.tostring(...)* + +```lua +-- returns a string representing the contents of the quaternion +quat.tostring(q: quat) +``` diff --git a/doc/ru/scripting.md b/doc/ru/scripting.md index 45dd8df9..88ef3b09 100644 --- a/doc/ru/scripting.md +++ b/doc/ru/scripting.md @@ -13,11 +13,23 @@ - [entities](scripting/builtins/libentities.md) - [cameras](scripting/builtins/libcameras.md) - [mat4](scripting/builtins/libmat4.md) + - [quat](scripting/builtins/libquat.md) - [vec2, vec3, vec4](scripting/builtins/libvecn.md) - [Модуль core:bit_converter](scripting/modules/core_bit_converter.md) - [Модуль core:data_buffer](scripting/modules/core_data_buffer.md) - [Модули core:vector2, core:vector3](scripting/modules/core_vector2_vector3.md) +## Аннотации типов данных + +В документации к Lua библиотекам используются аннотации типов, +не являющиеся частью синтаксиса Lua. + +- vector - массив из трех или четырех чисел +- vec2 - массив из двух чисел +- vec3 - массив из трех чисел +- vec4 - массив из четырех чисел +- quat - массив из четырех чисел - кватернион +- matrix - массив из 16 чисел - матрица ```lua require "контентпак:имя_модуля" -- загружает lua модуль из папки modules (расширение не указывается) diff --git a/doc/ru/scripting/builtins/libmat4.md b/doc/ru/scripting/builtins/libmat4.md index da4e1c2f..e30ca0b6 100644 --- a/doc/ru/scripting/builtins/libmat4.md +++ b/doc/ru/scripting/builtins/libmat4.md @@ -4,19 +4,6 @@ Большинство функций имеют несколько вариантов списка агрументов (перегрузок). -## Типы данных - -На данной странице будут использоваться условные обозначения типов. -- vector - массив из трех или четырех чисел -- vec3 - массив из трех чисел -- vec4 - массив из четырех чисел -- quat - массив из четырех чисел - кватернион -- matrix - массив из 16 чисел - матрица - -> [!WARNING] -> -> Аннотации типов являются частью документации и не указываются при вызове использовании. - ## Единичная матрица - *mat4.idt(...)* ```lua diff --git a/doc/ru/scripting/builtins/libquat.md b/doc/ru/scripting/builtins/libquat.md new file mode 100644 index 00000000..5b61c36b --- /dev/null +++ b/doc/ru/scripting/builtins/libquat.md @@ -0,0 +1,34 @@ +# Библиотека *quat* + +Библиотека для работы с кватернионами. + +## Кватернион из матрицы - *mat4.from_quat(...)* + +```lua +-- создает кватернион на основе матрицы вращения +quat.from_mat4(m: matrix) + +-- записывает кватернион по матрице вращения в dst +quat.from_mat4(m: matrix, dst: quat) +``` + +## Сферическая линейная интерполяция - *quat.slerp(...)* + +Интерполяция всегда выполняется по короткому пути, а вращение выполняется с постоянной скоростью. + +```lua +-- создает кватернион как интерполяцию между a и b, +-- где t - фактор интерполяции +quat.slerp(a: quat, b: quat, t: number) + +-- записывает кватернион как интерполяцию между a и b в dst, +-- где t - фактор интерполяции +quat.slerp(a: quat, b: quat, t: number, dst: quat) +``` + +## Перевод в строку - *quat.tostring(...)* + +```lua +-- возвращает строку представляющую содержимое кватерниона +quat.tostring(q: quat) +``` diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index 4c5c062d..de869aec 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -31,6 +31,7 @@ extern const luaL_Reg jsonlib []; extern const luaL_Reg mat4lib []; extern const luaL_Reg packlib []; extern const luaL_Reg playerlib []; +extern const luaL_Reg quatlib []; // quat.cpp extern const luaL_Reg timelib []; extern const luaL_Reg tomllib []; extern const luaL_Reg vec2lib []; // vecn.cpp diff --git a/src/logic/scripting/lua/libquat.cpp b/src/logic/scripting/lua/libquat.cpp new file mode 100644 index 00000000..8b7d581c --- /dev/null +++ b/src/logic/scripting/lua/libquat.cpp @@ -0,0 +1,50 @@ +#include "api_lua.hpp" + +#define GLM_ENABLE_EXPERIMENTAL +#include +#include + +static int l_from_mat4(lua::State* L) { + uint argc = lua::check_argc(L, 1, 2); + auto matrix = lua::tomat4(L, 1); + if (argc == 1) { + return lua::pushquat(L, glm::toQuat(matrix)); + } else { + return lua::setquat(L, 2, glm::toQuat(matrix)); + } +} + +static int l_slerp(lua::State* L) { + uint argc = lua::check_argc(L, 3, 4); + auto quat1 = lua::toquat(L, 1); + auto quat2 = lua::toquat(L, 2); + float t = lua::tonumber(L, 3); + if (argc == 3) { + return lua::pushquat(L, glm::slerp(quat1, quat2, t)); + } else { + return lua::setquat(L, 4, glm::slerp(quat1, quat2, t)); + } +} + +static int l_tostring(lua::State* L) { + lua::check_argc(L, 1); + auto quat = lua::toquat(L, 1); + + std::stringstream ss; + ss << "quat" << "{"; + for (int i = 0; i < 4; i++) { + if (i > 0) { + ss << ", "; + } + ss << quat[i]; + } + ss << "}"; + return lua::pushstring(L, ss.str()); +} + +const luaL_Reg quatlib [] = { + {"from_mat4", lua::wrap}, + {"slerp", 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 6d303593..f3852c30 100644 --- a/src/logic/scripting/lua/lua_engine.cpp +++ b/src/logic/scripting/lua/lua_engine.cpp @@ -40,6 +40,7 @@ static void create_libs(lua::State* L) { openlib(L, "mat4", mat4lib); openlib(L, "pack", packlib); openlib(L, "player", playerlib); + openlib(L, "quat", quatlib); openlib(L, "time", timelib); openlib(L, "toml", tomllib); openlib(L, "vec2", vec2lib); diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index 5237604c..d522165b 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -196,7 +196,14 @@ namespace lua { } return 1; } - + inline int setquat(lua::State* L, int idx, glm::quat quat) { + pushvalue(L, idx); + for (int i = 0; i < 4; i++) { + pushnumber(L, quat[i]); + rawseti(L, i+1); + } + return 1; + } inline int pushmat4(lua::State* L, glm::mat4 matrix) { createtable(L, 16, 0); for (uint y = 0; y < 4; y++) {