Merge pull request #770 from MihailRis/add-solid-property

add explicit 'solid' block property
This commit is contained in:
MihailRis 2026-01-09 00:10:51 +03:00 • committed by GitHub
commit e051921a56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 40 additions and 21 deletions

View file

@ -56,6 +56,11 @@ Enables translucency support in block textures (examples: water, ice).
Should only be used when needed, as it impacts performance. Should only be used when needed, as it impacts performance.
Not required for full transparency (grass, flowers). Not required for full transparency (grass, flowers).
### *solid*
Explicitly specifies that the block is solid - completely overlapping the blocks behind it.
Used by blocks with the `custom` model type, which must support culling of invisible geometry, as with the `block` type. If `false` specified then ignored.
### *rotation* ### *rotation*
Rotation profile (set of available block rotations and behaviour of placing block rotation) from list: Rotation profile (set of available block rotations and behaviour of placing block rotation) from list:

View file

@ -57,6 +57,11 @@
Следует использовать только при надобности, так как влияет на производительность. Следует использовать только при надобности, так как влияет на производительность.
Не требуется для полной прозрачности (трава, цветы). Не требуется для полной прозрачности (трава, цветы).
### Цельность - *solid*
Явно указывает, что блок является цельным (полным) - полностью перекрывает блоки за собой.
Используется блоками с типом модели `custom`, которые должны поддерживать отсечение невидимой геометрии, как у типа `block`. Свойство игнорируется при указании `false`.
### Вращение - *rotation* ### Вращение - *rotation*
Профиль вращения (набор положений, в которые можно установить блок) из списка: Профиль вращения (набор положений, в которые можно установить блок) из списка:

View file

@ -7,7 +7,7 @@ local names = {
"hidden", "draw-group", "picking-item", "surface-replacement", "script-name", "hidden", "draw-group", "picking-item", "surface-replacement", "script-name",
"ui-layout", "inventory-size", "tick-interval", "overlay-texture", "ui-layout", "inventory-size", "tick-interval", "overlay-texture",
"translucent", "fields", "particles", "icon-type", "icon", "placing-block", "translucent", "fields", "particles", "icon-type", "icon", "placing-block",
"stack-size", "name", "script-file", "culling" "stack-size", "name", "script-file", "culling", "solid"
} }
for name, _ in pairs(user_props) do for name, _ in pairs(user_props) do
table.insert(names, name) table.insert(names, name)

View file

