From 94639171643b632573f92e5198a2e76df405d4a2 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 30 Apr 2025 20:21:59 +0300 Subject: [PATCH 1/3] feat: 'stairs' rotation profile --- src/content/loading/BlockLoader.cpp | 2 ++ src/logic/PlayerController.cpp | 12 +++++++++++- src/voxels/Block.cpp | 16 ++++++++++++++++ src/voxels/Block.hpp | 4 ++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/content/loading/BlockLoader.cpp b/src/content/loading/BlockLoader.cpp index 5e3b09be..9569301b 100644 --- a/src/content/loading/BlockLoader.cpp +++ b/src/content/loading/BlockLoader.cpp @@ -122,6 +122,8 @@ template<> void ContentUnitLoader::loadUnit( def.rotations = BlockRotProfile::PIPE; } else if (profile == BlockRotProfile::PANE_NAME) { def.rotations = BlockRotProfile::PANE; + } else if (profile == BlockRotProfile::STAIRS_NAME) { + def.rotations = BlockRotProfile::STAIRS; } else if (profile != "none") { logger.error() << "unknown rotation profile " << profile; def.rotatable = false; diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index b157e5e5..080c04cf 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -345,6 +345,16 @@ static int determine_rotation( if (camDir.z > 0.0f) return BLOCK_DIR_SOUTH; if (camDir.z < 0.0f) return BLOCK_DIR_NORTH; } + } else if (name == "stairs") { + int verticalBit = ((norm.y - camDir.y * 0.5f) < 0.0) ? 4 : 0; + if (abs(camDir.x) > abs(camDir.z)) { + if (camDir.x > 0.0f) return BLOCK_DIR_EAST | verticalBit; + if (camDir.x < 0.0f) return BLOCK_DIR_WEST | verticalBit; + } + if (abs(camDir.x) < abs(camDir.z)) { + if (camDir.z > 0.0f) return BLOCK_DIR_SOUTH | verticalBit; + if (camDir.z < 0.0f) return BLOCK_DIR_NORTH | verticalBit; + } } } return 0; @@ -421,7 +431,7 @@ void PlayerController::processRightClick( auto camera = player.fpCamera.get(); blockstate state {}; - state.rotation = determine_rotation(&def, selection.normal, camera->dir); + state.rotation = determine_rotation(&def, selection.normal, camera->front); if (!input.shift && target.rt.funcsset.oninteract) { if (scripting::on_block_interact( diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index b7b0d836..39f8bf11 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -91,6 +91,22 @@ const BlockRotProfile BlockRotProfile::PANE { 4 }; +const BlockRotProfile BlockRotProfile::STAIRS { + "stairs", + { + {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // North + {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}, // East + {{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}}, // South + {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}, // West + + {{-1, 0, 0}, {0, -1, 0}, {0, 0, 1}}, + {{0, 0, 1}, {0, -1, 0}, {1, 0, 0}}, + {{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + {{0, 0, -1}, {0, -1, 0}, {-1, 0, 0}}, + }, + 8 +}; + Block::Block(const std::string& name) : name(name), caption(util::id_to_caption(name)), diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 378cbb5d..5d2d797d 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -77,8 +77,12 @@ struct BlockRotProfile { /// @brief Doors, signs and other panes static const BlockRotProfile PANE; + /// @brief Stairs, stairs and stairs + static const BlockRotProfile STAIRS; + static inline std::string PIPE_NAME = "pipe"; static inline std::string PANE_NAME = "pane"; + static inline std::string STAIRS_NAME = "stairs"; }; enum class BlockModelType { From 3e2bf8a1d3655b636f9a2401bd52ca4141c5ff9c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 30 Apr 2025 21:55:29 +0300 Subject: [PATCH 2/3] fix custom block models culling --- src/graphics/render/BlocksRenderer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 83086975..3baeb0e4 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -308,7 +308,14 @@ void BlocksRenderer::blockCustomModel( const auto& v0 = mesh.vertices[triangle * 3]; auto n = v0.normal.x * X + v0.normal.y * Y + v0.normal.z * Z; - if (!isOpen(glm::floor(coord + n * 1e-4f), *block) && is_aligned(n)) { + auto vp = (mesh.vertices[triangle * 3].coord + + mesh.vertices[triangle * 3 + 1].coord + + mesh.vertices[triangle * 3 + 2].coord) * + 0.3333f - + 0.5f; + vp = vp.x * X + vp.y * Y + vp.z * Z; + + if (!isOpen(glm::floor(coord + vp + 0.5f + n * 1e-3f), *block) && is_aligned(n)) { continue; } From 12c7d4dfb452d8806d88c59d3b0bac7ab2265b2a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 30 Apr 2025 21:56:04 +0300 Subject: [PATCH 3/3] feat: voxel fragment rotation applying to 'stairs' profile --- src/logic/PlayerController.cpp | 13 ++----------- src/world/generator/VoxelFragment.cpp | 5 ++++- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 080c04cf..1d5875ef 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -336,17 +336,8 @@ static int determine_rotation( if (norm.y < 0.0f) return BLOCK_DIR_DOWN; if (norm.z > 0.0f) return BLOCK_DIR_NORTH; if (norm.z < 0.0f) return BLOCK_DIR_SOUTH; - } else if (name == "pane") { - if (abs(camDir.x) > abs(camDir.z)) { - if (camDir.x > 0.0f) return BLOCK_DIR_EAST; - if (camDir.x < 0.0f) return BLOCK_DIR_WEST; - } - if (abs(camDir.x) < abs(camDir.z)) { - if (camDir.z > 0.0f) return BLOCK_DIR_SOUTH; - if (camDir.z < 0.0f) return BLOCK_DIR_NORTH; - } - } else if (name == "stairs") { - int verticalBit = ((norm.y - camDir.y * 0.5f) < 0.0) ? 4 : 0; + } else if (name == "pane" || name == "stairs") { + int verticalBit = (name == "stairs" && (norm.y - camDir.y * 0.5f) < 0.0) ? 4 : 0; if (abs(camDir.x) > abs(camDir.z)) { if (camDir.x > 0.0f) return BLOCK_DIR_EAST | verticalBit; if (camDir.x < 0.0f) return BLOCK_DIR_WEST | verticalBit; diff --git a/src/world/generator/VoxelFragment.cpp b/src/world/generator/VoxelFragment.cpp index 64f9153e..344f0450 100644 --- a/src/world/generator/VoxelFragment.cpp +++ b/src/world/generator/VoxelFragment.cpp @@ -209,10 +209,13 @@ std::unique_ptr VoxelFragment::rotated(const Content& content) co | ((voxel.state.segment & 0b100) >> 2); auto& def = content.blocks.require(blockNames[voxel.id]); if (def.rotations.name == BlockRotProfile::PANE_NAME || - def.rotations.name == BlockRotProfile::PIPE_NAME){ + def.rotations.name == BlockRotProfile::PIPE_NAME) { if (voxel.state.rotation < 4) { voxel.state.rotation = (voxel.state.rotation + 3) & 0b11; } + } else if (def.rotations.name == BlockRotProfile::STAIRS_NAME) { + voxel.state.rotation = ((voxel.state.rotation + 3) & 0b11) | + (voxel.state.rotation & 0b100); } } }