add new block.get_AXIS functions overloads & add rotation support to base:falling_block

This commit is contained in:
MihailRis 2024-12-29 21:48:36 +03:00
parent 9a190acb8b
commit ab5a62c3aa
9 changed files with 72 additions and 75 deletions

View File

@ -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. -- Returns X: integer direction vector of the block at specified coordinates.
-- Example: no rotation: 1, 0, 0. -- Example: no rotation: 1, 0, 0.
block.get_X(x: int, y: int, z: int) -> int, int, int 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. -- Same for axis Y. Default: 0, 1, 0.
block.get_Y(x: int, y: int, z: int) -> int, int, int 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. -- Same for axis Z. Default: 0, 0, 1.
block.get_Z(x: int, y: int, z: int) -> int, int, int 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. -- Returns block rotation index based on used profile.
block.get_rotation(x: int, y: int, z: int) -> int block.get_rotation(x: int, y: int, z: int) -> int

View File

@ -90,12 +90,15 @@ block.raycast(start: vec3, dir: vec3, max_distance: number, [опциональ
-- Возвращает целочисленный единичный вектор X блока на указанных координатах с учётом его вращения (три целых числа). -- Возвращает целочисленный единичный вектор X блока на указанных координатах с учётом его вращения (три целых числа).
-- Если поворот отсутствует, возвращает 1, 0, 0 -- Если поворот отсутствует, возвращает 1, 0, 0
block.get_X(x: int, y: int, z: int) -> int, int, int 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) -- То же, но для оси Y (по-умолчанию 0, 1, 0)
block.get_Y(x: int, y: int, z: int) -> int, int, int 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) -- То же, но для оси Z (по-умолчанию 0, 0, 1)
block.get_Z(x: int, y: int, z: int) -> int, int, int block.get_Z(x: int, y: int, z: int) -> int, int, int
block.get_Z(id: int, rotation: int) -> int, int, int
-- Возвращает индекс поворота блока в его профиле вращения (не превышает 7). -- Возвращает индекс поворота блока в его профиле вращения (не превышает 7).
block.get_rotation(x: int, y: int, z: int) -> int block.get_rotation(x: int, y: int, z: int) -> int

View File

@ -13,9 +13,12 @@ else
end end
do -- setup visuals 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 for i,t in ipairs(textures) do
rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i]) 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
end end

View File

