2021-11-15 20:58:13 -05:00
|
|
|
|
#include "world.h"
|
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
World::World() {}
|
2021-11-15 20:58:13 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
World::~World() {}
|
2021-11-15 20:58:13 -05:00
|
|
|
|
|
|
|
|
|
Array2d<Chunk*>& World::GetChunks() { return m_chunks; }
|
2021-11-15 21:39:50 -05:00
|
|
|
|
|
|
|
|
|
Chunk* World::ChunkAt(float x, float y, float z) const {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
int cx = (int)x / CHUNK_SIZE_X;
|
|
|
|
|
int cz = (int)z / CHUNK_SIZE_Z;
|
2021-11-15 21:39:50 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
if (x < 0 || y < 0 || z < 0 ||
|
|
|
|
|
x >= WORLD_SIZE_X * CHUNK_SIZE_X ||
|
|
|
|
|
z >= CHUNK_SIZE_Z * WORLD_SIZE_Y ||
|
|
|
|
|
y > CHUNK_SIZE_Y)
|
|
|
|
|
return 0;
|
2021-11-15 21:39:50 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
return m_chunks.Get(cx, cz);
|
2021-11-15 21:39:50 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Chunk* World::ChunkAt(const Vector3f& pos) const { return ChunkAt(pos.x, pos.y, pos.z); }
|
|
|
|
|
|
|
|
|
|
BlockType World::BlockAt(float x, float y, float z, BlockType defaultBlockType) const {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
Chunk* c = ChunkAt(x, y, z);
|
2021-11-15 21:39:50 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
if (!c)
|
|
|
|
|
return defaultBlockType;
|
2021-11-15 21:39:50 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
int bx = (int)x % CHUNK_SIZE_X;
|
|
|
|
|
int by = (int)y % CHUNK_SIZE_Y;
|
|
|
|
|
int bz = (int)z % CHUNK_SIZE_Z;
|
2021-11-15 21:39:50 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
return c->GetBlock(bx, by, bz);
|
2021-11-15 21:39:50 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BlockType World::BlockAt(const Vector3f& pos, BlockType defaultBlockType) const {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
return BlockAt(pos.x, pos.y, pos.z, defaultBlockType);
|
2021-11-15 21:39:50 -05:00
|
|
|
|
}
|
2021-11-30 19:55:11 -05:00
|
|
|
|
|
2021-12-01 21:21:45 -05:00
|
|
|
|
void World::TransposeWorld(Player& player) {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
int x = 0;
|
|
|
|
|
int y = 0;
|
|
|
|
|
|
|
|
|
|
if (player.GetPosition().x > (WORLD_SIZE_X * CHUNK_SIZE_X) * .66f) ++x;
|
|
|
|
|
else if (player.GetPosition().x < (WORLD_SIZE_X * CHUNK_SIZE_X) * .33f) --x;
|
|
|
|
|
if (player.GetPosition().z > (WORLD_SIZE_Y * CHUNK_SIZE_Z) * .66f) ++y;
|
|
|
|
|
else if (player.GetPosition().z < (WORLD_SIZE_Y * CHUNK_SIZE_Z) * .33f) --y;
|
|
|
|
|
|
|
|
|
|
if (!x && !y) return;
|
|
|
|
|
|
|
|
|
|
if (x > 0) {
|
|
|
|
|
for (int ax = 0; ax < WORLD_SIZE_X; ++ax)
|
|
|
|
|
for (int ay = 0; ay < WORLD_SIZE_Y; ++ay)
|
|
|
|
|
if (ax - x >= 0)
|
|
|
|
|
m_chunks.Set(ax - x, ay,
|
|
|
|
|
m_chunks.Remove(ax, ay));
|
|
|
|
|
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
|
|
|
|
|
}
|
|
|
|
|
else if (x < 0) {
|
|
|
|
|
for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax)
|
|
|
|
|
for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay)
|
|
|
|
|
if (ax - x < WORLD_SIZE_X)
|
|
|
|
|
m_chunks.Set(ax - x, ay,
|
|
|
|
|
m_chunks.Remove(ax, ay));
|
|
|
|
|
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
|
|
|
|
|
}
|
2021-12-01 22:06:47 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
if (y > 0) {
|
|
|
|
|
for (int ax = 0; ax < WORLD_SIZE_X; ++ax)
|
|
|
|
|
for (int ay = 0; ay < WORLD_SIZE_Y; ++ay)
|
|
|
|
|
if (ay - y >= 0)
|
|
|
|
|
m_chunks.Set(ax, ay - y,
|
|
|
|
|
m_chunks.Remove(ax, ay));
|
|
|
|
|
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
|
|
|
|
|
}
|
|
|
|
|
else if (y < 0) {
|
|
|
|
|
for (int ax = WORLD_SIZE_X - 1; ax >= 0; --ax)
|
|
|
|
|
for (int ay = WORLD_SIZE_Y - 1; ay >= 0; --ay)
|
|
|
|
|
if (ay - y < WORLD_SIZE_Y)
|
|
|
|
|
m_chunks.Set(ax, ay - y,
|
|
|
|
|
m_chunks.Remove(ax, ay));
|
|
|
|
|
else if (m_chunks.Get(ax, ay)) m_tbDeleted.emplace_back(m_chunks.Remove(ax, ay));
|
|
|
|
|
}
|
2021-12-01 22:06:47 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
m_center[0] += x; m_center[1] += y;
|
|
|
|
|
player.Teleport(x, y);
|
|
|
|
|
}
|
2021-12-01 22:06:47 -05:00
|
|
|
|
|
2021-12-03 11:49:59 -05:00
|
|
|
|
void World::CleanUpWorld(int& deleteframes, bool clear = false) {
|
|
|
|
|
if (clear) {
|
|
|
|
|
while (m_tbDeleted.size() > 0) {
|
|
|
|
|
delete m_tbDeleted.back();
|
|
|
|
|
m_tbDeleted.pop_back();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!m_tbDeleted.empty() && !deleteframes) {
|
|
|
|
|
delete m_tbDeleted.back();
|
|
|
|
|
m_tbDeleted.pop_back();
|
|
|
|
|
deleteframes = FRAMES_DELETE_CHUNKS;
|
|
|
|
|
}
|
|
|
|
|
std::cout << "Chunk Write Buffer: " << m_tbDeleted.size() << std::endl;
|
2021-12-01 22:06:47 -05:00
|
|
|
|
}
|
2021-12-02 18:12:35 -05:00
|
|
|
|
|
|
|
|
|
void World::GetScope(int& x, int& y) {
|
|
|
|
|
x = m_center[0];
|
|
|
|
|
y = m_center[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void World::Update(int& rendercount, int& badhitcount, Player& player, Transformation& world, Shader& shader, TextureAtlas& atlas, Perlin& perlin, BlockInfo* blockinfo[BTYPE_LAST]) {
|
|
|
|
|
atlas.Bind();
|
|
|
|
|
RenderWorld(rendercount, badhitcount, player, world, shader);
|
2021-12-03 11:49:59 -05:00
|
|
|
|
TransposeWorld(player);
|
2021-12-02 18:12:35 -05:00
|
|
|
|
UpdateWorld(player, perlin, blockinfo);
|
|
|
|
|
shader.Disable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool World::GenerateChunk(int chx, int chy, Perlin& perlin) {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
|
2021-12-02 18:12:35 -05:00
|
|
|
|
if (chx < WORLD_SIZE_X * CHUNK_SIZE_X && chy < WORLD_SIZE_Y * CHUNK_SIZE_Z &&
|
|
|
|
|
chx >= 0 && chy >= 0)
|
|
|
|
|
if (!ChunkAt(chx, 1, chy)) {
|
|
|
|
|
|
|
|
|
|
for (int index = 0; index < m_tbDeleted.size(); ++index) { // V<>rifie l'existence d'un chunk dans le buffer de suppression avec sa position.
|
|
|
|
|
int x, y;
|
2021-12-03 11:49:59 -05:00
|
|
|
|
|
|
|
|
|
if (&m_tbDeleted.at(index)) {
|
|
|
|
|
m_tbDeleted.at(index)->GetPosition(x, y);
|
|
|
|
|
if (chx / CHUNK_SIZE_X + m_center[0] == x &&
|
2021-12-02 18:12:35 -05:00
|
|
|
|
chy / CHUNK_SIZE_Z + m_center[1] == y) {
|
|
|
|
|
GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, std::move(m_tbDeleted.at(index)));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2021-12-03 11:49:59 -05:00
|
|
|
|
}
|
2021-12-02 18:12:35 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::ostringstream pos; // V<>rifie l'existence d'un fichier .chunk avec sa position.
|
|
|
|
|
pos << CHUNK_PATH << chx / CHUNK_SIZE_X + m_center[0] << '_' << chy / CHUNK_SIZE_Z + m_center[1] << ".chunk";
|
|
|
|
|
|
|
|
|
|
std::ifstream input(pos.str().c_str(), std::fstream::binary);
|
|
|
|
|
|
|
|
|
|
if (input.fail()) {
|
|
|
|
|
GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, new Chunk(chx / CHUNK_SIZE_X + m_center[0], chy / CHUNK_SIZE_Z + m_center[1]));
|
|
|
|
|
Chunk* chunk = GetChunks().Get(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z);
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < CHUNK_SIZE_X; ++x)
|
|
|
|
|
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
float xnoiz, ynoiz;
|
|
|
|
|
xnoiz = (double)(x + (chx / CHUNK_SIZE_X + m_center[0]) * CHUNK_SIZE_X) / (double)INT16_MAX;
|
|
|
|
|
ynoiz = (double)(z + (chy / CHUNK_SIZE_Z + m_center[1]) * CHUNK_SIZE_Z) / (double)INT16_MAX;
|
|
|
|
|
float height = (perlin.Get(xnoiz, ynoiz)) * 10.f;
|
|
|
|
|
for (int y = 0; y <= (int)height; ++y)
|
2021-12-02 18:12:35 -05:00
|
|
|
|
chunk->SetBlock(x, y, z, BTYPE_METAL, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < CHUNK_SIZE_X; ++x)
|
|
|
|
|
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
float xnoiz, ynoiz;
|
|
|
|
|
xnoiz = (double)(x + (chx / CHUNK_SIZE_X + m_center[0]) * CHUNK_SIZE_X) / (double)INT16_MAX;
|
|
|
|
|
ynoiz = (double)(z + (chy / CHUNK_SIZE_Z + m_center[1]) * CHUNK_SIZE_Z) / (double)INT16_MAX;
|
|
|
|
|
float height = (perlin.Get(xnoiz, ynoiz) + 16.f);
|
2021-12-02 18:12:35 -05:00
|
|
|
|
for (int y = 0; y <= (int)height % CHUNK_SIZE_Y; ++y) {
|
|
|
|
|
if (chunk->GetBlock(x, y, z) == BTYPE_AIR)
|
|
|
|
|
chunk->SetBlock(x, y, z, BTYPE_GRASS, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < CHUNK_SIZE_X; ++x)
|
|
|
|
|
for (int z = 0; z < CHUNK_SIZE_Z; ++z) {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
for (int y = 0; y < 15; ++y) {
|
2021-12-02 18:12:35 -05:00
|
|
|
|
if (chunk->GetBlock(x, y, z) == BTYPE_AIR)
|
|
|
|
|
chunk->SetBlock(x, y, z, BTYPE_ICE, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
input.seekg(0, std::ios_base::end);
|
|
|
|
|
int size = input.tellg();
|
|
|
|
|
input.seekg(0, std::ios_base::beg);
|
|
|
|
|
|
|
|
|
|
char* data = new char[size];
|
|
|
|
|
input.read(data, size);
|
|
|
|
|
input.close();
|
|
|
|
|
|
|
|
|
|
GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, new Chunk(chx / CHUNK_SIZE_X + m_center[0], chy / CHUNK_SIZE_Z + m_center[1], data));
|
|
|
|
|
|
|
|
|
|
delete[] data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void World::UpdateChunk(int& generates, int& updates, int chx, int chy, Perlin& perlin, BlockInfo* blockinfo[BTYPE_LAST]) {
|
|
|
|
|
if (generates == 0 && GenerateChunk(chx, chy, perlin)) generates = FRAMES_RENDER_CHUNKS;
|
|
|
|
|
if (updates == 0 && ChunkAt(chx, 1, chy) &&
|
|
|
|
|
ChunkAt(chx, 1, chy)->IsDirty()) {
|
|
|
|
|
ChunkAt(chx, 1, chy)->Update(blockinfo, this);
|
|
|
|
|
updates = FRAMES_UPDATE_CHUNKS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void World::ChangeBlockAtCursor(BlockType blockType, Player& player, bool& block) {
|
|
|
|
|
Vector3f currentPos = player.GetPosition();
|
|
|
|
|
Vector3f currentBlock = currentPos;
|
|
|
|
|
Vector3f ray = player.GetDirection();
|
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
|
|
if (block) return;
|
|
|
|
|
|
|
|
|
|
while ((currentPos - currentBlock).Length() <= MAX_SELECTION_DISTANCE && !found) {
|
|
|
|
|
currentBlock += ray / 10.f;
|
|
|
|
|
|
|
|
|
|
BlockType bt = BlockAt(currentBlock);
|
|
|
|
|
|
|
|
|
|
if (bt != BTYPE_AIR)
|
|
|
|
|
found = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found)
|
|
|
|
|
if (blockType != BTYPE_AIR) {
|
|
|
|
|
found = false;
|
|
|
|
|
while ((currentPos - currentBlock).Length() >= 1.7f && !found) {
|
|
|
|
|
currentBlock -= ray / 10.f;
|
|
|
|
|
|
|
|
|
|
BlockType bt = BlockAt(currentBlock);
|
|
|
|
|
|
|
|
|
|
if (bt == BTYPE_AIR) { // V<>rification pour <20>tre s<>r que le bloc <20> changer n'est pas dans le joueur.
|
|
|
|
|
int Bx = (int)currentBlock.x;
|
|
|
|
|
int By = (int)currentBlock.y;
|
|
|
|
|
int Bz = (int)currentBlock.z;
|
|
|
|
|
|
|
|
|
|
int Px = (int)currentPos.x;
|
|
|
|
|
int PyA = (int)currentPos.y;
|
|
|
|
|
int PyB = (int)(currentPos.y - .9f);
|
|
|
|
|
int PyC = (int)(currentPos.y - 1.7f);
|
|
|
|
|
int Pz = (int)currentPos.z;
|
|
|
|
|
|
|
|
|
|
if (!(Bx == Px &&
|
|
|
|
|
(By == PyA ||
|
|
|
|
|
By == PyB ||
|
|
|
|
|
By == PyC) &&
|
|
|
|
|
Bz == Pz))
|
|
|
|
|
found = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found && (int)currentBlock.y < CHUNK_SIZE_Y) {
|
|
|
|
|
int bx = (int)currentBlock.x % CHUNK_SIZE_X;
|
|
|
|
|
int by = (int)currentBlock.y % CHUNK_SIZE_Y;
|
|
|
|
|
int bz = (int)currentBlock.z % CHUNK_SIZE_Z;
|
|
|
|
|
|
|
|
|
|
ChunkAt(currentBlock)->SetBlock(bx, by, bz, blockType, this);
|
|
|
|
|
ChunkAt(currentBlock)->MakeModified();
|
|
|
|
|
block = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Transformation& world, Shader& shader) {
|
|
|
|
|
shader.Use();
|
|
|
|
|
rendercount = 0;
|
|
|
|
|
badhitcount = 0;
|
|
|
|
|
Vector3f angle;
|
|
|
|
|
Vector3f cursor;
|
|
|
|
|
Vector3f direct = player.GetDirection();
|
|
|
|
|
Vector3f pos = player.GetPosition() - direct;
|
|
|
|
|
|
|
|
|
|
direct.y = 0;
|
|
|
|
|
direct.Normalize();
|
|
|
|
|
pos.y = 1;
|
2021-12-03 11:49:59 -05:00
|
|
|
|
|
|
|
|
|
static Vector3i renderManifest[VIEW_DISTANCE * 4];
|
2021-12-02 18:12:35 -05:00
|
|
|
|
|
|
|
|
|
for (int dist = VIEW_DISTANCE; dist >= 0; dist -= CHUNK_SIZE_X) {
|
|
|
|
|
// Configuration du radar.
|
2021-12-03 11:49:59 -05:00
|
|
|
|
float sinus, cosinus;
|
|
|
|
|
int echantillons;
|
|
|
|
|
|
|
|
|
|
if (dist > VIEW_DISTANCE * .375f) {
|
|
|
|
|
angle.x = direct.z + direct.x;
|
|
|
|
|
angle.z = direct.z - direct.x;
|
|
|
|
|
sinus = .01745240643; // sin(1 degr<67>)
|
|
|
|
|
cosinus = .99984769515; // cos(1 degr<67>)
|
|
|
|
|
echantillons = 90;
|
|
|
|
|
}
|
|
|
|
|
else if (dist > VIEW_DISTANCE * .5f) {
|
|
|
|
|
angle.x = direct.z + direct.x;
|
|
|
|
|
angle.z = direct.z - direct.x;
|
|
|
|
|
sinus = .0261769483;
|
|
|
|
|
cosinus = .99965732497;
|
|
|
|
|
echantillons = 60;
|
|
|
|
|
}
|
|
|
|
|
else if (dist > VIEW_DISTANCE * .625f) {
|
|
|
|
|
angle.x = direct.z + direct.x;
|
|
|
|
|
angle.z = direct.z - direct.x;
|
|
|
|
|
sinus = .0348994967;
|
|
|
|
|
cosinus = .99939082701;
|
|
|
|
|
echantillons = 45;
|
|
|
|
|
}
|
2021-12-03 11:51:59 -05:00
|
|
|
|
else {
|
2021-12-03 11:49:59 -05:00
|
|
|
|
angle.x = direct.z + direct.x;
|
|
|
|
|
angle.z = direct.z - direct.x;
|
|
|
|
|
sinus = .05233595624;
|
|
|
|
|
cosinus = .99862953475;
|
|
|
|
|
echantillons = 30;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-02 18:12:35 -05:00
|
|
|
|
angle.y = 0;
|
|
|
|
|
angle.Normalize();
|
|
|
|
|
|
|
|
|
|
for (int radar = 0; radar < echantillons; ++radar) {
|
|
|
|
|
float x = angle.x;
|
|
|
|
|
|
2021-12-03 11:51:59 -05:00
|
|
|
|
angle.x = angle.x * cosinus - angle.z * sinus;
|
|
|
|
|
angle.z = angle.z * cosinus + x * sinus;
|
2021-12-02 18:12:35 -05:00
|
|
|
|
angle.Normalize();
|
|
|
|
|
|
|
|
|
|
cursor = pos - direct * CHUNK_SIZE_X * 2 + angle * dist;
|
|
|
|
|
if (cursor.y >= 128.f || cursor.y >= 0.f) cursor.y = 1;
|
|
|
|
|
|
|
|
|
|
bool valide = true;
|
|
|
|
|
|
|
|
|
|
if (ChunkAt(cursor)) {
|
|
|
|
|
int chx, chy;
|
|
|
|
|
ChunkAt(cursor)->GetPosition(chx, chy);
|
2021-12-03 11:49:59 -05:00
|
|
|
|
for (int index = 0; index < rendercount; ++index)
|
2021-12-02 18:12:35 -05:00
|
|
|
|
if (renderManifest[index] == Vector3i(chx, 0, chy)) {
|
|
|
|
|
valide = false;
|
|
|
|
|
++badhitcount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (valide) {
|
|
|
|
|
world.ApplyTranslation((chx - m_center[0]) * CHUNK_SIZE_X, 0, (chy - m_center[1]) * CHUNK_SIZE_Z);
|
|
|
|
|
world.Use();
|
|
|
|
|
float dist = (pos - cursor).Length();
|
|
|
|
|
float blend = ((float)VIEW_DISTANCE - dist * 2.f + 128.f) / (float)VIEW_DISTANCE;
|
|
|
|
|
glBlendColor(0.f, 0.f, 0.f, blend);
|
|
|
|
|
ChunkAt(cursor)->Render();
|
|
|
|
|
world.ApplyTranslation(-(chx - m_center[0]) * CHUNK_SIZE_X, 0, -(chy - m_center[1]) * CHUNK_SIZE_Z);
|
2021-12-03 11:49:59 -05:00
|
|
|
|
renderManifest[++rendercount] = Vector3i(chx, 0, chy);
|
2021-12-02 18:12:35 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
shader.Disable();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void World::UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTYPE_LAST]) {
|
|
|
|
|
int cx = player.GetPosition().x;
|
|
|
|
|
int cy = player.GetPosition().z;
|
|
|
|
|
static int frameGenerate = 0;
|
|
|
|
|
static int frameUpdate = 0;
|
|
|
|
|
static int frameDelete = 0;
|
|
|
|
|
int side = 0;
|
|
|
|
|
|
|
|
|
|
if (frameGenerate > 0) --frameGenerate;
|
|
|
|
|
if (frameUpdate > 0) --frameUpdate;
|
|
|
|
|
if (frameDelete > 0) --frameDelete;
|
|
|
|
|
|
|
|
|
|
if (!frameGenerate || !frameUpdate)
|
|
|
|
|
while (side * CHUNK_SIZE_X <= VIEW_DISTANCE * 2) {
|
|
|
|
|
int tx = -side, ty = -side;
|
|
|
|
|
|
|
|
|
|
for (; tx <= side; ++tx)
|
|
|
|
|
UpdateChunk(frameGenerate, frameUpdate, cx + tx * CHUNK_SIZE_X, cy + ty * CHUNK_SIZE_Z, perlin, blockinfo);
|
|
|
|
|
for (; ty <= side; ++ty)
|
|
|
|
|
UpdateChunk(frameGenerate, frameUpdate, cx + tx * CHUNK_SIZE_X, cy + ty * CHUNK_SIZE_Z, perlin, blockinfo);
|
|
|
|
|
for (; tx >= -side; --tx)
|
|
|
|
|
UpdateChunk(frameGenerate, frameUpdate, cx + tx * CHUNK_SIZE_X, cy + ty * CHUNK_SIZE_Z, perlin, blockinfo);
|
|
|
|
|
for (; ty >= -side; --ty)
|
|
|
|
|
UpdateChunk(frameGenerate, frameUpdate, cx + tx * CHUNK_SIZE_X, cy + ty * CHUNK_SIZE_Z, perlin, blockinfo);
|
|
|
|
|
|
|
|
|
|
++side;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CleanUpWorld(frameDelete);
|
|
|
|
|
}
|