diff --git a/doc/en/scripting/builtins/libblock.md b/doc/en/scripting/builtins/libblock.md index 5bd0536e..61ea0edf 100644 --- a/doc/en/scripting/builtins/libblock.md +++ b/doc/en/scripting/builtins/libblock.md @@ -67,12 +67,15 @@ Following three functions return direction vectors based on block rotation. -- Returns X: integer direction vector of the block at specified coordinates. -- Example: no rotation: 1, 0, 0. block.get_X(x: int, y: int, z: int) -> int, int, int +block.get_X(id: int, rotation: int) -> int, int, int -- Same for axis Y. Default: 0, 1, 0. block.get_Y(x: int, y: int, z: int) -> int, int, int +block.get_Y(id: int, rotation: int) -> int, int, int -- Same for axis Z. Default: 0, 0, 1. block.get_Z(x: int, y: int, z: int) -> int, int, int +block.get_Z(id: int, rotation: int) -> int, int, int -- Returns block rotation index based on used profile. block.get_rotation(x: int, y: int, z: int) -> int diff --git a/doc/ru/scripting/builtins/libblock.md b/doc/ru/scripting/builtins/libblock.md index 19a28198..5cb149e3 100644 --- a/doc/ru/scripting/builtins/libblock.md +++ b/doc/ru/scripting/builtins/libblock.md @@ -90,12 +90,15 @@ block.raycast(start: vec3, dir: vec3, max_distance: number, [опциональ -- Возвращает целочисленный единичный вектор X блока на указанных координатах с учётом его вращения (три целых числа). -- Если поворот отсутствует, возвращает 1, 0, 0 block.get_X(x: int, y: int, z: int) -> int, int, int +block.get_X(id: int, rotation: int) -> int, int, int -- То же, но для оси Y (по-умолчанию 0, 1, 0) block.get_Y(x: int, y: int, z: int) -> int, int, int +block.get_Y(id: int, rotation: int) -> int, int, int -- То же, но для оси Z (по-умолчанию 0, 0, 1) block.get_Z(x: int, y: int, z: int) -> int, int, int +block.get_Z(id: int, rotation: int) -> int, int, int -- Возвращает индекс поворота блока в его профиле вращения (не превышает 7). block.get_rotation(x: int, y: int, z: int) -> int diff --git a/res/content/base/scripts/components/falling_block.lua b/res/content/base/scripts/components/falling_block.lua index ee2075f4..ab69c513 100644 --- a/res/content/base/scripts/components/falling_block.lua +++ b/res/content/base/scripts/components/falling_block.lua @@ -13,9 +13,12 @@ else end do -- setup visuals - local textures = block.get_textures(block.index(blockid)) + local id = block.index(blockid) + local rotation = block.decompose_state(blockstates)[1] + local textures = block.get_textures(id) for i,t in ipairs(textures) do rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i]) + rig:set_matrix(0, mat4.look_at({0,0,0}, {block.get_Z(id, rotation)}, {block.get_Y(id, rotation)})) end end diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 371c0ada..1d3b39b4 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -237,9 +237,9 @@ void BlocksRenderer::blockAABB( if (block->rotatable) { auto& rotations = block->rotations; auto& orient = rotations.variants[rotation]; - X = orient.axisX; - Y = orient.axisY; - Z = orient.axisZ; + X = orient.axes[0]; + Y = orient.axes[1]; + Z = orient.axes[2]; orient.transform(hitbox); } coord -= glm::vec3(0.5f) - hitbox.center(); @@ -272,14 +272,13 @@ void BlocksRenderer::blockCustomModel( glm::vec3 X(1, 0, 0); glm::vec3 Y(0, 1, 0); glm::vec3 Z(0, 0, 1); - CoordSystem orient(X,Y,Z); glm::vec3 coord(icoord); if (block->rotatable) { auto& rotations = block->rotations; - orient = rotations.variants[rotation]; - X = orient.axisX; - Y = orient.axisY; - Z = orient.axisZ; + CoordSystem orient = rotations.variants[rotation]; + X = orient.axes[0]; + Y = orient.axes[1]; + Z = orient.axes[2]; } const auto& model = cache.getModel(block->rt.id); @@ -333,9 +332,9 @@ void BlocksRenderer::blockCube( if (block.rotatable) { auto& rotations = block.rotations; auto& orient = rotations.variants[states.rotation]; - X = orient.axisX; - Y = orient.axisY; - Z = orient.axisZ; + X = orient.axes[0]; + Y = orient.axes[1]; + Z = orient.axes[2]; } if (ao) { diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 2fcfd46b..cdc25b48 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -41,9 +41,9 @@ void BlocksController::updateSides(int x, int y, int z, int w, int h, int d) { voxel* vox = blocks_agent::get(chunks, x, y, z); const auto& def = level.content.getIndices()->blocks.require(vox->id); const auto& rot = def.rotations.variants[vox->state.rotation]; - const auto& xaxis = rot.axisX; - const auto& yaxis = rot.axisY; - const auto& zaxis = rot.axisZ; + const auto& xaxis = rot.axes[0]; + const auto& yaxis = rot.axes[1]; + const auto& zaxis = rot.axes[2]; for (int ly = -1; ly <= h; ly++) { for (int lz = -1; lz <= d; lz++) { for (int lx = -1; lx <= w; lx++) { diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index a4f15a3c..d35dd764 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -125,55 +125,47 @@ static int l_get(lua::State* L) { return lua::pushinteger(L, id); } -static int l_get_x(lua::State* L) { +template +static int get_axis(lua::State* L, const Block& def, int rotation) { + const CoordSystem& rot = def.rotations.variants[rotation]; + return lua::pushivec_stack(L, rot.axes[n]); +} + +template +static int get_axis(lua::State* L) { auto x = lua::tointeger(L, 1); auto y = lua::tointeger(L, 2); + if (lua::gettop(L) == 2) { + const auto& def = level->content.getIndices()->blocks.require(x); + return get_axis(L, def, y); + } auto z = lua::tointeger(L, 3); + + glm::ivec3 defAxis; + defAxis[n] = 1; + auto vox = blocks_agent::get(*level->chunks, x, y, z); if (vox == nullptr) { - return lua::pushivec_stack(L, glm::ivec3(1, 0, 0)); + return lua::pushivec_stack(L, defAxis); } const auto& def = level->content.getIndices()->blocks.require(vox->id); if (!def.rotatable) { - return lua::pushivec_stack(L, glm::ivec3(1, 0, 0)); + return lua::pushivec_stack(L, defAxis); } else { - const CoordSystem& rot = def.rotations.variants[vox->state.rotation]; - return lua::pushivec_stack(L, rot.axisX); + return get_axis(L, def, vox->state.rotation); } } +static int l_get_x(lua::State* L) { + return get_axis<0>(L); +} + static int l_get_y(lua::State* L) { - auto x = lua::tointeger(L, 1); - auto y = lua::tointeger(L, 2); - auto z = lua::tointeger(L, 3); - auto vox = blocks_agent::get(*level->chunks, x, y, z); - if (vox == nullptr) { - return lua::pushivec_stack(L, glm::ivec3(0, 1, 0)); - } - const auto& def = level->content.getIndices()->blocks.require(vox->id); - if (!def.rotatable) { - return lua::pushivec_stack(L, glm::ivec3(0, 1, 0)); - } else { - const CoordSystem& rot = def.rotations.variants[vox->state.rotation]; - return lua::pushivec_stack(L, rot.axisY); - } + return get_axis<1>(L); } static int l_get_z(lua::State* L) { - auto x = lua::tointeger(L, 1); - auto y = lua::tointeger(L, 2); - auto z = lua::tointeger(L, 3); - auto vox = blocks_agent::get(*level->chunks, x, y, z); - if (vox == nullptr) { - return lua::pushivec_stack(L, glm::ivec3(0, 0, 1)); - } - const auto& def = level->content.getIndices()->blocks.require(vox->id); - if (!def.rotatable) { - return lua::pushivec_stack(L, glm::ivec3(0, 0, 1)); - } else { - const CoordSystem& rot = def.rotations.variants[vox->state.rotation]; - return lua::pushivec_stack(L, rot.axisZ); - } + return get_axis<2>(L); } static int l_get_rotation(lua::State* L) { diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 96bca245..300eb250 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -74,7 +74,7 @@ std::optional CullingMode_from(std::string_view str) { } CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ) - : axisX(axisX), axisY(axisY), axisZ(axisZ) { + : axes({axisX, axisY, axisZ}) { fix = glm::ivec3(0); if (isVectorHasNegatives(axisX)) fix -= axisX; if (isVectorHasNegatives(axisY)) fix -= axisY; @@ -82,9 +82,9 @@ CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ) } void CoordSystem::transform(AABB& aabb) const { - glm::vec3 X(axisX); - glm::vec3 Y(axisY); - glm::vec3 Z(axisZ); + glm::vec3 X(axes[0]); + glm::vec3 Y(axes[1]); + glm::vec3 Z(axes[2]); aabb.a = X * aabb.a.x + Y * aabb.a.y + Z * aabb.a.z; aabb.b = X * aabb.b.x + Y * aabb.b.y + Z * aabb.b.z; aabb.a += fix; diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 83dafa47..f3fa2a0f 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -47,10 +47,7 @@ struct BlockFuncsSet { }; struct CoordSystem { - glm::ivec3 axisX; - glm::ivec3 axisY; - glm::ivec3 axisZ; - + std::array axes; /// @brief Grid 3d position fix offset (for negative vectors) glm::ivec3 fix; @@ -261,5 +258,5 @@ public: }; inline glm::ivec3 get_ground_direction(const Block& def, int rotation) { - return -def.rotations.variants[rotation].axisY; + return -def.rotations.variants[rotation].axes[1]; } diff --git a/src/voxels/blocks_agent.hpp b/src/voxels/blocks_agent.hpp index 72cdd5ab..15813bc9 100644 --- a/src/voxels/blocks_agent.hpp +++ b/src/voxels/blocks_agent.hpp @@ -162,9 +162,9 @@ inline void erase_segments( continue; } glm::ivec3 pos(x, y, z); - pos += rotation.axisX * sx; - pos += rotation.axisY * sy; - pos += rotation.axisZ * sz; + pos += rotation.axes[0] * sx; + pos += rotation.axes[1] * sy; + pos += rotation.axes[2] * sz; set(chunks, pos.x, pos.y, pos.z, 0, {}); } } @@ -205,9 +205,9 @@ inline void repair_segments( segState.segment = segment_to_int(sx, sy, sz); glm::ivec3 pos(x, y, z); - pos += rotation.axisX * sx; - pos += rotation.axisY * sy; - pos += rotation.axisZ * sz; + pos += rotation.axes[0] * sx; + pos += rotation.axes[1] * sy; + pos += rotation.axes[2] * sz; set(chunks, pos.x, pos.y, pos.z, id, segState); } } @@ -233,9 +233,9 @@ inline glm::ivec3 seek_origin( if (!segment) { return pos; } - if (segment & 1) pos -= rotation.axisX; - if (segment & 2) pos -= rotation.axisY; - if (segment & 4) pos -= rotation.axisZ; + if (segment & 1) pos -= rotation.axes[0]; + if (segment & 2) pos -= rotation.axes[1]; + if (segment & 4) pos -= rotation.axes[2]; if (auto* voxel = get(chunks, pos.x, pos.y, pos.z)) { segment = voxel->state.segment; @@ -268,9 +268,9 @@ inline bool check_replaceability( for (int sz = 0; sz < size.z; sz++) { for (int sx = 0; sx < size.x; sx++) { auto pos = origin; - pos += rotation.axisX * sx; - pos += rotation.axisY * sy; - pos += rotation.axisZ * sz; + pos += rotation.axes[0] * sx; + pos += rotation.axes[1] * sy; + pos += rotation.axes[2] * sz; if (auto vox = get(chunks, pos.x, pos.y, pos.z)) { auto& target = blocks.require(vox->id); if (!target.replaceable && vox->id != ignore) { @@ -316,9 +316,9 @@ inline void set_rotation_extended( for (int sz = 0; sz < size.z; sz++) { for (int sx = 0; sx < size.x; sx++) { auto pos = origin; - pos += rotation.axisX * sx; - pos += rotation.axisY * sy; - pos += rotation.axisZ * sz; + pos += rotation.axes[0] * sx; + pos += rotation.axes[1] * sy; + pos += rotation.axes[2] * sz; blockstate segState = newstate; segState.segment = segment_to_int(sx, sy, sz); @@ -344,9 +344,9 @@ inline void set_rotation_extended( for (int sz = 0; sz < size.z; sz++) { for (int sx = 0; sx < size.x; sx++) { auto pos = origin; - pos += prevRotation.axisX * sx; - pos += prevRotation.axisY * sy; - pos += prevRotation.axisZ * sz; + pos += prevRotation.axes[0] * sx; + pos += prevRotation.axes[1] * sy; + pos += prevRotation.axes[2] * sz; if (std::find( segmentBlocks.begin(), segmentBlocks.end(), pos ) == segmentBlocks.end()) {