diff options
-rw-r--r-- | src/Event.hpp | 16 | ||||
-rw-r--r-- | src/GameState.cpp | 26 | ||||
-rw-r--r-- | src/Network.cpp | 5 | ||||
-rw-r--r-- | src/Packet.hpp | 50 | ||||
-rw-r--r-- | src/Renderer.cpp | 8 | ||||
-rw-r--r-- | src/Renderer.hpp | 4 | ||||
-rw-r--r-- | src/RendererEntity.cpp | 17 | ||||
-rw-r--r-- | src/RendererSection.cpp | 172 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 182 | ||||
-rw-r--r-- | src/RendererWorld.hpp | 6 | ||||
-rw-r--r-- | src/Section.cpp | 250 | ||||
-rw-r--r-- | src/Section.hpp | 38 | ||||
-rw-r--r-- | src/World.cpp | 148 | ||||
-rw-r--r-- | src/World.hpp | 32 |
14 files changed, 649 insertions, 305 deletions
diff --git a/src/Event.hpp b/src/Event.hpp index 23cc58c..5467f85 100644 --- a/src/Event.hpp +++ b/src/Event.hpp @@ -40,6 +40,8 @@ enum class EventType { DeleteSectionRender, EntityChanged, NewRenderDataAvailable, + BlockChange, + RendererWorkerTask, }; struct EchoData { @@ -136,7 +138,7 @@ struct CreatedSectionRenderData { }; struct PlayerPosChangedData { - Vector newPos; + VectorF newPos; }; struct UpdateSectionsRenderData { @@ -155,12 +157,22 @@ struct NewRenderDataAvailableData { }; +struct BlockChangeData { + Vector SectionPos; +}; + +struct RendererWorkerTaskData { + size_t WorkerId; + Vector Task; +}; + using EventData = std::variant<EchoData, ChunkChangedData, ConnectToServerData, ConnectionSuccessfullData, DisconnectData, SendPacketData, ReceivePacketData, RequestNetworkClientData, RegisterNetworkClientData, PlayerConnectedData, RemoveLoadingScreenData, ConnectionFailedData, ExitData, DisconnectedData, ConnectingData, NetworkClientExceptionData, MouseMovedData, KeyPressedData, KeyReleasedData, InitalizeSectionRenderData, CreateSectionRenderData, CreatedSectionRenderData, PlayerPosChangedData, - UpdateSectionsRenderData, DeleteSectionRenderData, EntityChangedData,NewRenderDataAvailableData>; + UpdateSectionsRenderData, DeleteSectionRenderData, EntityChangedData,NewRenderDataAvailableData, + BlockChangeData, RendererWorkerTaskData>; struct Event { EventType type; diff --git a/src/GameState.cpp b/src/GameState.cpp index 025eeda..77b6394 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -73,7 +73,7 @@ void GameState::UpdatePacket() entity.yaw = packet->Yaw / 256.0; entity.pitch = packet->Pitch / 256.0; entity.renderColor = glm::vec3(0,1,0); - world.entities.push_back(entity); + world.AddEntity(entity); EventAgregator::PushEvent(EventType::EntityChanged, EntityChangedData{ entity.entityId }); break; } @@ -91,7 +91,7 @@ void GameState::UpdatePacket() entity.yaw = packet->Yaw / 256.0; entity.pitch = packet->Pitch / 256.0; entity.renderColor = glm::vec3(0,0,1); - world.entities.push_back(entity); + world.AddEntity(entity); EventAgregator::PushEvent(EventType::EntityChanged, EntityChangedData{ entity.entityId }); break; } @@ -108,7 +108,7 @@ void GameState::UpdatePacket() entity.renderColor = glm::vec3(1, 0, 0); entity.height = 1.8; entity.width = 0.6; - world.entities.push_back(entity); + world.AddEntity(entity); EventAgregator::PushEvent(EventType::EntityChanged, EntityChangedData{ entity.entityId }); break; } @@ -122,8 +122,11 @@ void GameState::UpdatePacket() break; case BlockAction: break; - case BlockChange: + case BlockChange: { + auto packet = std::static_pointer_cast<PacketBlockChange>(ptr); + world.ParseChunkData(packet); break; + } case BossBar: break; case ServerDifficulty: @@ -132,8 +135,11 @@ void GameState::UpdatePacket() break; case ChatMessageCB: break; - case MultiBlockChange: + case MultiBlockChange: { + auto packet = std::static_pointer_cast<PacketMultiBlockChange>(ptr); + world.ParseChunkData(packet); break; + } case ConfirmTransactionCB: break; case CloseWindowCB: @@ -267,7 +273,7 @@ void GameState::UpdatePacket() g_PlayerZ = packet->Z; } - EventAgregator::PushEvent(EventType::PlayerPosChanged, PlayerPosChangedData{ Vector(g_PlayerX,g_PlayerY,g_PlayerZ) }); + EventAgregator::PushEvent(EventType::PlayerPosChanged, PlayerPosChangedData{ VectorF(g_PlayerX,g_PlayerY,g_PlayerZ) }); LOG(INFO) << "PlayerPos is " << g_PlayerX << ", " << g_PlayerY << ", " << g_PlayerZ << "\t\tAngle: " << g_PlayerYaw << "," << g_PlayerPitch; @@ -291,12 +297,8 @@ void GameState::UpdatePacket() break; case DestroyEntities: { auto packet = std::static_pointer_cast<PacketDestroyEntities>(ptr); - for (auto& entityId : packet->EntityIds) { - auto it = world.entities.begin(); - while (it != world.entities.end() && it->entityId != entityId) - ++it; - if (it != world.entities.end()) - world.entities.erase(it); + for (unsigned int entityId : packet->EntityIds) { + world.DeleteEntity(entityId); } break; } diff --git a/src/Network.cpp b/src/Network.cpp index 789e650..4ab85d3 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -69,7 +69,6 @@ std::shared_ptr<Packet> Network::ParsePacketPlay(PacketNamePlayCB id) { switch (id) { case SpawnObject: return std::make_shared<PacketSpawnObject>(); - break; case SpawnExperienceOrb: break; case SpawnGlobalEntity: @@ -91,7 +90,7 @@ std::shared_ptr<Packet> Network::ParsePacketPlay(PacketNamePlayCB id) { case BlockAction: break; case BlockChange: - break; + return std::make_shared<PacketBlockChange>(); case BossBar: break; case ServerDifficulty: @@ -101,7 +100,7 @@ std::shared_ptr<Packet> Network::ParsePacketPlay(PacketNamePlayCB id) { case ChatMessageCB: break; case MultiBlockChange: - break; + return std::make_shared<PacketMultiBlockChange>(); case ConfirmTransactionCB: break; case CloseWindowCB: diff --git a/src/Packet.hpp b/src/Packet.hpp index c499720..6318eab 100644 --- a/src/Packet.hpp +++ b/src/Packet.hpp @@ -751,4 +751,54 @@ struct PacketSpawnMob : Packet { unsigned char Yaw, Pitch, HeadPitch; short VelocityX, VelocityY, VelocityZ; //Metadata +}; + +struct PacketBlockChange : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + Position = stream->ReadPosition(); + BlockId = stream->ReadVarInt(); + } + + int GetPacketId() override { + return PacketNamePlayCB::BlockChange; + } + + Vector Position; + int BlockId; +}; + +struct PacketMultiBlockChange : Packet { + void ToStream(StreamOutput *stream) override { + + } + + void FromStream(StreamInput *stream) override { + ChunkX = stream->ReadInt(); + ChunkZ = stream->ReadInt(); + int recordCount = stream->ReadVarInt(); + for (int i = 0; i < recordCount; i++) { + Record record; + record.HorizontalPosition = stream->ReadUByte(); + record.YCoordinate = stream->ReadUByte(); + record.BlockId = stream->ReadVarInt(); + Records.push_back(record); + } + } + + int GetPacketId() override { + return PacketNamePlayCB::MultiBlockChange; + } + + int ChunkX; + int ChunkZ; + struct Record { + unsigned char HorizontalPosition; + unsigned char YCoordinate; + int BlockId; + }; + std::vector<Record> Records; };
\ No newline at end of file diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 5fc8c2e..76cef4e 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -1,10 +1,10 @@ #include "Renderer.hpp" void RenderState::SetActiveVao(GLuint Vao) { - if (Vao != ActiveVao) { - glBindVertexArray(Vao); - ActiveVao = Vao; - } + glBindVertexArray(Vao); + ActiveVao = Vao; + /*if (Vao != ActiveVao) { + }*/ } void RenderState::SetActiveShader(GLuint Shader) { diff --git a/src/Renderer.hpp b/src/Renderer.hpp index de2e331..cd0d7b0 100644 --- a/src/Renderer.hpp +++ b/src/Renderer.hpp @@ -3,8 +3,8 @@ #include <GL/glew.h> class RenderState { - GLuint ActiveVao = 0; - GLuint ActiveShader = 0; + GLuint ActiveVao = -1; + GLuint ActiveShader = -1; public: void SetActiveVao(GLuint Vao); void SetActiveShader(GLuint Shader); diff --git a/src/RendererEntity.cpp b/src/RendererEntity.cpp index 3adcf60..6a92cec 100644 --- a/src/RendererEntity.cpp +++ b/src/RendererEntity.cpp @@ -109,19 +109,23 @@ RendererEntity::RendererEntity(World *ptr, unsigned int id) entityId = id; - if (Vbo == magic || Vao == magic) { - glGenVertexArrays(1, &Vao); + if (Vbo == magic) { glGenBuffers(1, &Vbo); + glBindBuffer(GL_ARRAY_BUFFER, Vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glGenBuffers(1, &Vbo2); + glBindBuffer(GL_ARRAY_BUFFER, Vbo2); + glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); + glGenVertexArrays(1, &Vao); glBindVertexArray(Vao); { - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, Vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, Vbo2); - glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(1); } @@ -133,7 +137,7 @@ RendererEntity::~RendererEntity() { } void RendererEntity::Render(RenderState & renderState) { - renderState.SetActiveVao(Vao); + renderState.SetActiveVao(Vao); glm::mat4 model; Entity& entity = world->GetEntity(entityId); model = glm::translate(model, entity.pos.glm()); @@ -142,6 +146,7 @@ void RendererEntity::Render(RenderState & renderState) { glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniform3f(colorLoc, entity.renderColor.x, entity.renderColor.y, entity.renderColor.z); + glCheckError(); glDrawArrays(GL_TRIANGLES, 0, 36); glCheckError(); diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index add2d3d..16514b2 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -33,15 +33,15 @@ RendererSection::~RendererSection() { refCounterVbo[VboModels]--; refCounterVbo[VboColors]--; refCounterVao[Vao]--; - if (refCounterVbo[VboTextures] <= 0) - glDeleteBuffers(1, &VboTextures); + if (refCounterVbo[VboTextures] == 0) + glDeleteBuffers(1, &VboTextures); - if (refCounterVbo[VboModels] <= 0) + if (refCounterVbo[VboModels] == 0) glDeleteBuffers(1, &VboTextures); - if (refCounterVbo[VboColors] <= 0) + if (refCounterVbo[VboColors] == 0) glDeleteBuffers(1, &VboColors); - if (refCounterVao[Vao] <= 0) + if (refCounterVao[Vao] == 0) glDeleteVertexArrays(1, &Vao); } @@ -108,43 +108,43 @@ RendererSection::RendererSection(RendererSectionData data) { //Cube UVs GLuint UvAttribPos = 2; - glBindBuffer(GL_ARRAY_BUFFER, VboUvs); - glVertexAttribPointer(UvAttribPos, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(UvAttribPos); - - //Textures - GLuint textureAttribPos = 7; - glBindBuffer(GL_ARRAY_BUFFER, VboTextures); - glVertexAttribPointer(textureAttribPos, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(textureAttribPos); - glVertexAttribDivisor(textureAttribPos, 1); - glCheckError(); - - //Blocks models - GLuint matAttribPos = 8; - size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); - glBindBuffer(GL_ARRAY_BUFFER, VboModels); - glVertexAttribPointer(matAttribPos + 0, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, nullptr); - glVertexAttribPointer(matAttribPos + 1, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(1 * 4 * sizeof(GLfloat))); - glVertexAttribPointer(matAttribPos + 2, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(2 * 4 * sizeof(GLfloat))); - glVertexAttribPointer(matAttribPos + 3, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(3 * 4 * sizeof(GLfloat))); - glEnableVertexAttribArray(matAttribPos + 0); - glEnableVertexAttribArray(matAttribPos + 1); - glEnableVertexAttribArray(matAttribPos + 2); - glEnableVertexAttribArray(matAttribPos + 3); - glVertexAttribDivisor(matAttribPos + 0, 1); - glVertexAttribDivisor(matAttribPos + 1, 1); - glVertexAttribDivisor(matAttribPos + 2, 1); - glVertexAttribDivisor(matAttribPos + 3, 1); - - //Color - GLuint colorAttribPos = 12; - glBindBuffer(GL_ARRAY_BUFFER, VboColors); - glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); - glEnableVertexAttribArray(colorAttribPos); - glVertexAttribDivisor(colorAttribPos, 1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); +glBindBuffer(GL_ARRAY_BUFFER, VboUvs); +glVertexAttribPointer(UvAttribPos, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); +glEnableVertexAttribArray(UvAttribPos); + +//Textures +GLuint textureAttribPos = 7; +glBindBuffer(GL_ARRAY_BUFFER, VboTextures); +glVertexAttribPointer(textureAttribPos, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); +glEnableVertexAttribArray(textureAttribPos); +glVertexAttribDivisor(textureAttribPos, 1); +glCheckError(); + +//Blocks models +GLuint matAttribPos = 8; +size_t sizeOfMat4 = 4 * 4 * sizeof(GLfloat); +glBindBuffer(GL_ARRAY_BUFFER, VboModels); +glVertexAttribPointer(matAttribPos + 0, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, nullptr); +glVertexAttribPointer(matAttribPos + 1, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(1 * 4 * sizeof(GLfloat))); +glVertexAttribPointer(matAttribPos + 2, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(2 * 4 * sizeof(GLfloat))); +glVertexAttribPointer(matAttribPos + 3, 4, GL_FLOAT, GL_FALSE, sizeOfMat4, (void *)(3 * 4 * sizeof(GLfloat))); +glEnableVertexAttribArray(matAttribPos + 0); +glEnableVertexAttribArray(matAttribPos + 1); +glEnableVertexAttribArray(matAttribPos + 2); +glEnableVertexAttribArray(matAttribPos + 3); +glVertexAttribDivisor(matAttribPos + 0, 1); +glVertexAttribDivisor(matAttribPos + 1, 1); +glVertexAttribDivisor(matAttribPos + 2, 1); +glVertexAttribDivisor(matAttribPos + 3, 1); + +//Color +GLuint colorAttribPos = 12; +glBindBuffer(GL_ARRAY_BUFFER, VboColors); +glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); +glEnableVertexAttribArray(colorAttribPos); +glVertexAttribDivisor(colorAttribPos, 1); + +glBindBuffer(GL_ARRAY_BUFFER, 0); } glBindVertexArray(0); glCheckError(); @@ -168,48 +168,76 @@ RendererSection::RendererSection(RendererSectionData data) { } RendererSection::RendererSection(const RendererSection &other) { - this->VboModels = other.VboModels; - this->VboTextures = other.VboTextures; - this->VboColors = other.VboColors; - this->sectionPos = other.sectionPos; - this->Vao = other.Vao; - this->numOfFaces = other.numOfFaces; - this->hash = other.hash; - - refCounterVbo[VboTextures]++; - refCounterVbo[VboModels]++; - refCounterVbo[VboColors]++; - refCounterVao[Vao]++; + this->VboModels = other.VboModels; + this->VboTextures = other.VboTextures; + this->VboColors = other.VboColors; + this->sectionPos = other.sectionPos; + this->Vao = other.Vao; + this->numOfFaces = other.numOfFaces; + this->hash = other.hash; + + refCounterVbo[VboTextures]++; + refCounterVbo[VboModels]++; + refCounterVbo[VboColors]++; + refCounterVao[Vao]++; } RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) { const std::map<BlockTextureId, glm::vec4> &textureAtlas = AssetManager::Instance().GetTextureAtlasIndexes(); - Section §ion = world->GetSection(sectionPosition); + const Section §ion = world->GetSection(sectionPosition); + + auto sectionsList = world->GetSectionsList(); + for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { - Vector blockPos = Vector(x, y, z) + (sectionPosition * 16u); - Block block = world->GetBlock(blockPos); + Block block = section.GetBlock(Vector(x, y, z)); if (block.id == 0) - continue; - - auto checkBlockVisibility = [&](Vector block) -> bool { - return section.GetBlock(block).id == 0 || - section.GetBlock(block).id == 31 || - section.GetBlock(block).id == 18; + continue; + + auto testBlockNonExist = [&](Vector block) -> bool { + Vector offset; + if (block.x == -1) { + offset = Vector(-1, 0, 0); + block.x = 15; + } else if (block.x == 16) { + offset = Vector(1, 0, 0); + block.x = 0; + } else if (block.y == -1) { + offset = Vector(0, -1, 0); + block.y = 15; + } else if (block.y == 16) { + offset = Vector(0, 1, 0); + block.y = 0; + } else if (block.z == -1) { + offset = Vector(0, 0, -1); + block.z = 15; + } else if (block.z == 16) { + offset = Vector(0, 0, 1); + block.z = 0; + } + if (offset != Vector(0, 0, 0)) { + if (std::find(sectionsList.begin(), sectionsList.end(), sectionPosition + offset) == sectionsList.end()) + return true; + const Section& blockSection = world->GetSection(sectionPosition + offset); + return blockSection.GetBlock(block).id == 0 || blockSection.GetBlock(block).id == 31 || blockSection.GetBlock(block).id == 18; + } + return section.GetBlock(block).id == 0 || section.GetBlock(block).id == 31 || section.GetBlock(block).id == 18; + /*return block.x == -1 || block.x == 16 || block.y == -1 || block.y == 16 || block.z == -1 || block.z == 16 || + section.GetBlock(block).id == 0 || section.GetBlock(block).id == 31 || section.GetBlock(block).id == 18;*/ }; unsigned char isVisible = 0; - if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { + /*if (x == 0 || x == 15 || y == 0 || y == 15 || z == 0 || z == 15) { isVisible = 0b1111'1111; //All faces is visible - } else { - isVisible |= checkBlockVisibility(Vector(x - 1, y, z)) << 0; - isVisible |= checkBlockVisibility(Vector(x + 1, y, z)) << 1; - isVisible |= checkBlockVisibility(Vector(x, y + 1, z)) << 2; - isVisible |= checkBlockVisibility(Vector(x, y - 1, z)) << 3; - isVisible |= checkBlockVisibility(Vector(x, y, z - 1)) << 4; - isVisible |= checkBlockVisibility(Vector(x, y, z + 1)) << 5; - } + } else {*/ + isVisible |= testBlockNonExist(Vector(x - 1, y, z)) << 0; + isVisible |= testBlockNonExist(Vector(x + 1, y, z)) << 1; + isVisible |= testBlockNonExist(Vector(x, y + 1, z)) << 2; + isVisible |= testBlockNonExist(Vector(x, y - 1, z)) << 3; + isVisible |= testBlockNonExist(Vector(x, y, z - 1)) << 4; + isVisible |= testBlockNonExist(Vector(x, y, z + 1)) << 5; + //} if (isVisible == 0x00) continue; diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 08f890e..61c2afa 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -6,7 +6,8 @@ void RendererWorld::LoadedSectionController() { Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); std::vector<Vector> suitableChunks; - for (auto& it : gs->world.GetSectionsList()) { + auto chunks = gs->world.GetSectionsList(); + for (auto& it : chunks) { double distance = (Vector(it.x, 0, it.z) - playerChunk).GetLength(); if (distance > MaxRenderingDistance) continue; @@ -46,7 +47,6 @@ void RendererWorld::LoadedSectionController() { auto& result = sections.find(vec); if (result != sections.end()) { if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash()) { - sections.erase(result); sectionsMutex.unlock(); RendererSectionData data(&gs->world, vec); renderDataMutex.lock(); @@ -70,7 +70,7 @@ void RendererWorld::LoadedSectionController() { contentListener.RegisterHandler(EventType::PlayerPosChanged, [this,&updateAllSections](EventData eventData) { auto pos = std::get<PlayerPosChangedData>(eventData).newPos; - updateAllSections(pos); + updateAllSections(Vector(pos.x,pos.y,pos.z)); }); contentListener.RegisterHandler(EventType::UpdateSectionsRender, [this,&updateAllSections](EventData eventData) { @@ -91,6 +91,50 @@ void RendererWorld::LoadedSectionController() { } } +/*void RendererWorld::WorkerFunction(size_t workerId) { + EventListener tasksListener; + + tasksListener.RegisterHandler(EventType::RendererWorkerTask, [&](EventData eventData) { + auto data = std::get<RendererWorkerTaskData>(eventData); + if (data.WorkerId != workerId) + return; + Vector vec = data.Task; + + sectionsMutex.lock(); + auto& result = sections.find(vec); + if (result != sections.end()) { + if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash()) { + sectionsMutex.unlock(); + RendererSectionData data(&gs->world, vec); + renderDataMutex.lock(); + renderData.push(data); + renderDataMutex.unlock(); + EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{}); + sectionsMutex.lock(); + } + } + else { + sectionsMutex.unlock(); + RendererSectionData data(&gs->world, vec); + renderDataMutex.lock(); + renderData.push(data); + renderDataMutex.unlock(); + EventAgregator::PushEvent(EventType::NewRenderDataAvailable, NewRenderDataAvailableData{}); + sectionsMutex.lock(); + } + sectionsMutex.unlock(); + LOG(INFO) << "Task " << vec << " done in " << workerId; + + }); + + LoopExecutionTimeController timer(std::chrono::milliseconds(50)); + while (isRunning) { + while (tasksListener.IsEventsQueueIsNotEmpty()) + tasksListener.HandleEvent(); + timer.Update(); + } +}*/ + void RendererWorld::RenderBlocks(RenderState& renderState) { renderState.SetActiveShader(blockShader->Program); @@ -124,7 +168,7 @@ void RendererWorld::RenderEntities(RenderState& renderState) } RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { - MaxRenderingDistance = 2; + MaxRenderingDistance = 15; PrepareRender(); @@ -144,30 +188,70 @@ RendererWorld::RendererWorld(GameState * ptr):gs(ptr) { listener.RegisterHandler(EventType::NewRenderDataAvailable,[this](EventData eventData) { renderDataMutex.lock(); while (!renderData.empty()) { - auto &data = renderData.front(); - auto pair = std::make_pair(data.sectionPos, RendererSection(data)); + auto &data = renderData.front(); sectionsMutex.lock(); - if (!sections.insert(pair).second) { + if (sections.find(data.sectionPos) != sections.end()) { + if (sections.find(data.sectionPos)->second.GetHash() == data.hash) { + LOG(INFO) << "Generated not necesarry RendererData"; + sectionsMutex.unlock(); + renderData.pop(); + continue; + } sections.erase(sections.find(data.sectionPos)); - sections.insert(pair); } + RendererSection renderer(data); + sections.insert(std::make_pair(data.sectionPos, renderer)); sectionsMutex.unlock(); renderData.pop(); } renderDataMutex.unlock(); + + /*sectionsMutex.lock(); + renderList.clear(); + for (auto& it : sections) { + renderList.push_back(it.first); + } + sectionsMutex.unlock(); + std::sort(renderList.begin(), renderList.end(), [&](Vector lhs, Vector rhs) { + VectorF playerPos(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ); + VectorF left = VectorF(lhs.x, lhs.y, lhs.z) * 16 - playerPos; + VectorF right = VectorF(rhs.x, rhs.y, rhs.z) * 16 - playerPos; + return left.GetLength() > right.GetLength(); + });*/ }); listener.RegisterHandler(EventType::EntityChanged, [this](EventData eventData) { auto data = std::get<EntityChangedData>(eventData); - for (auto&it : gs->world.entities) { - if (it.entityId == data.EntityId) { - entities.push_back(RendererEntity(&gs->world,it.entityId)); - return; + for (unsigned int entityId : gs->world.GetEntitiesList()) { + if (entityId == data.EntityId) { + entities.push_back(RendererEntity(&gs->world, entityId)); } } }); + /*listener.RegisterHandler(EventType::ChunkChanged, [this](EventData eventData) { + auto vec = std::get<ChunkChangedData>(eventData).chunkPosition; + Vector playerChunk(std::floor(gs->g_PlayerX / 16), 0, std::floor(gs->g_PlayerZ / 16)); + + double distanceToChunk = (Vector(vec.x, 0, vec.z) - playerChunk).GetLength(); + if (distanceToChunk > MaxRenderingDistance) { + //LOG(WARNING) << (Vector(vec.x, 0, vec.z) - playerChunk).GetLength(); + //LOG(WARNING) << distanceToChunk; + return; + } + + EventAgregator::PushEvent(EventType::RendererWorkerTask, RendererWorkerTaskData{ currentWorker++,vec }); + if (currentWorker > numOfWorkers) + currentWorker = 0; + LOG(INFO) << "New task " << vec << " for " << currentWorker; + }); + + for (int i = 0; i < numOfWorkers; i++) + workers[i] = std::thread(&RendererWorld::WorkerFunction, this, i);*/ + resourceLoader = std::thread(&RendererWorld::LoadedSectionController, this); + + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } RendererWorld::~RendererWorld() { @@ -179,6 +263,8 @@ RendererWorld::~RendererWorld() { sectionsMutex.unlock(); LOG(INFO) << "Total faces to render: "<<faces; isRunning = false; + /*for (int i = 0; i < numOfWorkers; i++) + workers[i].join();*/ resourceLoader.join(); delete blockShader; delete entityShader; @@ -198,13 +284,73 @@ void RendererWorld::Render(RenderState & renderState) { glUniform2f(windowSizeLoc, renderState.WindowWidth, renderState.WindowHeight); glCheckError(); - sectionsMutex.lock(); - for (auto& it : sections) { + /*for (auto& pos : renderList) { + std::vector<Vector> sectionCorners = { + Vector(0, 0, 0), + Vector(0, 0, 16), + Vector(0, 16, 0), + Vector(0, 16, 16), + Vector(16, 0, 0), + Vector(16, 0, 16), + Vector(16, 16, 0), + Vector(16, 16, 16), + }; + bool isBreak = true; + glm::mat4 vp = projection * view; + for (auto &it : sectionCorners) { + glm::vec3 point(pos.x * 16 + it.x, pos.y * 16 + it.y, pos.z * 16 + it.z); + glm::vec4 p = vp * glm::vec4(point, 1); + glm::vec3 res = glm::vec3(p) / p.w; + if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) { + isBreak = false; + break; + } + } + double lengthToSection = (VectorF(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ) - VectorF(pos.x * 16, pos.y * 16, pos.z * 16)).GetLength(); - it.second.Render(renderState); + if (isBreak && lengthToSection > 30.0f) { + continue; + } + + sections.find(pos)->second.Render(renderState); + }*/ + sectionsMutex.lock(); + for (auto& section : sections) { + sectionsMutex.unlock(); + std::vector<Vector> sectionCorners = { + Vector(0, 0, 0), + Vector(0, 0, 16), + Vector(0, 16, 0), + Vector(0, 16, 16), + Vector(16, 0, 0), + Vector(16, 0, 16), + Vector(16, 16, 0), + Vector(16, 16, 16), + }; + bool isBreak = true; + glm::mat4 vp = projection * view; + for (auto &it : sectionCorners) { + glm::vec3 point(section.second.GetPosition().x * 16 + it.x, + section.second.GetPosition().y * 16 + it.y, + section.second.GetPosition().z * 16 + it.z); + glm::vec4 p = vp * glm::vec4(point, 1); + glm::vec3 res = glm::vec3(p) / p.w; + if (res.x < 1 && res.x > -1 && res.y < 1 && res.y > -1 && res.z > 0) { + isBreak = false; + break; + } + } + double lengthToSection = (VectorF(gs->g_PlayerX, gs->g_PlayerY, gs->g_PlayerZ) - VectorF(section.first.x*16,section.first.y*16,section.first.z*16)).GetLength(); + + if (isBreak && lengthToSection > 30.0f) { + sectionsMutex.lock(); + continue; + } + section.second.Render(renderState); + sectionsMutex.lock(); } sectionsMutex.unlock(); - + glCheckError(); renderState.SetActiveShader(entityShader->Program); glCheckError(); @@ -231,6 +377,7 @@ void RendererWorld::PrepareRender() { blockShader = new Shader("./shaders/face.vs", "./shaders/face.fs"); blockShader->Use(); glUniform1i(glGetUniformLocation(blockShader->Program, "textureAtlas"), 0); + entityShader = new Shader("./shaders/entity.vs", "./shaders/entity.fs"); } @@ -240,5 +387,6 @@ bool RendererWorld::IsNeedResourcesPrepare() { } void RendererWorld::Update() { - listener.HandleEvent(); + while (listener.IsEventsQueueIsNotEmpty()) + listener.HandleEvent(); } diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index d339706..54c1826 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -11,11 +11,15 @@ class RendererWorld: public Renderer { //General GameState *gs; EventListener listener; + /*static const size_t numOfWorkers = 4; + size_t currentWorker = 0; + std::thread workers[numOfWorkers]; + void WorkerFunction(size_t WorkerId);*/ std::thread resourceLoader; void LoadedSectionController(); bool isRunning = true; //Blocks - + std::vector<Vector> renderList; std::mutex sectionsMutex; std::map<Vector, RendererSection> sections; Shader *blockShader; diff --git a/src/Section.cpp b/src/Section.cpp index b2d9ac9..3fb100f 100644 --- a/src/Section.cpp +++ b/src/Section.cpp @@ -1,97 +1,120 @@ #include "Section.hpp" - -Section::Section(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, - byte bitsPerBlock, - std::vector<unsigned short> palette) { - worldPosition = position; - - m_dataBlocksLen = dataBlocksLength; - m_dataBlocks = new byte[m_dataBlocksLen]; - std::copy(dataBlocks, dataBlocks + m_dataBlocksLen, m_dataBlocks); - - m_dataLight = new byte[2048]; - std::copy(dataLight, dataLight + 2048, m_dataLight); - - if (dataSky) { - m_dataSkyLight = new byte[2048]; - std::copy(dataSky, dataSky + 2048, m_dataSkyLight); - } - - m_palette = palette; - m_bitsPerBlock = bitsPerBlock; -} - Section::~Section() { - delete[] m_dataBlocks; - m_dataBlocksLen = 0; - m_dataBlocks = nullptr; - delete[] m_dataLight; - m_dataLight = nullptr; - delete[] m_dataSkyLight; - m_dataSkyLight = nullptr; } Block &Section::GetBlock(Vector pos) { - return m_blocks[pos.y * 256 + pos.z * 16 + pos.x]; + return blocks[pos.y * 256 + pos.z * 16 + pos.x]; +} + +Block Section::GetBlock(Vector pos) const +{ + return blocks[pos.y * 256 + pos.z * 16 + pos.x]; } double totalParsingTime = 0; -void Section::Parse() { - if (!m_blocks.empty()) - return; - - long long *longArray = reinterpret_cast<long long *>(m_dataBlocks); - for (size_t i = 0; i < m_dataBlocksLen / 8; i++) - endswap(&longArray[i]); - std::vector<unsigned short> blocks; - blocks.reserve(4096); - { - auto begin = std::chrono::steady_clock::now(); - int bitPos = 0; - unsigned short t = 0; - for (size_t i = 0; i < m_dataBlocksLen; i++) { - for (int j = 0; j < 8; j++) { - t |= (m_dataBlocks[i] & 0x01) ? 0x80 : 0x00; - t >>= 1; - m_dataBlocks[i] >>= 1; - bitPos++; - if (bitPos >= m_bitsPerBlock) { - bitPos = 0; - t >>= m_bitsPerBlock - 1; - blocks.push_back(t); - t = 0; - } - } - } - auto end = std::chrono::steady_clock::now(); - std::chrono::duration<double, std::milli> time = end - begin; - totalParsingTime += time.count(); - } - std::vector<byte> light; - light.reserve(4096); - for (int i = 0; i < 2048; i++) { - byte t = m_dataLight[i]; - byte first = t & 0b11110000; - byte second = t >> 4; - light.push_back(first); - light.push_back(second); - } - for (int i = 0; i < 4096; i++) { - unsigned short blockId = m_palette.size() > 0 ? m_palette[blocks[i]] : blocks[i]; - Block block(blockId >> 4, blockId & 0xF); - m_blocks.push_back(block); - } - delete[] m_dataBlocks; - m_dataBlocksLen = 0; - m_dataBlocks = nullptr; - delete[] m_dataLight; - m_dataLight = nullptr; - delete[] m_dataSkyLight; - m_dataSkyLight = nullptr; - - parseWaiter.notify_all(); +//void Section::Parse() { +// if (!m_blocks.empty()) +// return; +// +// long long *longArray = reinterpret_cast<long long *>(m_dataBlocks); +// for (size_t i = 0; i < m_dataBlocksLen / 8; i++) +// endswap(&longArray[i]); +// std::vector<unsigned short> blocks; +// blocks.reserve(4096); +// { +// auto begin = std::chrono::steady_clock::now(); +// int bitPos = 0; +// unsigned short t = 0; +// for (size_t i = 0; i < m_dataBlocksLen; i++) { +// for (int j = 0; j < 8; j++) { +// t |= (m_dataBlocks[i] & 0x01) ? 0x80 : 0x00; +// t >>= 1; +// m_dataBlocks[i] >>= 1; +// bitPos++; +// if (bitPos >= m_bitsPerBlock) { +// bitPos = 0; +// t >>= m_bitsPerBlock - 1; +// blocks.push_back(t); +// t = 0; +// } +// } +// } +// auto end = std::chrono::steady_clock::now(); +// std::chrono::duration<double, std::milli> time = end - begin; +// totalParsingTime += time.count(); +// } +// std::vector<byte> light; +// light.reserve(4096); +// for (int i = 0; i < 2048; i++) { +// byte t = m_dataLight[i]; +// byte first = t & 0b11110000; +// byte second = t >> 4; +// light.push_back(first); +// light.push_back(second); +// } +// for (int i = 0; i < 4096; i++) { +// unsigned short blockId = m_palette.size() > 0 ? m_palette[blocks[i]] : blocks[i]; +// Block block(blockId >> 4, blockId & 0xF); +// m_blocks.push_back(block); +// } +// delete[] m_dataBlocks; +// m_dataBlocksLen = 0; +// m_dataBlocks = nullptr; +// delete[] m_dataLight; +// m_dataLight = nullptr; +// delete[] m_dataSkyLight; +// m_dataSkyLight = nullptr; +// +// parseWaiter.notify_all(); +//} + +Section::Section(PackedSection data) +{ + worldPosition = data.position; + + long long *longArray = reinterpret_cast<long long *>(data.blocks.data()); + for (size_t i = 0; i < data.blocks.size() / 8; i++) + endswap(&longArray[i]); + std::vector<unsigned short> blocks; + blocks.reserve(4096); + { + auto begin = std::chrono::steady_clock::now(); + int bitPos = 0; + unsigned short t = 0; + for (size_t i = 0; i < data.blocks.size(); i++) { + for (int j = 0; j < 8; j++) { + t |= (data.blocks.data()[i] & 0x01) ? 0x80 : 0x00; + t >>= 1; + data.blocks.data()[i] >>= 1; + bitPos++; + if (bitPos >= data.bitsPerBlock) { + bitPos = 0; + t >>= data.bitsPerBlock - 1; + blocks.push_back(t); + t = 0; + } + } + } + auto end = std::chrono::steady_clock::now(); + std::chrono::duration<double, std::milli> time = end - begin; + totalParsingTime += time.count(); + } + std::vector<byte> light; + light.reserve(4096); + for (int i = 0; i < 2048; i++) { + byte t = data.light[i]; + byte first = t & 0b11110000; + byte second = t >> 4; + light.push_back(first); + light.push_back(second); + } + for (int i = 0; i < 4096; i++) { + unsigned short blockId = data.palette.size() > 0 ? data.palette[blocks[i]] : blocks[i]; + Block block(blockId >> 4, blockId & 0xF); + this->blocks.push_back(block); + } } Section &Section::operator=(Section other) { @@ -101,47 +124,42 @@ Section &Section::operator=(Section other) { void swap(Section &a, Section &b) { using std::swap; - swap(a.m_dataBlocksLen, b.m_dataBlocksLen); - swap(a.m_dataBlocks, b.m_dataBlocks); - swap(a.m_dataLight, b.m_dataLight); - swap(a.m_dataSkyLight, b.m_dataSkyLight); - swap(a.m_blocks, b.m_blocks); - swap(a.m_palette, b.m_palette); - swap(a.m_bitsPerBlock, b.m_bitsPerBlock); + swap(a.blocks, b.blocks); } Section::Section(const Section &other) { - worldPosition = other.worldPosition; - m_dataBlocksLen = other.m_dataBlocksLen; - if (other.m_blocks.empty()) { - m_dataBlocks = new byte[m_dataBlocksLen]; - std::copy(other.m_dataBlocks, other.m_dataBlocks + m_dataBlocksLen, m_dataBlocks); - - m_dataLight = new byte[2048]; - std::copy(other.m_dataLight, other.m_dataLight + 2048, m_dataLight); - - if (other.m_dataSkyLight) { - m_dataSkyLight = new byte[2048]; - std::copy(other.m_dataSkyLight, other.m_dataSkyLight + 2048, m_dataSkyLight); - } - } else { - std::copy(other.m_blocks.begin(), other.m_blocks.end(), std::back_inserter(m_blocks)); - } - - m_palette = other.m_palette; - m_bitsPerBlock = other.m_bitsPerBlock; + worldPosition = other.worldPosition; + this->blocks = other.blocks; + //std::copy(other.blocks.begin(), other.blocks.end(), std::back_inserter(blocks)); } -Vector Section::GetPosition() { +Vector Section::GetPosition() const { return worldPosition; } -size_t Section::GetHash() { - if (m_blocks.empty()) return 0; +size_t Section::GetHash() const { + if (blocks.empty()) return 0; - unsigned char *from = reinterpret_cast<unsigned char *>(m_blocks.data()); - size_t length = m_blocks.size() * sizeof(Block); + const unsigned char *from = reinterpret_cast<const unsigned char *>(blocks.data()); + size_t length = blocks.size() * sizeof(Block); std::string str(from, from + length); return std::hash<std::string>{}(str); -}
\ No newline at end of file +} + +PackedSection::PackedSection(Vector position, byte * dataBlocks, size_t dataBlocksLength, byte * dataLight, byte * dataSky, byte bitsPerBlock, std::vector<unsigned short> palette) +{ + this->position = position; + + this->palette = palette; + + this->bitsPerBlock = bitsPerBlock; + + blocks.assign(dataBlocks, dataBlocks + dataBlocksLength); + + light.assign(dataLight, dataLight + 2048); + + if (dataSky != nullptr) { + sky.assign(dataSky, dataSky + 2048); + } +} diff --git a/src/Section.hpp b/src/Section.hpp index f40fdf9..5422cf3 100644 --- a/src/Section.hpp +++ b/src/Section.hpp @@ -15,37 +15,43 @@ const int SECTION_WIDTH = 16; const int SECTION_LENGTH = 16; const int SECTION_HEIGHT = 16; -class Section { - std::vector<unsigned short> m_palette; - byte *m_dataBlocks = nullptr; - size_t m_dataBlocksLen; - byte *m_dataLight = nullptr; - byte *m_dataSkyLight = nullptr; - byte m_bitsPerBlock = 0; - std::vector<Block> m_blocks; - std::condition_variable parseWaiter; +struct PackedSection { + Vector position; + + int bitsPerBlock; + + std::vector<unsigned short> palette; + + std::vector<unsigned char> blocks; + std::vector<unsigned char> light; + std::vector<unsigned char> sky; - Section(); + PackedSection(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, + std::vector<unsigned short> palette); +}; + +class Section { + std::vector<Block> blocks; Vector worldPosition; public: - void Parse(); - - Section(Vector position, byte *dataBlocks, size_t dataBlocksLength, byte *dataLight, byte *dataSky, byte bitsPerBlock, - std::vector<unsigned short> palette); + + Section(PackedSection data); ~Section(); Block &GetBlock(Vector pos); + Block GetBlock(Vector pos) const; + Section &operator=(Section other); friend void swap(Section &a, Section &b); Section(const Section &other); - Vector GetPosition(); + Vector GetPosition() const; - size_t GetHash(); + size_t GetHash() const; };
\ No newline at end of file diff --git a/src/World.cpp b/src/World.cpp index dda7058..44816e7 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -7,10 +7,20 @@ void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { for (int i = 0; i < 16; i++) { if (bitmask[i]) { Vector chunkPosition = Vector(packet->ChunkX, i, packet->ChunkZ); - Section section = ParseSection(&chunkData, chunkPosition); - parseMutex.lock(); + PackedSection section = ParseSection(&chunkData, chunkPosition); + auto it = sections.find(chunkPosition); + if (it == sections.end()) { + sections.insert(std::make_pair(chunkPosition, section)); + } + else { + using std::swap; + swap(it->second, section); + } + EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ chunkPosition }); + + /*parseMutex.lock(); toParse.push(section); - parseMutex.unlock(); + parseMutex.unlock();*/ /*section.Parse(); sectionMutexes[chunkPosition].lock(); auto it = sections.find(chunkPosition); @@ -27,7 +37,7 @@ void World::ParseChunkData(std::shared_ptr<PacketChunkData> packet) { } } -Section World::ParseSection(StreamInput *data, Vector position) { +PackedSection World::ParseSection(StreamInput *data, Vector position) { unsigned char bitsPerBlock = data->ReadUByte(); int paletteLength = data->ReadVarInt(); std::vector<unsigned short> palette; @@ -40,10 +50,10 @@ Section World::ParseSection(StreamInput *data, Vector position) { std::vector<unsigned char> skyLight; if (dimension == 0) skyLight = data->ReadByteArray(4096 / 2); - return Section(position, dataArray.data(), dataArray.size(), blockLight.data(), + return PackedSection(position, dataArray.data(), dataArray.size(), blockLight.data(), (skyLight.size() > 0 ? skyLight.data() : nullptr), bitsPerBlock, palette); } - +/* void World::ParserFunc() { LoopExecutionTimeController timer(std::chrono::milliseconds(32)); @@ -74,14 +84,30 @@ void World::ParserFunc() timer.Update(); } } - +*/ World::~World() { - isRunning = false; - parser.join(); +} + +Block & World::GetBlock(Vector worldPosition) +{ + Vector sectionPos(std::floor(worldPosition.x / 16.0), std::floor(worldPosition.y / 16.0), std::floor(worldPosition.z / 16.0)); + auto sectionIt = sections.find(sectionPos); + if (sectionIt != sections.end()) { + Section section(sectionIt->second); + auto result = cachedSections.insert(std::make_pair(sectionPos, section)); + sections.erase(sectionIt); + } + auto it = cachedSections.find(sectionPos); + if (it == cachedSections.end()) { + static Block fallbackBlock; + return fallbackBlock; + } + Section& section = it->second; + Block& block = section.GetBlock(worldPosition - sectionPos * 16); + return block; } World::World() { - parser = std::thread(&World::ParserFunc, this); } bool World::isPlayerCollides(double X, double Y, double Z) { @@ -95,14 +121,13 @@ bool World::isPlayerCollides(double X, double Y, double Z) { Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z + 1), Vector(PlayerChunk.x, PlayerChunk.y, PlayerChunk.z - 1), }; - std::vector<std::map<Vector, Section>::iterator> closestSections; + std::vector<Vector> closestSections; for (auto &coord:closestSectionsCoordinates) { - auto it = sections.find(coord); - if (it != sections.end()) - closestSections.push_back(it); + if (sections.find(coord) != sections.end()) + closestSections.push_back(coord); + else if (cachedSections.find(coord) != cachedSections.end()) + closestSections.push_back(coord); } - if (closestSections.empty()) - return false; for (auto &it:closestSections) { @@ -118,15 +143,16 @@ bool World::isPlayerCollides(double X, double Y, double Z) { playerColl.z = Z - PlayerLength / 2.0; playerColl.l = PlayerLength; + const Section §ion = this->GetSection(it); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { - Block block = it->second.GetBlock(Vector(x, y, z)); + Block block = section.GetBlock(Vector(x, y, z)); if (block.id == 0 || block.id == 31) continue; - AABB blockColl{(x + it->first.x * 16.0), - (y + it->first.y * 16.0), - (z + it->first.z * 16.0), 1, 1, 1}; + AABB blockColl{(x + it.x * 16.0), + (y + it.y * 16.0), + (z + it.z * 16.0), 1, 1, 1}; if (TestCollision(playerColl, blockColl)) return true; } @@ -136,31 +162,30 @@ bool World::isPlayerCollides(double X, double Y, double Z) { return false; } -Block &World::GetBlock(Vector pos) { - Vector sectionPos (floor(pos.x / 16.0f),floor(pos.y / 16.0f),floor(pos.z/16.0f)); - Vector inSectionPos = pos - (sectionPos * 16u); - if (sections.find(sectionPos)==sections.end()){ - static Block block(0,0); - return block; - } - sectionMutexes[sectionPos].lock(); - Block& block = sections.find(sectionPos)->second.GetBlock(inSectionPos); - sectionMutexes[sectionPos].unlock(); - return block; -} - std::vector<Vector> World::GetSectionsList() { std::vector<Vector> sectionsList; for (auto& it:sections) { sectionsList.push_back(it.first); } + for (auto& it : cachedSections) { + if (std::find(sectionsList.begin(), sectionsList.end(), it.first) == sectionsList.end()) + sectionsList.push_back(it.first); + } return sectionsList; } -Section &World::GetSection(Vector sectionPos) { - sectionMutexes[sectionPos].lock(); - sectionMutexes[sectionPos].unlock(); - return sections.find(sectionPos)->second; +const Section &World::GetSection(Vector sectionPos) { + auto result = cachedSections.find(sectionPos); + if (result == cachedSections.end()) { + auto it = sections.find(sectionPos); + if (it == sections.end()) + LOG(ERROR) << "BAD"; + Section section(it->second); + auto result = cachedSections.insert(std::make_pair(sectionPos, section)); + return result.first->second; + } else { + return result->second; + } } glm::vec3 World::Raycast(glm::vec3 position, glm::vec3 direction, float maxLength, float minPrecision) { @@ -169,10 +194,12 @@ glm::vec3 World::Raycast(glm::vec3 position, glm::vec3 direction, float maxLengt void World::UpdatePhysics(float delta) { - delta /= 5; + //delta /= 5; + entitiesMutex.lock(); for (auto& it : entities) { it.pos = it.pos + it.vel * delta; } + entitiesMutex.unlock(); } //Faces: 14 650 653 //Models: 937.641.792 Bytes x64 @@ -181,26 +208,32 @@ void World::UpdatePhysics(float delta) Entity & World::GetEntity(unsigned int EntityId) { + entitiesMutex.lock(); for (auto& it : entities) { if (it.entityId == EntityId) { + entitiesMutex.unlock(); return it; } } + entitiesMutex.unlock(); static Entity fallback; return fallback; } std::vector<unsigned int> World::GetEntitiesList() { + entitiesMutex.lock(); std::vector<unsigned int> ret; for (auto& it : entities) { ret.push_back(it.entityId); } + entitiesMutex.unlock(); return ret; } void World::AddEntity(Entity entity) { + entitiesMutex.lock(); for (auto& it : entities) { if (it.entityId == entity.entityId) { LOG(ERROR) << "Adding already existing entity" << entity.entityId; @@ -208,5 +241,44 @@ void World::AddEntity(Entity entity) } } entities.push_back(entity); + entitiesMutex.unlock(); +} + +void World::DeleteEntity(unsigned int EntityId) +{ + entitiesMutex.lock(); + auto it = entities.begin(); + for (; it != entities.end(); ++it) { + if (it->entityId == EntityId) { + break; + } + } + if (it != entities.end()) + entities.erase(it); + entitiesMutex.unlock(); +} +void World::ParseChunkData(std::shared_ptr<PacketBlockChange> packet) { + Block& block = this->GetBlock(packet->Position); + block = Block(packet->BlockId >> 4, packet->BlockId & 15); + Vector sectionPos(std::floor(packet->Position.x / 16.0), std::floor(packet->Position.y / 16.0), std::floor(packet->Position.z / 16.0)); + EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos }); } + +void World::ParseChunkData(std::shared_ptr<PacketMultiBlockChange> packet) { + std::vector<Vector> changedSections; + for (auto& it : packet->Records) { + int x = (it.HorizontalPosition >> 4 & 15) + (packet->ChunkX * 16); + int y = it.YCoordinate; + int z = (it.HorizontalPosition & 15) + (packet->ChunkZ * 16); + Vector worldPos(x, y, z); + Block& block = GetBlock(worldPos); + block = Block(it.BlockId >> 4, it.BlockId & 15); + + Vector sectionPos(packet->ChunkX, std::floor(it.YCoordinate / 16.0), packet->ChunkZ); + if (std::find(changedSections.begin(), changedSections.end(), sectionPos) == changedSections.end()) + changedSections.push_back(sectionPos); + } + for (auto& sectionPos: changedSections) + EventAgregator::PushEvent(EventType::ChunkChanged, ChunkChangedData{ sectionPos }); +}
\ No newline at end of file diff --git a/src/World.hpp b/src/World.hpp index 06155cf..a90d437 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -15,20 +15,18 @@ #include "Vector.hpp" class World { - std::map<Vector, Section> sections; - std::map<Vector, std::mutex> sectionMutexes; - int dimension = 0; + int dimension = 0; + std::map<Vector, PackedSection> sections; + std::map<Vector, Section> cachedSections; - Section ParseSection(StreamInput *data, Vector position); + PackedSection ParseSection(StreamInput *data, Vector position); - void ParserFunc(); + std::vector<Entity> entities; + + std::mutex entitiesMutex; - std::queue<Section> toParse; - std::mutex parseMutex; + Block& GetBlock(Vector worldPosition); - bool isRunning = true; - std::thread parser; - public: World(); @@ -36,17 +34,17 @@ public: void ParseChunkData(std::shared_ptr<PacketChunkData> packet); - bool isPlayerCollides(double X, double Y, double Z); + void ParseChunkData(std::shared_ptr<PacketBlockChange> packet); - Block &GetBlock(Vector pos); + void ParseChunkData(std::shared_ptr<PacketMultiBlockChange> packet); - std::vector<Vector> GetSectionsList(); + bool isPlayerCollides(double X, double Y, double Z); - Section &GetSection(Vector sectionPos); + std::vector<Vector> GetSectionsList(); - glm::vec3 Raycast(glm::vec3 position, glm::vec3 direction, float maxLength = 1000.0f, float minPrecision = 0.01f); + const Section &GetSection(Vector sectionPos); - std::vector<Entity> entities; + glm::vec3 Raycast(glm::vec3 position, glm::vec3 direction, float maxLength = 1000.0f, float minPrecision = 0.01f); void UpdatePhysics(float delta); @@ -55,4 +53,6 @@ public: std::vector<unsigned int> GetEntitiesList(); void AddEntity(Entity entity); + + void DeleteEntity(unsigned int EntityId); };
\ No newline at end of file |