2026-02-17 09:33:57 +01:00

92 lines
2.1 KiB
C++

#pragma once
#include "DeerCore/Tools/Memory.h"
#include "DeerCore/Tools/TypeDefs.h"
#include <string>
#include <unordered_map>
#include <vector>
#define CHUNK_VOXEL_SIZE 16
#ifdef DEER_RENDER
#include "DeerRender/Resource.h"
namespace Deer {
class VoxelBuilder;
class GPUMesh;
} // namespace Deer
#endif
namespace Deer {
struct VoxelType {
std::string id;
};
struct Chunk {
Chunk() {
Voxel voxel = {.voxelTypeId = 0};
voxels_list.push_back(voxel);
voxels_reference_map[voxel] = 0;
}
struct Voxel {
uint32_t voxelTypeId;
bool operator==(const Voxel& other) const noexcept {
return voxelTypeId == other.voxelTypeId;
}
};
struct VoxelHasher {
std::size_t operator()(const Voxel& v) const noexcept {
return std::hash<uint32_t>{}(v.voxelTypeId);
}
};
std::vector<Chunk::Voxel> voxels_list;
std::unordered_map<Chunk::Voxel, uint16_t, VoxelHasher> voxels_reference_map;
uint16_t reference_matrix[CHUNK_VOXEL_SIZE][CHUNK_VOXEL_SIZE][CHUNK_VOXEL_SIZE];
uint16_t getOrCreateVoxelReference(const Voxel& voxel);
Voxel getVoxel(uint16_t voxelReference);
};
class VoxelEnvironment {
public:
VoxelEnvironment();
void modifyVoxel(uint32_t voxelId, int x, int y, int z);
uint32_t getVoxel(int x, int y, int z);
#ifdef DEER_RENDER
public:
Resource<GPUMesh> buildChunk(int x, int y, int z);
Scope<VoxelBuilder> voxelBuilder;
#endif
private:
struct ChunkID {
int x, y, z;
bool operator==(const ChunkID& other) const noexcept {
return x == other.x &&
y == other.y &&
z == other.z;
}
};
struct ChunkIDHasher {
std::size_t operator()(const ChunkID& c) const noexcept {
std::size_t h = 0;
h ^= std::hash<int>{}(c.x) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= std::hash<int>{}(c.y) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= std::hash<int>{}(c.z) + 0x9e3779b9 + (h << 6) + (h >> 2);
return h;
}
};
Chunk* getOrCreateChunk(int x, int y, int z);
Chunk* tryGetChunk(int x, int y, int z);
std::vector<Scope<Chunk>> chunk_list;
std::unordered_map<ChunkID, Chunk*, ChunkIDHasher> chunk_map;
};
} // namespace Deer