From 9cec4758668f0f467fd2dfbdb41ff75373a423d6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 14 Jul 2024 13:16:07 +0300 Subject: [PATCH] add block.raycast(...) --- doc/en/scripting.md | 14 ++++++++++++ doc/ru/scripting.md | 14 ++++++++++++ src/logic/scripting/lua/libblock.cpp | 34 ++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/doc/en/scripting.md b/doc/en/scripting.md index d6b9fa86..d27a1dd8 100644 --- a/doc/en/scripting.md +++ b/doc/en/scripting.md @@ -482,6 +482,20 @@ block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) ``` Set specified bits. +```lua +block.raycast(start: vec3, dir: vec3, max_distance: number) -> { + block: int, -- block id + endpoint: vec3, -- point of the ray hit point + iendpoint: vec3, -- position of the block hit by the ray + length: number, -- ray length + normal: vec3, -- normal vector of the surface hit by the ray +} or nil +``` + +Casts a ray from the start point in the direction of dir. Max_distance specifies the maximum ray length. + +The function returns a table with the results or nil if the ray does not hit any block. + ## *item* library ```python diff --git a/doc/ru/scripting.md b/doc/ru/scripting.md index ea48535a..7d89e4f6 100644 --- a/doc/ru/scripting.md +++ b/doc/ru/scripting.md @@ -402,6 +402,20 @@ block.get_picking_item(id: int) -> int Возвращает числовой id предмета, указанного в свойстве *picking-item*. +```lua +block.raycast(start: vec3, dir: vec3, max_distance: number) -> { + block: int, -- id блока + endpoint: vec3, -- точка касания луча + iendpoint: vec3, -- позиция блока, которого касается луч + length: number, -- длина луча + normal: vec3, -- вектор нормали поверхности, которой касается луч +} или nil +``` + +Бросает луч из точки start в направлении dir. Max_distance указывает максимальную длину луча. + +Функция возвращает таблицу с результатами или nil, если луч не касается блока. + ### Вращение Следующие функции используется для учёта вращения блока при обращении к соседним блокам или других целей, где направление блока имеет решающее значение. diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 40fda814..660d8f3c 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -307,6 +307,39 @@ static int l_get_picking_item(lua::State* L) { return 0; } +static int l_raycast(lua::State* L) { + auto start = lua::tovec<3>(L, 1); + auto dir = lua::tovec<3>(L, 2); + auto maxDistance = lua::tonumber(L, 3); + glm::vec3 end; + glm::ivec3 normal; + glm::ivec3 iend; + if (auto voxel = level->chunks->rayCast(start, dir, maxDistance, end, normal, iend)) { + if (lua::gettop(L) >= 4) { + lua::pushvalue(L, 4); + } else { + lua::createtable(L, 0, 5); + } + + lua::pushvec3_arr(L, end); + lua::setfield(L, "endpoint"); + + lua::pushvec3_arr(L, normal); + lua::setfield(L, "normal"); + + lua::pushnumber(L, glm::distance(start, end)); + lua::setfield(L, "length"); + + lua::pushvec3_arr(L, iend); + lua::setfield(L, "iendpoint"); + + lua::pushinteger(L, voxel->id); + lua::setfield(L, "block"); + return 1; + } + return 0; +} + const luaL_Reg blocklib [] = { {"index", lua::wrap}, {"name", lua::wrap}, @@ -335,5 +368,6 @@ const luaL_Reg blocklib [] = { {"get_hitbox", lua::wrap}, {"get_rotation_profile", lua::wrap}, {"get_picking_item", lua::wrap}, + {"raycast", lua::wrap}, {NULL, NULL} };