minecraftvulkan/src/chunk.cpp

154 lines
3.7 KiB
C++
Raw Normal View History

2022-09-25 23:05:56 +00:00
#include "chunk.hpp"
#include "xe_engine.hpp"
namespace app {
static std::map<std::pair<int32_t, int32_t>, Chunk*> chunks{};
2022-09-25 23:05:56 +00:00
Chunk::Chunk(int32_t gridX, int32_t gridZ, uint32_t world_seed)
2022-09-25 23:05:56 +00:00
: world_seed{world_seed},
chunk_seed{(world_seed * gridX) + (world_seed * gridZ) / 2},
gridX{gridX},
gridZ{gridZ} {
generate();
}
Chunk* Chunk::newChunk(int32_t gridX, int32_t gridZ, uint32_t world_seed) {
2022-09-26 15:03:27 +00:00
Chunk* chunk = new Chunk(gridX, gridZ, world_seed);
chunks[{gridX, gridZ}] = std::move(chunk);
return chunks[{gridX, gridZ}];
2022-09-25 23:05:56 +00:00
}
Chunk* Chunk::getChunk(int32_t gridX, int32_t gridZ) {
2022-09-26 15:03:27 +00:00
if(chunks.count({gridX, gridZ})) {
return chunks[{gridX, gridZ}];
} else {
return NULL;
2022-09-25 23:05:56 +00:00
}
}
uint8_t Chunk::getBlock(int32_t x, int32_t y, int32_t z) {
2022-09-26 15:03:27 +00:00
if(y > 256) return AIR;
if(y < 0) return INVALID;
2022-09-25 23:05:56 +00:00
int chunkX = gridX;
int chunkZ = gridZ;
if(x < 0) {
chunkX--;
2022-09-26 15:03:27 +00:00
} else if(x > 15) {
chunkX++;
2022-09-25 23:05:56 +00:00
}
if(z < 0) {
chunkZ--;
2022-09-26 15:03:27 +00:00
} else if(z > 15) {
chunkZ++;
2022-09-25 23:05:56 +00:00
}
x = (x+16)%16;
z = (z+16)%16;
2022-09-25 23:05:56 +00:00
if(chunkX == gridX && chunkZ == gridZ) {
2022-09-26 15:03:27 +00:00
int index = x + (z * 16) + (y * 256);
2022-09-25 23:05:56 +00:00
return blocks[index];
} else {
Chunk* chunk = getChunk(chunkX, chunkZ);
if(chunk == NULL) {
2022-09-26 15:03:27 +00:00
return INVALID;
2022-09-25 23:05:56 +00:00
} else {
2022-09-26 15:03:27 +00:00
int index = x + (z * 16) + (y * 256);
2022-09-25 23:05:56 +00:00
return chunk->blocks[index];
}
}
}
void Chunk::setBlock(int32_t x, int32_t y, int32_t z, uint8_t block) {
2022-09-26 15:03:27 +00:00
int index = x + (z * 16) + (y * 256);
2022-09-25 23:05:56 +00:00
blocks[index] = block;
}
2022-09-26 15:03:27 +00:00
void Chunk::reset() {
for(const auto &[key, chunk]: chunks) {
delete chunk;
}
chunks.clear();
}
std::shared_ptr<xe::Model> Chunk::getMesh() {
if(reloadRequired) {
delete chunkMesh.get();
xe::Model::Builder builder{};
builder.vertexData = vertexData;
2022-09-26 22:03:07 +00:00
builder.vertexSize = 36;
2022-09-26 15:03:27 +00:00
chunkMesh = std::make_shared<xe::Model>(xe::Engine::getInstance()->getDevice(), builder);
}
return chunkMesh;
2022-09-25 23:05:56 +00:00
}
void Chunk::createMeshAsync() {
if(working) return;
// worker = std::thread(createMesh);
}
void Chunk::createMesh() {
working = true;
vertexData.clear();
for(int32_t x=0;x<16;x++) {
for(int32_t y=0; y<256; y++) {
for(int32_t z=0; z<16; z++) {
2022-09-25 23:05:56 +00:00
uint8_t block = getBlock(x,y,z);
if(block == AIR) continue;
if(getBlock(x+1,y,z) == AIR) {
addVerticies(0, x, y, z);
}
if(getBlock(x-1,y,z) == AIR) {
addVerticies(1, x, y, z);
}
if(getBlock(x,y+1,z) == AIR) {
addVerticies(2, x, y, z);
}
if(getBlock(x,y-1,z) == AIR) {
addVerticies(3, x, y, z);
}
if(getBlock(x,y,z+1) == AIR) {
addVerticies(4, x, y, z);
}
if(getBlock(x,y,z-1) == AIR) {
addVerticies(5, x, y, z);
}
}
}
}
working = false;
reloadRequired = true;
}
void Chunk::addVerticies(uint8_t side, int32_t x, int32_t y, int32_t z) {
2022-09-25 23:05:56 +00:00
for(int i = 0; i < 6; i ++) {
vertexData.push_back(px[side * 6 + i][0] + x);
vertexData.push_back(px[side * 6 + i][1] + y);
vertexData.push_back(px[side * 6 + i][2] + z);
vertexData.push_back(nm[side][0]);
vertexData.push_back(nm[side][1]);
vertexData.push_back(nm[side][2]);
vertexData.push_back(uv[i][0]);
vertexData.push_back(uv[i][1]);
2022-09-26 22:03:07 +00:00
vertexData.push_back(0.f);
2022-09-25 23:05:56 +00:00
}
}
void Chunk::generate() {
blocks.resize(16*16*256);
2022-09-26 15:03:27 +00:00
const PerlinNoise perlin{world_seed};
2022-09-25 23:05:56 +00:00
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
2022-09-26 15:03:27 +00:00
int height = perlin.octave2D_01((( x + gridX * 16) * 0.01), ((z + gridZ * 16) * 0.01), 4) * 10;
2022-09-25 23:05:56 +00:00
for(int y = 0; y < 256; y++) {
if(y <= height)
setBlock(x, y, z, DIRT);
else
setBlock(x, y, z, AIR);
}
}
}
}
}