diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index b1d8d135..cd20249d 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -5,7 +5,7 @@ #include "maths/UVRegion.hpp" #include "constants.hpp" #include "content/Content.hpp" -#include "voxels/ChunksStorage.hpp" +#include "voxels/Chunks.hpp" #include "lighting/Lightmap.hpp" #include "frontend/ContentGfxCache.hpp" #include "settings.hpp" @@ -486,7 +486,7 @@ void BlocksRenderer::render(const voxel* voxels) { } } -void BlocksRenderer::build(const Chunk* chunk, const ChunksStorage* chunks) { +void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) { this->chunk = chunk; voxelsBuffer->setPosition( chunk->x * CHUNK_W - voxelBufferPadding, 0, @@ -515,7 +515,7 @@ MeshData BlocksRenderer::createMesh() { ); } -std::shared_ptr BlocksRenderer::render(const Chunk* chunk, const ChunksStorage* chunks) { +std::shared_ptr BlocksRenderer::render(const Chunk* chunk, const Chunks* chunks) { build(chunk, chunks); const vattr attrs[]{ {3}, {2}, {1}, {0} }; diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index 3890349a..15d68905 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -19,7 +19,7 @@ class Block; class Chunk; class Chunks; class VoxelsVolume; -class ChunksStorage; +class Chunks; class ContentGfxCache; struct EngineSettings; struct UVRegion; @@ -140,8 +140,8 @@ public: BlocksRenderer(size_t capacity, const Content* content, const ContentGfxCache* cache, const EngineSettings* settings); virtual ~BlocksRenderer(); - void build(const Chunk* chunk, const ChunksStorage* chunks); - std::shared_ptr render(const Chunk* chunk, const ChunksStorage* chunks); + void build(const Chunk* chunk, const Chunks* chunks); + std::shared_ptr render(const Chunk* chunk, const Chunks* chunks); MeshData createMesh(); VoxelsVolume* getVoxelsBuffer() const; diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index f5fb7f89..656124da 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -26,7 +26,7 @@ public: {} RendererResult operator()(const std::shared_ptr& chunk) override { - renderer.build(chunk.get(), level->chunksStorage.get()); + renderer.build(chunk.get(), level->chunks.get()); if (renderer.isCancelled()) { return RendererResult { glm::ivec2(chunk->x, chunk->z), true, MeshData()}; @@ -66,7 +66,7 @@ ChunksRenderer::~ChunksRenderer() { std::shared_ptr ChunksRenderer::render(const std::shared_ptr& chunk, bool important) { chunk->flags.modified = false; if (important) { - auto mesh = renderer->render(chunk.get(), level->chunksStorage.get()); + auto mesh = renderer->render(chunk.get(), level->chunks.get()); meshes[glm::ivec2(chunk->x, chunk->z)] = mesh; return mesh; } diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 5937a38e..0ce0e5c1 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -20,6 +20,7 @@ #include "objects/Entities.hpp" #include "world/Level.hpp" #include "world/LevelEvents.hpp" +#include "VoxelsVolume.hpp" #include "Block.hpp" #include "Chunk.hpp" #include "voxel.hpp" @@ -161,7 +162,7 @@ light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) const { return chunk->lightmap.get(lx, y, lz); } -Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) { +Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) const { if (y < 0 || y >= CHUNK_H) { return nullptr; } @@ -173,7 +174,7 @@ Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) { return nullptr; } -Chunk* Chunks::getChunk(int x, int z) { +Chunk* Chunks::getChunk(int x, int z) const { if (auto ptr = areaMap.getIf(x, z)) { return ptr->get(); } @@ -675,6 +676,95 @@ bool Chunks::putChunk(const std::shared_ptr& chunk) { return areaMap.set(chunk->x, chunk->z, chunk); } +// reduce nesting on next modification +// 25.06.2024: not now +// 11.11.2024: not now +void Chunks::getVoxels(VoxelsVolume* volume, bool backlight) const { + const Content* content = level->content; + auto indices = content->getIndices(); + voxel* voxels = volume->getVoxels(); + light_t* lights = volume->getLights(); + int x = volume->getX(); + int y = volume->getY(); + int z = volume->getZ(); + + int w = volume->getW(); + int h = volume->getH(); + int d = volume->getD(); + + int scx = floordiv(x, CHUNK_W); + int scz = floordiv(z, CHUNK_D); + + int ecx = floordiv(x + w, CHUNK_W); + int ecz = floordiv(z + d, CHUNK_D); + + int cw = ecx - scx + 1; + int cd = ecz - scz + 1; + + // cw*cd chunks will be scanned + for (int cz = scz; cz < scz + cd; cz++) { + 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.getLights(); + 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[cidx]; + 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(Lightmap::extract(light, 3))) + ); + } + } + lights[vidx] = light; + } + } + } + } + } + } +} + void Chunks::saveAndClear() { areaMap.clear(); } diff --git a/src/voxels/Chunks.hpp b/src/voxels/Chunks.hpp index fed09f1d..d2440210 100644 --- a/src/voxels/Chunks.hpp +++ b/src/voxels/Chunks.hpp @@ -21,6 +21,7 @@ class WorldFiles; class LevelEvents; class Block; class Level; +class VoxelsVolume; /// Player-centred chunks matrix class Chunks { @@ -55,8 +56,8 @@ public: bool putChunk(const std::shared_ptr& chunk); - Chunk* getChunk(int32_t x, int32_t z); - Chunk* getChunkByVoxel(int32_t x, int32_t y, int32_t z); + Chunk* getChunk(int32_t x, int32_t z) const; + Chunk* getChunkByVoxel(int32_t x, int32_t y, int32_t z) const; voxel* get(int32_t x, int32_t y, int32_t z) const; voxel& require(int32_t x, int32_t y, int32_t z) const; @@ -119,6 +120,8 @@ public: bool isReplaceableBlock(int32_t x, int32_t y, int32_t z); bool isObstacleBlock(int32_t x, int32_t y, int32_t z); + void getVoxels(VoxelsVolume* volume, bool backlight = false) const; + void setCenter(int32_t x, int32_t z); void resize(uint32_t newW, uint32_t newD); diff --git a/src/voxels/ChunksStorage.cpp b/src/voxels/ChunksStorage.cpp index 75b37b9e..596c4b78 100644 --- a/src/voxels/ChunksStorage.cpp +++ b/src/voxels/ChunksStorage.cpp @@ -14,7 +14,6 @@ #include "world/World.hpp" #include "Block.hpp" #include "Chunk.hpp" -#include "VoxelsVolume.hpp" static debug::Logger logger("chunks-storage"); @@ -84,93 +83,3 @@ std::shared_ptr ChunksStorage::create(int x, int z) { chunk->blocksMetadata = regions.getBlocksData(chunk->x, chunk->z); return chunk; } - -// reduce nesting on next modification -// 25.06.2024: not now -// TODO: move to Chunks for performance improvement -void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const { - const Content* content = level->content; - auto indices = content->getIndices(); - voxel* voxels = volume->getVoxels(); - light_t* lights = volume->getLights(); - int x = volume->getX(); - int y = volume->getY(); - int z = volume->getZ(); - - int w = volume->getW(); - int h = volume->getH(); - int d = volume->getD(); - - int scx = floordiv(x, CHUNK_W); - int scz = floordiv(z, CHUNK_D); - - int ecx = floordiv(x + w, CHUNK_W); - int ecz = floordiv(z + d, CHUNK_D); - - int cw = ecx - scx + 1; - int cd = ecz - scz + 1; - - // cw*cd chunks will be scanned - for (int cz = scz; cz < scz + cd; cz++) { - for (int cx = scx; cx < scx + cw; cx++) { - const auto& found = chunksMap.find(glm::ivec2(cx, cz)); - if (found == chunksMap.end()) { - // 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 { - auto& chunk = found->second; - const voxel* cvoxels = chunk->voxels; - const light_t* clights = chunk->lightmap.getLights(); - 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[cidx]; - 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(Lightmap::extract(light, 3))) - ); - } - } - lights[vidx] = light; - } - } - } - } - } - } -} diff --git a/src/voxels/ChunksStorage.hpp b/src/voxels/ChunksStorage.hpp index 887af1ca..35fff6c1 100644 --- a/src/voxels/ChunksStorage.hpp +++ b/src/voxels/ChunksStorage.hpp @@ -11,7 +11,6 @@ class Chunk; class Level; -class VoxelsVolume; class ChunksStorage { Level* level; @@ -23,6 +22,5 @@ public: std::shared_ptr get(int x, int z) const; void store(const std::shared_ptr& chunk); void remove(int x, int y); - void getVoxels(VoxelsVolume* volume, bool backlight = false) const; std::shared_ptr create(int x, int z); }; diff --git a/src/world/generator/VoxelFragment.cpp b/src/world/generator/VoxelFragment.cpp index 2d287b0b..f36824b0 100644 --- a/src/world/generator/VoxelFragment.cpp +++ b/src/world/generator/VoxelFragment.cpp @@ -26,7 +26,7 @@ std::unique_ptr VoxelFragment::create( if (crop) { VoxelsVolume volume(size.x, size.y, size.z); volume.setPosition(start.x, start.y, start.z); - level->chunksStorage->getVoxels(&volume); + level->chunks->getVoxels(&volume); auto end = start + size; @@ -51,7 +51,7 @@ std::unique_ptr VoxelFragment::create( VoxelsVolume volume(size.x, size.y, size.z); volume.setPosition(start.x, start.y, start.z); - level->chunksStorage->getVoxels(&volume); + level->chunks->getVoxels(&volume); auto volVoxels = volume.getVoxels(); std::vector voxels(size.x * size.y * size.z);