@ -34,11 +34,15 @@ std::unique_ptr<Content> ContentBuilder::build() {
if (def.variants) { if (def.variants) {
for (auto& variant : def.variants->variants) { for (auto& variant : def.variants->variants) {
variant.rt.solid = variant.model.type == BlockModelType::BLOCK; variant.rt.solid =
variant.model.type == BlockModelType::BLOCK ||
def.explictlySolid;
} }
def.defaults = def.variants->variants.at(0); def.defaults = def.variants->variants.at(0);
} else { } else {
def.defaults.rt.solid = def.defaults.model.type == BlockModelType::BLOCK; def.defaults.rt.solid =
def.defaults.model.type == BlockModelType::BLOCK ||
def.explictlySolid;
} }
const float EPSILON = 0.01f; const float EPSILON = 0.01f;

View file

@ -227,6 +227,7 @@ template<> void ContentUnitLoader<Block>::loadUnit(
root.at("tick-interval").get(def.tickInterval); root.at("tick-interval").get(def.tickInterval);
root.at("overlay-texture").get(def.overlayTexture); root.at("overlay-texture").get(def.overlayTexture);
root.at("translucent").get(def.translucent); root.at("translucent").get(def.translucent);
root.at("solid").get(def.explictlySolid);
if (root.has("fields")) { if (root.has("fields")) {
def.dataStruct = std::make_unique<StructLayout>(); def.dataStruct = std::make_unique<StructLayout>();

View file

@ -274,19 +274,6 @@ void BlocksRenderer::blockAABB(
} }
} }
static bool is_aligned(const glm::vec3& v, float e = 1e-6f) {
if (std::abs(v.y) < e && std::abs(v.z) < e && std::abs(v.x) > e) {
return true;
}
if (std::abs(v.x) < e && std::abs(v.z) < e && std::abs(v.y) > e) {
return true;
}
if (std::abs(v.x) < e && std::abs(v.y) < e && std::abs(v.z) > e) {
return true;
}
return false;
}
void BlocksRenderer::blockCustomModel( void BlocksRenderer::blockCustomModel(
const glm::ivec3& icoord, const Block& block, blockstate states, bool lights, bool ao const glm::ivec3& icoord, const Block& block, blockstate states, bool lights, bool ao
) { ) {
@ -303,6 +290,23 @@ void BlocksRenderer::blockCustomModel(
Z = orient.axes[2]; Z = orient.axes[2];
} }
if (!block.rt.extended) {
glm::ivec3 offsets[6] {
{-1, 0, 0}, {0, -1, 0}, {0, 0, -1},
{1, 0, 0}, {0, 1, 0}, {0, 0, 1},
};
bool culled = true;
for (int i = 0; i < 6; i++) {
if (isOpen(icoord + offsets[i], block, variant)) {
culled = false;
break;
}
}
if (culled) {
return;
}
}
const auto& model = cache.getModel(block.rt.id, block.getVariantIndex(states.userbits)); const auto& model = cache.getModel(block.rt.id, block.getVariantIndex(states.userbits));
for (const auto& mesh : model.meshes) { for (const auto& mesh : model.meshes) {
if (vertexCount + mesh.vertices.size() >= capacity if (vertexCount + mesh.vertices.size() >= capacity
@ -330,8 +334,7 @@ void BlocksRenderer::blockCustomModel(
vp = vp.x * X + vp.y * Y + vp.z * Z; vp = vp.x * X + vp.y * Y + vp.z * Z;
if (!block.rt.extended if (!block.rt.extended
&& !isOpen(glm::floor(coord + vp + 0.5f + n * 1e-3f), block, variant) && !isOpen(glm::floor(coord + vp + 0.5f + n * 1e-3f), block, variant)) {
&& is_aligned(n)) {
continue; continue;
} }

View file

@ -125,9 +125,6 @@ Block::Block(std::string name, const std::string& texture)
void Block::cloneTo(Block& dst) { void Block::cloneTo(Block& dst) {
dst.caption = caption; dst.caption = caption;
for (int i = 0; i < 6; i++) {
dst.defaults = defaults;
}
dst.defaults = defaults; dst.defaults = defaults;
if (variants) { if (variants) {
dst.variants = std::make_unique<Variants>(*variants); dst.variants = std::make_unique<Variants>(*variants);
@ -155,6 +152,7 @@ void Block::cloneTo(Block& dst) {
dst.tickInterval = tickInterval; dst.tickInterval = tickInterval;
dst.overlayTexture = overlayTexture; dst.overlayTexture = overlayTexture;
dst.translucent = translucent; dst.translucent = translucent;
dst.explictlySolid = explictlySolid;
dst.tags = tags; dst.tags = tags;
if (particles) { if (particles) {
dst.particles = std::make_unique<ParticlesPreset>(*particles); dst.particles = std::make_unique<ParticlesPreset>(*particles);

View file

@ -230,6 +230,9 @@ public:
/// @brief Block has semi-transparent texture /// @brief Block has semi-transparent texture
bool translucent = false; bool translucent = false;
/// @brief Explicitly overriding 'solid' property if true assigned
bool explictlySolid = false;
/// @brief Set of block physical hitboxes /// @brief Set of block physical hitboxes
std::vector<AABB> hitboxes {AABB()}; std::vector<AABB> hitboxes {AABB()};