stabilize delays of chunks meshes building

This commit is contained in:
MihailRis 2025-12-29 20:41:47 +03:00
parent f47ccd5f30
commit 88544183d0
13 changed files with 335 additions and 191 deletions

View file

@ -335,26 +335,106 @@ bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
return false;
}
// reduce nesting on next modification
// 25.06.2024: not now
// 11.11.2024: not now
// 12.12.2025: not now
void Chunks::getVoxels(VoxelsVolume& volume, bool backlight, int top) const {
voxel* voxels = volume.getVoxels();
light_t* lights = volume.getLights();
int x = volume.getX();
int y = volume.getY();
int z = volume.getZ();
static void fill_with_void(
voxel* voxels,
light_t* lights,
const glm::ivec3& pos,
const glm::ivec3& size,
int cx,
int cz
) {
for (int ly = pos.y; ly < pos.y + size.y; ly++) {
for (int lz = std::max(pos.z, cz * CHUNK_D);
lz < std::min(pos.z + size.z, (cz + 1) * CHUNK_D);
lz++) {
for (int lx = std::max(pos.x, cx * CHUNK_W);
lx < std::min(pos.x + size.x, (cx + 1) * CHUNK_W);
lx++) {
uint idx = vox_index(
lx - pos.x, ly - pos.y, lz - pos.z, size.x, size.z
);
voxels[idx].id = BLOCK_VOID;
lights[idx] = 0;
}
}
}
}
int w = volume.getW();
int h = std::min<int>(volume.getH(), top);
int d = volume.getD();
static inline light_t apply_backlight(light_t light) {
return Lightmap::combine(
std::min(15, Lightmap::extract(light, 0) + 1),
std::min(15, Lightmap::extract(light, 1) + 1),
std::min(15, Lightmap::extract(light, 2) + 1),
std::min(15, static_cast<int>(Lightmap::extract(light, 3)))
);
}
int scx = floordiv<CHUNK_W>(x);
int scz = floordiv<CHUNK_D>(z);
#include "util/timeutil.hpp"
int ecx = floordiv<CHUNK_W>(x + w);
int ecz = floordiv<CHUNK_D>(z + d);
// ugly
static inline void sample_chunk(
const decltype(ContentIndices::blocks)& defs,
const Chunk& chunk,
voxel* voxels,
light_t* lights,
const glm::ivec3& pos,
const glm::ivec3& size,
int cx,
int cz,
bool backlight
) {
const auto cvoxels = chunk.voxels;
const auto clights = chunk.lightmap ? chunk.lightmap->getLights() : nullptr;
for (int ly = pos.y; ly < pos.y + size.y; ly++) {
for (int lz = std::max(pos.z, cz * CHUNK_D);
lz < std::min(pos.z + size.z, (cz + 1) * CHUNK_D);
lz++) {
for (int lx = std::max(pos.x, cx * CHUNK_W);
lx < std::min(pos.x + size.x, (cx + 1) * CHUNK_W);
lx++) {
uint vidx = vox_index(
lx - pos.x, ly - pos.y, lz - pos.z, size.x, size.z
);
uint cidx = vox_index(
lx - cx * CHUNK_W,
ly,
lz - cz * CHUNK_D,
CHUNK_W,
CHUNK_D
);
auto& vox = voxels[vidx];
vox = cvoxels[cidx];
light_t light = clights ? clights[cidx]
: Lightmap::SUN_LIGHT_ONLY;
// todo: move to the BlocksRenderer
if (backlight) {
const auto block = defs.get(vox.id);
if (block && block->lightPassing) {
light = apply_backlight(light);
}
}
lights[vidx] = light;
}
}
}
}
void Chunks::getVoxels(
voxel* voxels,
light_t* lights,
const glm::ivec3& pos,
const glm::ivec3& size,
bool backlight,
int top
) const {
timeutil::ScopeLogTimer log(111);
int h = std::min<int>(size.y, top);
int scx = floordiv<CHUNK_W>(pos.x);
int scz = floordiv<CHUNK_D>(pos.z);
int ecx = floordiv<CHUNK_W>(pos.x + size.x);
int ecz = floordiv<CHUNK_D>(pos.z + size.z);
int cw = ecx - scx + 1;
int cd = ecz - scz + 1;
@ -364,67 +444,37 @@ void Chunks::getVoxels(VoxelsVolume& volume, bool backlight, int top) const {
for (int cx = scx; cx < scx + cw; cx++) {
const auto chunk = getChunk(cx, cz);
if (chunk == nullptr) {
// no chunk loaded -> filling with BLOCK_VOID
for (int ly = y; ly < y + h; ly++) {
for (int lz = std::max(z, cz * CHUNK_D);
lz < std::min(z + d, (cz + 1) * CHUNK_D);
lz++) {
for (int lx = std::max(x, cx * CHUNK_W);
lx < std::min(x + w, (cx + 1) * CHUNK_W);
lx++) {
uint idx = vox_index(lx - x, ly - y, lz - z, w, d);
voxels[idx].id = BLOCK_VOID;
lights[idx] = 0;
}
}
}
} else {
const voxel* cvoxels = chunk->voxels;
const light_t* clights =
chunk->lightmap ? chunk->lightmap->getLights() : nullptr;
for (int ly = y; ly < y + h; ly++) {
for (int lz = std::max(z, cz * CHUNK_D);
lz < std::min(z + d, (cz + 1) * CHUNK_D);
lz++) {
for (int lx = std::max(x, cx * CHUNK_W);
lx < std::min(x + w, (cx + 1) * CHUNK_W);
lx++) {
uint vidx = vox_index(lx - x, ly - y, lz - z, w, d);
uint cidx = vox_index(
lx - cx * CHUNK_W,
ly,
lz - cz * CHUNK_D,
CHUNK_W,
CHUNK_D
);
voxels[vidx] = cvoxels[cidx];
light_t light = clights ? clights[cidx]
: Lightmap::SUN_LIGHT_ONLY;
if (backlight) {
const auto block =
indices.blocks.get(voxels[vidx].id);
if (block && block->lightPassing) {
light = Lightmap::combine(
std::min(15,
Lightmap::extract(light, 0) + 1),
std::min(15,
Lightmap::extract(light, 1) + 1),
std::min(15,
Lightmap::extract(light, 2) + 1),
std::min(15,
static_cast<int>(Lightmap::extract(light, 3)))
);
}
}
lights[vidx] = light;
}
}
}
fill_with_void(
voxels, lights, pos, {size.x, h, size.z}, cx, cz
);
continue;
}
sample_chunk(
indices.blocks,
*chunk,
voxels,
lights,
pos,
{size.x, h, size.z},
cx,
cz,
backlight
);
}
}
}
void Chunks::getVoxels(VoxelsVolume& volume, bool backlight, int top) const {
getVoxels(
volume.getVoxels(),
volume.getLights(),
{volume.getX(), volume.getY(), volume.getZ()},
{volume.getW(), volume.getH(), volume.getD()},
backlight,
top
);
}
void Chunks::saveAndClear() {
areaMap.clear();
}