diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 377811329..6fe0f2091 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -251,6 +251,10 @@ void BlocksRenderer::blockAABB( Z = orient.axes[2]; orient.transform(hitbox); } + if (block->rt.extended) { + meshAABB.addPoint(coord + hitbox.max()); + meshAABB.addPoint(coord + hitbox.min()); + } coord -= glm::vec3(0.5f) - hitbox.center(); if (ao) { @@ -687,6 +691,7 @@ SortingMeshData BlocksRenderer::renderTranslucent( void BlocksRenderer::build( const Chunk* chunk, const VoxelsRenderVolume& volume ) { + meshAABB = AABB(glm::vec3(CHUNK_W, CHUNK_H, CHUNK_D)); this->chunk = chunk; this->voxelsBuffer = &volume; if (voxelsBuffer->pickBlockId( @@ -767,7 +772,8 @@ ChunkMeshData BlocksRenderer::createMesh() { sizeof(ChunkVertex::ATTRIBUTES) / sizeof(VertexAttribute) ) ), - std::move(sortingMesh) + std::move(sortingMesh), + std::move(meshAABB) }; } @@ -786,7 +792,7 @@ ChunkMesh BlocksRenderer::render( IndexBufferData {indexBuffer.get(), indexCount}, IndexBufferData {denseIndexBuffer.get(), denseIndexCount}, } - ), std::move(sortingMesh), nullptr}; + ), std::move(sortingMesh), nullptr, std::move(meshAABB)}; } size_t BlocksRenderer::getMemoryConsumption() const { diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index 8af7fab7a..94b708a54 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -6,6 +6,7 @@ #include "voxels/Chunk.hpp" #include "voxels/VoxelsVolume.hpp" #include "maths/util.hpp" +#include "maths/aabb.hpp" #include "commons.hpp" #include "settings.hpp" @@ -56,6 +57,7 @@ private: bool cancelled = false; bool densePass = false; bool denseRender = false; + AABB meshAABB {}; const Chunk* chunk = nullptr; const VoxelsRenderVolume* voxelsBuffer = nullptr; diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index b7ffa3715..8498091c9 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -81,7 +81,9 @@ ChunksRenderer::ChunksRenderer( meshes[result.key] = ChunkMesh { std::move(chunk), std::move(meshData.sortingMesh), - nullptr}; + nullptr, + std::move(meshData.meshAABB) + }; } inwork.erase(result.key); }, @@ -120,7 +122,7 @@ std::shared_ptr ChunksRenderer::prepareVoxelsVolume( return voxelsBuffer; } -const Mesh* ChunksRenderer::render( +const ChunkMesh* ChunksRenderer::render( const std::shared_ptr& chunk, bool important, bool lowPriority ) { glm::ivec2 key(chunk->x, chunk->z); @@ -130,7 +132,7 @@ const Mesh* ChunksRenderer::render( auto voxelsBuffer = prepareVoxelsVolume(*chunk); mesh = renderer->render(chunk.get(), *voxelsBuffer); meshes[key] = std::move(mesh); - return meshes[key].mesh.get(); + return &meshes[key]; } if (inwork.find(key) != inwork.end() || ((inwork.size() >= threadPool.getWorkersCount() || @@ -158,7 +160,7 @@ void ChunksRenderer::clear() { threadPool.clearQueue(); } -const Mesh* ChunksRenderer::getOrRender( +const ChunkMesh* ChunksRenderer::getOrRender( const std::shared_ptr& chunk, bool important, bool lowPriority ) { auto found = meshes.find(glm::ivec2(chunk->x, chunk->z)); @@ -168,7 +170,7 @@ const Mesh* ChunksRenderer::getOrRender( if (chunk->flags.modified && chunk->flags.lighted) { render(chunk, important, lowPriority); } - return found->second.mesh.get(); + return &found->second; } void ChunksRenderer::update() { @@ -211,16 +213,23 @@ const Mesh* ChunksRenderer::retrieveChunk( chunk->updateHeights(); } if (culling) { - glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D); + const auto& meshAABB = mesh->meshAABB; + auto aabbMin = meshAABB.min(); + auto aabbMax = meshAABB.max(); + glm::vec3 min( + chunk->x * CHUNK_W + std::min(0.0f, aabbMin.x), + chunk->bottom, + chunk->z * CHUNK_D + std::min(0.0f, aabbMin.z) + ); glm::vec3 max( - chunk->x * CHUNK_W + CHUNK_W, + chunk->x * CHUNK_W + aabbMax.x, chunk->top, - chunk->z * CHUNK_D + CHUNK_D + chunk->z * CHUNK_D + aabbMax.z ); if (!frustum.isBoxVisible(min, max)) return nullptr; } - return mesh; + return mesh->mesh.get(); } void ChunksRenderer::drawShadowsPass( diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index 4fc88ff69..5e6783d97 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -71,13 +71,13 @@ public: ); virtual ~ChunksRenderer(); - const Mesh* render( + const ChunkMesh* render( const std::shared_ptr& chunk, bool important, bool lowPriority ); void unload(const Chunk* chunk); void clear(); - const Mesh* getOrRender( + const ChunkMesh* getOrRender( const std::shared_ptr& chunk, bool important, bool lowPriority ); diff --git a/src/graphics/render/commons.hpp b/src/graphics/render/commons.hpp index 41b352bac..52f7d5a95 100644 --- a/src/graphics/render/commons.hpp +++ b/src/graphics/render/commons.hpp @@ -2,6 +2,7 @@ #include "constants.hpp" #include "graphics/core/MeshData.hpp" +#include "maths/aabb.hpp" #include "util/Buffer.hpp" #include @@ -45,12 +46,14 @@ struct SortingMeshData { struct ChunkMeshData { MeshData mesh; SortingMeshData sortingMesh; + AABB meshAABB; }; struct ChunkMesh { std::unique_ptr> mesh; SortingMeshData sortingMeshData; std::unique_ptr > sortedMesh; + AABB meshAABB; }; inline constexpr int VOXELS_BUFFER_PADDING = 2;