move Chunks from Level to Player

This commit is contained in:
MihailRis
2024-12-17 19:40:00 +03:00
parent b7664b4188
commit 1c18c02092
40 changed files with 450 additions and 220 deletions
+8
View File
@@ -38,6 +38,14 @@ Chunks::Chunks(
});
}
void Chunks::configure(int32_t x, int32_t z, uint32_t radius) {
setCenter(x, z);
uint32_t diameter = radius * 2LL;
if (getWidth() != diameter) {
resize(diameter, diameter);
}
}
voxel* Chunks::get(int32_t x, int32_t y, int32_t z) const {
return blocks_agent::get(*this, x, y, z);
}
+2
View File
@@ -50,6 +50,8 @@ public:
);
~Chunks() = default;
void configure(int32_t x, int32_t z, uint32_t radius);
bool putChunk(const std::shared_ptr<Chunk>& chunk);
Chunk* getChunk(int32_t x, int32_t z) const;
+5
View File
@@ -10,6 +10,7 @@
#include "lighting/Lightmap.hpp"
#include "maths/voxmaths.hpp"
#include "objects/Entities.hpp"
#include "voxels/blocks_agent.hpp"
#include "typedefs.hpp"
#include "world/Level.hpp"
#include "world/World.hpp"
@@ -198,3 +199,7 @@ void GlobalChunks::saveAll() {
void GlobalChunks::putChunk(std::shared_ptr<Chunk> chunk) {
chunksMap[keyfrom(chunk->x, chunk->z)] = std::move(chunk);
}
const AABB* GlobalChunks::isObstacleAt(float x, float y, float z) const {
return blocks_agent::is_obstacle_at(*this, x, y, z);
}
+3
View File
@@ -11,6 +11,7 @@
class Chunk;
class Level;
struct AABB;
class ContentIndices;
class GlobalChunks {
@@ -51,6 +52,8 @@ public:
void putChunk(std::shared_ptr<Chunk> chunk);
const AABB* isObstacleAt(float x, float y, float z) const;
inline Chunk* getChunk(int cx, int cz) const {
const auto& found = chunksMap.find(keyfrom(cx, cz));
if (found == chunksMap.end()) {
+102
View File
@@ -265,3 +265,105 @@ voxel* blocks_agent::raycast(
) {
return raycast_blocks(chunks, start, dir, maxDist, end, norm, iend, filter);
}
// reduce nesting on next modification
// 25.06.2024: not now
// 11.11.2024: not now
template <class Storage>
inline void get_voxels_impl(
const Storage& chunks, VoxelsVolume* volume, bool backlight
) {
const auto& blocks = chunks.getContentIndices().blocks;
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<CHUNK_W>(x);
int scz = floordiv<CHUNK_D>(z);
int ecx = floordiv<CHUNK_W>(x + w);
int ecz = floordiv<CHUNK_D>(z + 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 = get_chunk(chunks, 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 = 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;
}
}
}
}
}
}
}
void blocks_agent::get_voxels(
const Chunks& chunks, VoxelsVolume* volume, bool backlight
) {
get_voxels_impl(chunks, volume, backlight);
}
void blocks_agent::get_voxels(
const GlobalChunks& chunks, VoxelsVolume* volume, bool backlight
) {
get_voxels_impl(chunks, volume, backlight);
}
+41
View File
@@ -6,6 +6,7 @@
#include "Block.hpp"
#include "Chunk.hpp"
#include "Chunks.hpp"
#include "VoxelsVolume.hpp"
#include "GlobalChunks.hpp"
#include "constants.hpp"
#include "typedefs.hpp"
@@ -17,6 +18,8 @@
#include <stdexcept>
#include <glm/glm.hpp>
struct AABB;
namespace blocks_agent {
/// @brief Get specified chunk.
@@ -432,4 +435,42 @@ voxel* raycast(
std::set<blockid_t> filter
);
void get_voxels(const Chunks& chunks, VoxelsVolume* volume, bool backlight=false);
void get_voxels(const GlobalChunks& chunks, VoxelsVolume* volume, bool backlight=false);
template <class Storage>
inline const AABB* is_obstacle_at(const Storage& chunks, float x, float y, float z) {
int ix = std::floor(x);
int iy = std::floor(y);
int iz = std::floor(z);
voxel* v = get(chunks, ix, iy, iz);
if (v == nullptr) {
if (iy >= CHUNK_H) {
return nullptr;
} else {
static const AABB empty;
return &empty;
}
}
const auto& def = chunks.getContentIndices().blocks.require(v->id);
if (def.obstacle) {
glm::ivec3 offset {};
if (v->state.segment) {
glm::ivec3 point(ix, iy, iz);
offset = seek_origin(chunks, point, def, v->state) - point;
}
const auto& boxes =
def.rotatable ? def.rt.hitboxes[v->state.rotation] : def.hitboxes;
for (const auto& hitbox : boxes) {
if (hitbox.contains(
{x - ix - offset.x, y - iy - offset.y, z - iz - offset.z}
)) {
return &hitbox;
}
}
}
return nullptr;
}
} // blocks_agent