diff --git a/SQCSim2021/array2d.h b/SQCSim2021/array2d.h index b6068a1..7451365 100644 --- a/SQCSim2021/array2d.h +++ b/SQCSim2021/array2d.h @@ -12,6 +12,7 @@ class Array2d { void Set(int x, int y, T type); T Get(int x, int y) const; + T Remove(int x, int y); void Reset(T type); @@ -41,6 +42,13 @@ void Array2d::Set(int x, int y, T type) { m_array[To1dIndex(x, y)] = type; } template T Array2d::Get(int x, int y) const { return m_array[To1dIndex(x, y)]; } +template +T Array2d::Remove(int x, int y) { + T thing = std::move(m_array[To1dIndex(x, y)]); + m_array[To1dIndex(x, y)] = nullptr; + return thing; +} + template void Array2d::Reset(T type) { for (int i = 0; i < m_x * m_y; ++i) diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index d877407..1eeff0d 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -47,7 +47,7 @@ private: TextureAtlas m_textureAtlas = TextureAtlas(BTYPE_LAST); World m_world = World(); - Perlin m_perlin = Perlin(3,7.f,127.f,12345); + Perlin m_perlin = Perlin(4,32.f,7.f,12345); Texture m_textureSkybox; Texture m_textureFont; diff --git a/SQCSim2021/media/chunks/16357_16343.chunk b/SQCSim2021/media/chunks/16357_16343.chunk new file mode 100644 index 0000000..96cfa40 --- /dev/null +++ b/SQCSim2021/media/chunks/16357_16343.chunk @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SQCSim2021/media/chunks/16382_16360.chunk b/SQCSim2021/media/chunks/16382_16360.chunk new file mode 100644 index 0000000..7f5c474 Binary files /dev/null and b/SQCSim2021/media/chunks/16382_16360.chunk differ diff --git a/SQCSim2021/media/chunks/16382_16377.chunk b/SQCSim2021/media/chunks/16382_16377.chunk new file mode 100644 index 0000000..a62d18d Binary files /dev/null and b/SQCSim2021/media/chunks/16382_16377.chunk differ diff --git a/SQCSim2021/media/chunks/16382_16382.chunk b/SQCSim2021/media/chunks/16382_16382.chunk new file mode 100644 index 0000000..21daccc Binary files /dev/null and b/SQCSim2021/media/chunks/16382_16382.chunk differ diff --git a/SQCSim2021/media/chunks/16382_16383.chunk b/SQCSim2021/media/chunks/16382_16383.chunk new file mode 100644 index 0000000..63cd548 Binary files /dev/null and b/SQCSim2021/media/chunks/16382_16383.chunk differ diff --git a/SQCSim2021/media/chunks/16383_16382.chunk b/SQCSim2021/media/chunks/16383_16382.chunk new file mode 100644 index 0000000..2868119 Binary files /dev/null and b/SQCSim2021/media/chunks/16383_16382.chunk differ diff --git a/SQCSim2021/media/chunks/16383_16383.chunk b/SQCSim2021/media/chunks/16383_16383.chunk new file mode 100644 index 0000000..5781824 Binary files /dev/null and b/SQCSim2021/media/chunks/16383_16383.chunk differ diff --git a/SQCSim2021/player.cpp b/SQCSim2021/player.cpp index 5c91375..005500c 100644 --- a/SQCSim2021/player.cpp +++ b/SQCSim2021/player.cpp @@ -158,7 +158,7 @@ Vector3f Player::GetPOV() const { return Vector3f(GetPosition().x, m_POV, GetPos Vector3f Player::GetDirection() const { return m_direction; } -void Player::Transpose(int& x, int& z) { +void Player::Teleport(int& x, int& z) { m_position.x -= x * CHUNK_SIZE_X; m_position.z -= z * CHUNK_SIZE_Z; } diff --git a/SQCSim2021/player.h b/SQCSim2021/player.h index 7789ada..8d6253f 100644 --- a/SQCSim2021/player.h +++ b/SQCSim2021/player.h @@ -19,7 +19,7 @@ public: Vector3f GetDirection() const; Vector3f GetVelocity() const; Vector3f GetPOV() const; - void Transpose(int& x, int& z); + void Teleport(int& x, int& z); private: Vector3f m_position; diff --git a/SQCSim2021/world.cpp b/SQCSim2021/world.cpp index cd51c18..43209eb 100644 --- a/SQCSim2021/world.cpp +++ b/SQCSim2021/world.cpp @@ -1,102 +1,105 @@ #include "world.h" -World::World(){} +World::World() {} -World::~World(){} +World::~World() {} Array2d& World::GetChunks() { return m_chunks; } Chunk* World::ChunkAt(float x, float y, float z) const { - int cx = (int)x / CHUNK_SIZE_X; - int cz = (int)z / CHUNK_SIZE_Z; + int cx = (int)x / CHUNK_SIZE_X; + int cz = (int)z / CHUNK_SIZE_Z; - 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; + 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; - return m_chunks.Get(cx, cz); + return m_chunks.Get(cx, cz); } 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 { - Chunk* c = ChunkAt(x, y, z); + Chunk* c = ChunkAt(x, y, z); - if (!c) - return defaultBlockType; + if (!c) + return defaultBlockType; - int bx = (int)x % CHUNK_SIZE_X; - int by = (int)y % CHUNK_SIZE_Y; - int bz = (int)z % CHUNK_SIZE_Z; + int bx = (int)x % CHUNK_SIZE_X; + int by = (int)y % CHUNK_SIZE_Y; + int bz = (int)z % CHUNK_SIZE_Z; - return c->GetBlock(bx, by, bz); + return c->GetBlock(bx, by, bz); } BlockType World::BlockAt(const Vector3f& pos, BlockType defaultBlockType) const { - return BlockAt(pos.x, pos.y, pos.z, defaultBlockType); + return BlockAt(pos.x, pos.y, pos.z, defaultBlockType); } void World::TransposeWorld(Player& player) { - int x = 0; - int y = 0; + 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 (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 && !y) return; - if (x != 0) - for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) - for (int ax = 0; ax < abs(x); ++ay) - if (ChunkAt(x < 0 ? (WORLD_SIZE_X - 1 - ax) * WORLD_SIZE_X : ax, 1, ay * WORLD_SIZE_Y)) - m_tbDeleted.push_back(std::move(m_chunks.Get(x < 0? WORLD_SIZE_X - 1 - ax: ax, ay))); - if (y != 0) - for (int ax = 0; ax < WORLD_SIZE_X; ++ax) - for (int ay = 0; ay < abs(y); ++ay) - if (ChunkAt(ax * WORLD_SIZE_X , 1, y < 0 ? (WORLD_SIZE_Y - 1 - ay) * WORLD_SIZE_Y : ay)) - m_tbDeleted.push_back(std::move(m_chunks.Get(ax, y < 0 ? WORLD_SIZE_Y - 1 - ay: ay))); - - for (int ax = 0; ax < WORLD_SIZE_X; ++ax) - for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) - if (ax + x < WORLD_SIZE_X && ax + x > 0 && - ay + y < WORLD_SIZE_Y && ay + y > 0) - m_chunks.Set(x > 0? ax: ax + x, y > 0? ay: ay + y, - m_chunks.Get(x < 0 ? ax : ax + x, y < 0 ? ay : ay + y)); - if (x != 0) - for (int ay = 0; ay < WORLD_SIZE_Y; ++ay) - for (int ax = 0; ax < abs(x); ++ay) - m_chunks.Set(x > 0 ? WORLD_SIZE_X - 1 - ax : ax, ay, nullptr); - if (y != 0) - for (int ax = 0; ax < WORLD_SIZE_X; ++ax) - for (int ay = 0; ay < abs(y); ++ay) - m_chunks.Set(ax, y > 0 ? WORLD_SIZE_Y - 1 - ay : ay, nullptr); - - m_center[0] += x; m_center[1] += y; - player.Transpose(x, y); + 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)); + } + + 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)); + } + + m_center[0] += x; m_center[1] += y; + player.Teleport(x, y); } void World::CleanUpWorld(int& deleteframes, bool clear = false) { - if (clear) m_tbDeleted.clear(); - if (!m_tbDeleted.empty() && !deleteframes) { - m_tbDeleted.pop_back(); - deleteframes = FRAMES_DELETE_CHUNKS; - } -} - -Chunk* World::RetrieveChunk(int x, int y) { - for (int index = 0; index < m_tbDeleted.size(); ++index) { - int cx, cy; - m_tbDeleted.at(index)->GetPosition(cx, cy); - - if (cx == x && cy == y) - return std::move(m_tbDeleted.at(index)); - } - - return nullptr; + 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; } void World::GetScope(int& x, int& y) { @@ -106,25 +109,29 @@ void World::GetScope(int& x, int& y) { void World::Update(int& rendercount, int& badhitcount, Player& player, Transformation& world, Shader& shader, TextureAtlas& atlas, Perlin& perlin, BlockInfo* blockinfo[BTYPE_LAST]) { atlas.Bind(); - TransposeWorld(player); RenderWorld(rendercount, badhitcount, player, world, shader); + TransposeWorld(player); UpdateWorld(player, perlin, blockinfo); shader.Disable(); } bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { + 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; - m_tbDeleted.at(index)->GetPosition(x, y); - if (chx / CHUNK_SIZE_X + m_center[0] == x && + + if (&m_tbDeleted.at(index)) { + m_tbDeleted.at(index)->GetPosition(x, y); + if (chx / CHUNK_SIZE_X + m_center[0] == x && 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; } + } } std::ostringstream pos; // Vérifie l'existence d'un fichier .chunk avec sa position. @@ -138,24 +145,20 @@ bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { for (int x = 0; x < CHUNK_SIZE_X; ++x) for (int z = 0; z < CHUNK_SIZE_Z; ++z) { - Vector3f noise; - noise.x = x * (CHUNK_SIZE_X + 1) + (CHUNK_SIZE_X - 1) * (chx + m_center[0]); - noise.y = 0; - noise.z = z * (CHUNK_SIZE_Z + 1) + (CHUNK_SIZE_Z - 1) * (chy + m_center[1]); - noise.Normalize(); - float height = perlin.Get(noise.x, noise.z) * 3 - 32; - for (int y = 0; y <= (int)height % CHUNK_SIZE_Y; ++y) + 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) 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) { - Vector3f noise; - noise.x = x * (CHUNK_SIZE_X + 1) + (CHUNK_SIZE_X - 1) * (chx + m_center[0]); - noise.y = 0; - noise.z = z * (CHUNK_SIZE_Z + 1) + (CHUNK_SIZE_Z - 1) * (chy + m_center[1]); - noise.Normalize(); - float height = perlin.Get(noise.x, noise.z) + 16; + 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); 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); @@ -164,25 +167,12 @@ bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { for (int x = 0; x < CHUNK_SIZE_X; ++x) for (int z = 0; z < CHUNK_SIZE_Z; ++z) { - for (int y = 0; y <= 10; ++y) { + for (int y = 0; y < 15; ++y) { if (chunk->GetBlock(x, y, z) == BTYPE_AIR) chunk->SetBlock(x, y, z, BTYPE_ICE, this); } } - for (int x = 0; x < CHUNK_SIZE_X; ++x) - for (int z = 0; z < CHUNK_SIZE_Z; ++z) { - for (int y = 0; y < CHUNK_SIZE_Y; ++y) { - Vector3f noise; - noise.x = x * (CHUNK_SIZE_X + 1) + (CHUNK_SIZE_X - 1) * (chx + m_center[0]); - noise.y = (x + z) * CHUNK_SIZE_Y + m_center[0]; - noise.z = z * (CHUNK_SIZE_Z + 1) + (CHUNK_SIZE_Z - 1) * (chy + m_center[1]); - noise.Normalize(); - float height = perlin.Get(noise.x, noise.y, noise.z); - if (chunk->GetBlock(x, y, z) != BTYPE_AIR && height > 18) - chunk->SetBlock(x, y, z, BTYPE_DIRT, this); - } - } } else { input.seekg(0, std::ios_base::end); @@ -197,7 +187,6 @@ bool World::GenerateChunk(int chx, int chy, Perlin& perlin) { delete[] data; } - std::cout << "Chunk generated: " << chx / CHUNK_SIZE_X + m_center[0] << ", " << chy / CHUNK_SIZE_Z + m_center[1] << std::endl; return true; } @@ -274,7 +263,7 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran shader.Use(); rendercount = 0; badhitcount = 0; - static std::vector renderManifest; + //static std::vector renderManifest; Vector3f angle; Vector3f cursor; Vector3f direct = player.GetDirection(); @@ -283,18 +272,61 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran direct.y = 0; direct.Normalize(); pos.y = 1; - renderManifest.clear(); + //renderManifest.clear(); + + static Vector3i renderManifest[VIEW_DISTANCE * 4]; for (int dist = VIEW_DISTANCE; dist >= 0; dist -= CHUNK_SIZE_X) { // Configuration du radar. - angle.x = direct.z + direct.x; - angle.y = 0; - angle.z = direct.z - direct.x; - angle.Normalize(); + float sinus, cosinus; + int echantillons; - float sinus = .01745240643; // sin(1 degré) - float cosinus = .99984769515; // cos(1 degré) - int echantillons = 90; + if (dist > VIEW_DISTANCE * .375f) { + angle.x = direct.z + direct.x; + angle.z = direct.z - direct.x; + sinus = .01745240643; // sin(1 degré) + cosinus = .99984769515; // cos(1 degré) + 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; + } + else /*if (dist > VIEW_DISTANCE * .75f)*/ { + angle.x = direct.z + direct.x; + angle.z = direct.z - direct.x; + sinus = .05233595624; + cosinus = .99862953475; + echantillons = 30; + } + //else if (dist > VIEW_DISTANCE * .875f) { // - CHUNK_SIZE_X * 28) { + // angle.x = direct.z; + // angle.z = -direct.x; + // sinus = .08715574274; + // cosinus = .996194698091; + // echantillons = 36; + // //echantillons = 0; + //} + //else { + // angle.x = direct.z; + // angle.z = -direct.x; + // sinus = .13052619222; + // cosinus = .99144486137; + // echantillons = 24; + //} + + angle.y = 0; + angle.Normalize(); for (int radar = 0; radar < echantillons; ++radar) { float x = angle.x; @@ -312,7 +344,7 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran if (ChunkAt(cursor)) { int chx, chy; ChunkAt(cursor)->GetPosition(chx, chy); - for (int index = 0; index < renderManifest.size(); ++index) + for (int index = 0; index < rendercount; ++index) if (renderManifest[index] == Vector3i(chx, 0, chy)) { valide = false; ++badhitcount; @@ -326,8 +358,8 @@ void World::RenderWorld(int& rendercount, int& badhitcount, Player& player, Tran 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); - renderManifest.push_back(Vector3i(chx, 0, chy)); - ++rendercount; + renderManifest[++rendercount] = Vector3i(chx, 0, chy); + //++rendercount; } } } diff --git a/SQCSim2021/world.h b/SQCSim2021/world.h index 8e4c6e9..55eeb98 100644 --- a/SQCSim2021/world.h +++ b/SQCSim2021/world.h @@ -46,7 +46,7 @@ private: void RenderWorld(int& rendercount, int& badhitcount, Player& player, Transformation& world, Shader& shader); void UpdateWorld(Player& player, Perlin& perlin, BlockInfo* blockinfo[BTYPE_LAST]); void TransposeWorld(Player& player); - Chunk* RetrieveChunk(int x, int y); + /*Chunk* RetrieveChunk(int x, int y);*/ };