Make chunks check adjacent chunks when generating mesh
This commit is contained in:
parent
a516f29be1
commit
4a8bf7d05b
4
Makefile
4
Makefile
@ -1,11 +1,11 @@
|
|||||||
CXX = g++
|
CXX = g++
|
||||||
CXXFLAGS = -g -Isrc
|
CXXFLAGS = -O3 -Isrc
|
||||||
LD = ld
|
LD = ld
|
||||||
|
|
||||||
LINKFLAGS = -lGL -lglfw
|
LINKFLAGS = -lGL -lglfw
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CCFLAGS = -g -Isrc
|
CCFLAGS = -O3 -Isrc
|
||||||
|
|
||||||
XNOECRAFT_CPP_SRCS = $(shell find src/ -name '*.cpp')
|
XNOECRAFT_CPP_SRCS = $(shell find src/ -name '*.cpp')
|
||||||
XNOECRAFT_C_SRCS = $(shell find src/ -name '*.c')
|
XNOECRAFT_C_SRCS = $(shell find src/ -name '*.c')
|
||||||
|
@ -31,12 +31,37 @@ void Chunk::set_block(int x, int y, int z, int block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Chunk::get_block(int x, int y, int z) {
|
int Chunk::get_block(int x, int y, int z) {
|
||||||
if (x < 0 || x >= Chunk::horiz_size)
|
|
||||||
return 0;
|
|
||||||
if (z < 0 || z >= Chunk::horiz_size)
|
|
||||||
return 0;
|
|
||||||
if (y < 0 || y >= Chunk::vert_size)
|
if (y < 0 || y >= Chunk::vert_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (x < 0) {
|
||||||
|
Chunk* c;
|
||||||
|
if (c = World::get_chunk(this->x-1, this->z))
|
||||||
|
return c->get_block(Chunk::horiz_size-1, y, z);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
} else if (x >= Chunk::horiz_size) {
|
||||||
|
Chunk* c;
|
||||||
|
if (c = World::get_chunk(this->x+1, this->z))
|
||||||
|
return c->get_block(0, y, z);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z < 0) {
|
||||||
|
Chunk* c;
|
||||||
|
if (c = World::get_chunk(this->x, this->z-1))
|
||||||
|
return c->get_block(x, y, Chunk::horiz_size-1);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
} else if (z >= Chunk::horiz_size) {
|
||||||
|
Chunk* c;
|
||||||
|
if (c = World::get_chunk(this->x, this->z+1))
|
||||||
|
return c->get_block(x, y, 0);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return this->blocks[y * Chunk::horiz_size * Chunk::horiz_size + z * Chunk::horiz_size + x];
|
return this->blocks[y * Chunk::horiz_size * Chunk::horiz_size + z * Chunk::horiz_size + x];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +102,6 @@ Chunk::~Chunk() {
|
|||||||
|
|
||||||
void Chunk::generate() {
|
void Chunk::generate() {
|
||||||
std::chrono::high_resolution_clock clock;
|
std::chrono::high_resolution_clock clock;
|
||||||
if (mesh_version < current_version) {
|
|
||||||
auto t1 = clock.now();
|
auto t1 = clock.now();
|
||||||
mesh_version++;
|
mesh_version++;
|
||||||
|
|
||||||
@ -170,7 +194,6 @@ void Chunk::generate() {
|
|||||||
std::chrono::duration<double> d = (t2 - t1);
|
std::chrono::duration<double> d = (t2 - t1);
|
||||||
|
|
||||||
std::cerr << "Generated chunk in " << d.count() << " seconds.\n";
|
std::cerr << "Generated chunk in " << d.count() << " seconds.\n";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Chunk::outdated() {
|
bool Chunk::outdated() {
|
||||||
|
@ -6,10 +6,11 @@ FastNoise World::noise;
|
|||||||
World::World() {
|
World::World() {
|
||||||
World::noise = FastNoise();
|
World::noise = FastNoise();
|
||||||
World::noise.SetNoiseType(FastNoise::Perlin);
|
World::noise.SetNoiseType(FastNoise::Perlin);
|
||||||
|
World::world = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::generate_around(int x, int z) {
|
void World::generate_around(int x, int z) {
|
||||||
int world_size_half = this->world_size / 2;
|
int world_size_half = this->world_size;
|
||||||
|
|
||||||
this->world_center = glm::vec2(x, z);
|
this->world_center = glm::vec2(x, z);
|
||||||
|
|
||||||
@ -23,8 +24,6 @@ void World::generate_around(int x, int z) {
|
|||||||
|
|
||||||
for (Chunk* c : this->chunks)
|
for (Chunk* c : this->chunks)
|
||||||
c->generate();
|
c->generate();
|
||||||
|
|
||||||
World::world = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::process(int x, int z) {
|
void World::process(int x, int z) {
|
||||||
@ -34,12 +33,13 @@ void World::process(int x, int z) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<Chunk*> new_chunks;
|
std::vector<Chunk*> new_chunks;
|
||||||
|
std::vector<Chunk*> to_generate;
|
||||||
|
|
||||||
// Player has moved from the world center.
|
// Player has moved from the world center.
|
||||||
|
|
||||||
// Determine world bounds.
|
// Determine world bounds.
|
||||||
|
|
||||||
int world_size_half = this->world_size / 2;
|
int world_size_half = this->world_size;
|
||||||
|
|
||||||
int x_low = x - world_size_half;
|
int x_low = x - world_size_half;
|
||||||
int x_high = x + world_size_half;
|
int x_high = x + world_size_half;
|
||||||
@ -68,20 +68,36 @@ void World::process(int x, int z) {
|
|||||||
|
|
||||||
Chunk* c = new Chunk(x + rel_x, z + rel_z);
|
Chunk* c = new Chunk(x + rel_x, z + rel_z);
|
||||||
new_chunks.push_back(c);
|
new_chunks.push_back(c);
|
||||||
|
to_generate.push_back(c);
|
||||||
this->location_map[std::tuple<int, int>(x + rel_x, z + rel_z)] = c;
|
this->location_map[std::tuple<int, int>(x + rel_x, z + rel_z)] = c;
|
||||||
|
|
||||||
// Remove and delete it.
|
// Remove and delete it.
|
||||||
this->location_map.erase(std::tuple<int, int>(chunk->x, chunk->z));
|
this->location_map.erase(std::tuple<int, int>(chunk->x, chunk->z));
|
||||||
delete chunk;
|
delete chunk;
|
||||||
} else {
|
} else {
|
||||||
// If it's in bounds, keep it.
|
// If it's in bounds, keep it
|
||||||
new_chunks.push_back(chunk);
|
new_chunks.push_back(chunk);
|
||||||
|
|
||||||
|
// Determine if its mesh needs regeneration
|
||||||
|
if (x < this->world_center[0]) {
|
||||||
|
if (chunk->x == x_low+2 || chunk->x == x_high)
|
||||||
|
to_generate.push_back(chunk);
|
||||||
|
} else if (x > this->world_center[0]) {
|
||||||
|
if (chunk->x == x_low || chunk->x == x_high-2)
|
||||||
|
to_generate.push_back(chunk);
|
||||||
|
}
|
||||||
|
if (z < this->world_center[1]) {
|
||||||
|
if (chunk->z == z_low+2 || chunk->z == z_high)
|
||||||
|
to_generate.push_back(chunk);
|
||||||
|
} else if (z > this->world_center[1]) {
|
||||||
|
if (chunk->z == z_low || chunk->z == z_high-2)
|
||||||
|
to_generate.push_back(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through all the chunks and regenerate them if they are outdated
|
// Go through all the chunks and regenerate them if they are outdated
|
||||||
for (Chunk* chunk : new_chunks)
|
for (Chunk* chunk : to_generate)
|
||||||
if (chunk->outdated())
|
|
||||||
chunk->generate();
|
chunk->generate();
|
||||||
|
|
||||||
//new_chunks.swap(this->chunks);
|
//new_chunks.swap(this->chunks);
|
||||||
@ -95,8 +111,8 @@ float World::get_height_at(int x, int z) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Chunk* World::get_chunk(int x, int z) {
|
Chunk* World::get_chunk(int x, int z) {
|
||||||
auto search = this->location_map.find(std::tuple<int, int>(x, z));
|
auto search = World::world->location_map.find(std::tuple<int, int>(x, z));
|
||||||
if (search == this->location_map.end())
|
if (search == World::world->location_map.end())
|
||||||
return 0;
|
return 0;
|
||||||
return std::get<1>(*search);
|
return std::get<1>(*search);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ private:
|
|||||||
|
|
||||||
glm::ivec2 world_center;
|
glm::ivec2 world_center;
|
||||||
|
|
||||||
int world_size = 32;
|
int world_size = 16;
|
||||||
|
|
||||||
static World* world;
|
static World* world;
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ public:
|
|||||||
void process(int x, int z);
|
void process(int x, int z);
|
||||||
|
|
||||||
static float get_height_at(int x, int z);
|
static float get_height_at(int x, int z);
|
||||||
Chunk* get_chunk(int x, int z);
|
static Chunk* get_chunk(int x, int z);
|
||||||
|
|
||||||
void render(Camera* c, Shader* s);
|
void render(Camera* c, Shader* s);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user