@ -237,9 +237,9 @@ void BlocksRenderer::blockAABB(
if (block->rotatable) { if (block->rotatable) {
auto& rotations = block->rotations; auto& rotations = block->rotations;
auto& orient = rotations.variants[rotation]; auto& orient = rotations.variants[rotation];
X = orient.axisX; X = orient.axes[0];
Y = orient.axisY; Y = orient.axes[1];
Z = orient.axisZ; Z = orient.axes[2];
orient.transform(hitbox); orient.transform(hitbox);
} }
coord -= glm::vec3(0.5f) - hitbox.center(); coord -= glm::vec3(0.5f) - hitbox.center();
@ -272,14 +272,13 @@ void BlocksRenderer::blockCustomModel(
glm::vec3 X(1, 0, 0); glm::vec3 X(1, 0, 0);
glm::vec3 Y(0, 1, 0); glm::vec3 Y(0, 1, 0);
glm::vec3 Z(0, 0, 1); glm::vec3 Z(0, 0, 1);
CoordSystem orient(X,Y,Z);
glm::vec3 coord(icoord); glm::vec3 coord(icoord);
if (block->rotatable) { if (block->rotatable) {
auto& rotations = block->rotations; auto& rotations = block->rotations;
orient = rotations.variants[rotation]; CoordSystem orient = rotations.variants[rotation];
X = orient.axisX; X = orient.axes[0];
Y = orient.axisY; Y = orient.axes[1];
Z = orient.axisZ; Z = orient.axes[2];
} }
const auto& model = cache.getModel(block->rt.id); const auto& model = cache.getModel(block->rt.id);
@ -333,9 +332,9 @@ void BlocksRenderer::blockCube(
if (block.rotatable) { if (block.rotatable) {
auto& rotations = block.rotations; auto& rotations = block.rotations;
auto& orient = rotations.variants[states.rotation]; auto& orient = rotations.variants[states.rotation];
X = orient.axisX; X = orient.axes[0];
Y = orient.axisY; Y = orient.axes[1];
Z = orient.axisZ; Z = orient.axes[2];
} }
if (ao) { if (ao) {

View File

@ -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); voxel* vox = blocks_agent::get(chunks, x, y, z);
const auto& def = level.content.getIndices()->blocks.require(vox->id); const auto& def = level.content.getIndices()->blocks.require(vox->id);
const auto& rot = def.rotations.variants[vox->state.rotation]; const auto& rot = def.rotations.variants[vox->state.rotation];
const auto& xaxis = rot.axisX; const auto& xaxis = rot.axes[0];
const auto& yaxis = rot.axisY; const auto& yaxis = rot.axes[1];
const auto& zaxis = rot.axisZ; const auto& zaxis = rot.axes[2];
for (int ly = -1; ly <= h; ly++) { for (int ly = -1; ly <= h; ly++) {
for (int lz = -1; lz <= d; lz++) { for (int lz = -1; lz <= d; lz++) {
for (int lx = -1; lx <= w; lx++) { for (int lx = -1; lx <= w; lx++) {

View File

@ -125,55 +125,47 @@ static int l_get(lua::State* L) {
return lua::pushinteger(L, id); return lua::pushinteger(L, id);
} }
static int l_get_x(lua::State* L) { template<int n>
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<int n>
static int get_axis(lua::State* L) {
auto x = lua::tointeger(L, 1); auto x = lua::tointeger(L, 1);
auto y = lua::tointeger(L, 2); auto y = lua::tointeger(L, 2);
if (lua::gettop(L) == 2) {
const auto& def = level->content.getIndices()->blocks.require(x);
return get_axis<n>(L, def, y);
}
auto z = lua::tointeger(L, 3); auto z = lua::tointeger(L, 3);
glm::ivec3 defAxis;
defAxis[n] = 1;
auto vox = blocks_agent::get(*level->chunks, x, y, z); auto vox = blocks_agent::get(*level->chunks, x, y, z);
if (vox == nullptr) { 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); const auto& def = level->content.getIndices()->blocks.require(vox->id);
if (!def.rotatable) { if (!def.rotatable) {
return lua::pushivec_stack(L, glm::ivec3(1, 0, 0)); return lua::pushivec_stack(L, defAxis);
} else { } else {
const CoordSystem& rot = def.rotations.variants[vox->state.rotation]; return get_axis<n>(L, def, vox->state.rotation);
return lua::pushivec_stack(L, rot.axisX);
} }
} }
static int l_get_x(lua::State* L) {
return get_axis<0>(L);
}
static int l_get_y(lua::State* L) { static int l_get_y(lua::State* L) {
auto x = lua::tointeger(L, 1); return get_axis<1>(L);
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);
}
} }
static int l_get_z(lua::State* L) { static int l_get_z(lua::State* L) {
auto x = lua::tointeger(L, 1); return get_axis<2>(L);
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);
}
} }
static int l_get_rotation(lua::State* L) { static int l_get_rotation(lua::State* L) {

View File

@ -74,7 +74,7 @@ std::optional<CullingMode> CullingMode_from(std::string_view str) {
} }
CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ) 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); fix = glm::ivec3(0);
if (isVectorHasNegatives(axisX)) fix -= axisX; if (isVectorHasNegatives(axisX)) fix -= axisX;
if (isVectorHasNegatives(axisY)) fix -= axisY; 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 { void CoordSystem::transform(AABB& aabb) const {
glm::vec3 X(axisX); glm::vec3 X(axes[0]);
glm::vec3 Y(axisY); glm::vec3 Y(axes[1]);
glm::vec3 Z(axisZ); glm::vec3 Z(axes[2]);
aabb.a = X * aabb.a.x + Y * aabb.a.y + Z * aabb.a.z; 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.b = X * aabb.b.x + Y * aabb.b.y + Z * aabb.b.z;
aabb.a += fix; aabb.a += fix;

View File

@ -47,10 +47,7 @@ struct BlockFuncsSet {
}; };
struct CoordSystem { struct CoordSystem {
glm::ivec3 axisX; std::array<glm::ivec3, 3> axes;
glm::ivec3 axisY;
glm::ivec3 axisZ;
/// @brief Grid 3d position fix offset (for negative vectors) /// @brief Grid 3d position fix offset (for negative vectors)
glm::ivec3 fix; glm::ivec3 fix;
@ -261,5 +258,5 @@ public:
}; };
inline glm::ivec3 get_ground_direction(const Block& def, int rotation) { inline glm::ivec3 get_ground_direction(const Block& def, int rotation) {
return -def.rotations.variants[rotation].axisY; return -def.rotations.variants[rotation].axes[1];
} }

View File

@ -162,9 +162,9 @@ inline void erase_segments(
continue; continue;
} }
glm::ivec3 pos(x, y, z); glm::ivec3 pos(x, y, z);
pos += rotation.axisX * sx; pos += rotation.axes[0] * sx;
pos += rotation.axisY * sy; pos += rotation.axes[1] * sy;
pos += rotation.axisZ * sz; pos += rotation.axes[2] * sz;
set(chunks, pos.x, pos.y, pos.z, 0, {}); 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); segState.segment = segment_to_int(sx, sy, sz);
glm::ivec3 pos(x, y, z); glm::ivec3 pos(x, y, z);
pos += rotation.axisX * sx; pos += rotation.axes[0] * sx;
pos += rotation.axisY * sy; pos += rotation.axes[1] * sy;
pos += rotation.axisZ * sz; pos += rotation.axes[2] * sz;
set(chunks, pos.x, pos.y, pos.z, id, segState); set(chunks, pos.x, pos.y, pos.z, id, segState);
} }
} }
@ -233,9 +233,9 @@ inline glm::ivec3 seek_origin(
if (!segment) { if (!segment) {
return pos; return pos;
} }
if (segment & 1) pos -= rotation.axisX; if (segment & 1) pos -= rotation.axes[0];
if (segment & 2) pos -= rotation.axisY; if (segment & 2) pos -= rotation.axes[1];
if (segment & 4) pos -= rotation.axisZ; if (segment & 4) pos -= rotation.axes[2];
if (auto* voxel = get(chunks, pos.x, pos.y, pos.z)) { if (auto* voxel = get(chunks, pos.x, pos.y, pos.z)) {
segment = voxel->state.segment; segment = voxel->state.segment;
@ -268,9 +268,9 @@ inline bool check_replaceability(
for (int sz = 0; sz < size.z; sz++) { for (int sz = 0; sz < size.z; sz++) {
for (int sx = 0; sx < size.x; sx++) { for (int sx = 0; sx < size.x; sx++) {
auto pos = origin; auto pos = origin;
pos += rotation.axisX * sx; pos += rotation.axes[0] * sx;
pos += rotation.axisY * sy; pos += rotation.axes[1] * sy;
pos += rotation.axisZ * sz; pos += rotation.axes[2] * sz;
if (auto vox = get(chunks, pos.x, pos.y, pos.z)) { if (auto vox = get(chunks, pos.x, pos.y, pos.z)) {
auto& target = blocks.require(vox->id); auto& target = blocks.require(vox->id);
if (!target.replaceable && vox->id != ignore) { 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 sz = 0; sz < size.z; sz++) {
for (int sx = 0; sx < size.x; sx++) { for (int sx = 0; sx < size.x; sx++) {
auto pos = origin; auto pos = origin;
pos += rotation.axisX * sx; pos += rotation.axes[0] * sx;
pos += rotation.axisY * sy; pos += rotation.axes[1] * sy;
pos += rotation.axisZ * sz; pos += rotation.axes[2] * sz;
blockstate segState = newstate; blockstate segState = newstate;
segState.segment = segment_to_int(sx, sy, sz); 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 sz = 0; sz < size.z; sz++) {
for (int sx = 0; sx < size.x; sx++) { for (int sx = 0; sx < size.x; sx++) {
auto pos = origin; auto pos = origin;
pos += prevRotation.axisX * sx; pos += prevRotation.axes[0] * sx;
pos += prevRotation.axisY * sy; pos += prevRotation.axes[1] * sy;
pos += prevRotation.axisZ * sz; pos += prevRotation.axes[2] * sz;
if (std::find( if (std::find(
segmentBlocks.begin(), segmentBlocks.end(), pos segmentBlocks.begin(), segmentBlocks.end(), pos
) == segmentBlocks.end()) { ) == segmentBlocks.end()) {