96 lines
2.4 KiB
C++
96 lines
2.4 KiB
C++
#ifndef CHUNK_H
|
|
#define CHUNK_H
|
|
|
|
#include <cstdint>
|
|
#include <unordered_map>
|
|
#include <memory>
|
|
#include <array>
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include "Mesh.h"
|
|
|
|
enum class VoxelKind : uint8_t {
|
|
Air,
|
|
Dirt,
|
|
Stone
|
|
};
|
|
|
|
const int CHUNK_SIZE = 32;
|
|
|
|
// Hash function for glm::ivec3 to use with unordered_set
|
|
// Still used in World.h
|
|
namespace std {
|
|
template <>
|
|
struct hash<glm::ivec3> {
|
|
size_t operator()(const glm::ivec3& v) const {
|
|
// Combine hash values of x, y, z components
|
|
size_t h1 = hash<int>()(v.x);
|
|
size_t h2 = hash<int>()(v.y);
|
|
size_t h3 = hash<int>()(v.z);
|
|
|
|
// Use a simple hash combination algorithm
|
|
return h1 ^ (h2 << 1) ^ (h3 << 2);
|
|
}
|
|
};
|
|
}
|
|
|
|
class Chunk {
|
|
public:
|
|
|
|
Chunk();
|
|
|
|
Mesh* getMesh(); // Returns pointer, can be null if not generated yet
|
|
|
|
void generateMesh();
|
|
void regenerateMesh();
|
|
|
|
// Accessors
|
|
inline VoxelKind get(int x, int y, int z) const {
|
|
return data[index(x, y, z)];
|
|
}
|
|
inline VoxelKind get(glm::ivec3 pos) const {
|
|
// std::cout << "Getting Pos (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
|
|
return data[index(pos.x, pos.y, pos.z)];
|
|
}
|
|
|
|
// Mutators
|
|
inline void set(int x, int y, int z, VoxelKind v) {
|
|
data[index(x, y, z)] = v;
|
|
empty_checked = false; // Invalidate cache
|
|
}
|
|
inline void set(glm::ivec3 pos, VoxelKind v) {
|
|
// std::cout << "Setting Pos (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl;
|
|
data[index(pos.x, pos.y, pos.z)] = v;
|
|
empty_checked = false; // Invalidate cache
|
|
}
|
|
|
|
// Other
|
|
inline bool isEmpty() const {
|
|
if (!empty_checked) {
|
|
is_empty = std::all_of(data.begin(), data.end(), [](VoxelKind k){
|
|
return k == VoxelKind::Air;
|
|
});
|
|
empty_checked = true;
|
|
}
|
|
return is_empty;
|
|
}
|
|
|
|
private:
|
|
static constexpr int SIZE = CHUNK_SIZE;
|
|
static constexpr int TOTAL = SIZE * SIZE * SIZE;
|
|
std::array<VoxelKind, TOTAL> data;
|
|
|
|
std::unique_ptr<Mesh> mesh; // Nullable mesh
|
|
mutable bool is_empty = true; // Cache empty state
|
|
mutable bool empty_checked = false; // Track if we've checked
|
|
|
|
static inline constexpr int index(int x, int y, int z) noexcept {
|
|
return x + (y * SIZE) + (z * SIZE * SIZE);
|
|
}
|
|
};
|
|
|
|
#endif // CHUNK_H
|