summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Event.hpp16
-rw-r--r--src/GameState.cpp26
-rw-r--r--src/Network.cpp5
-rw-r--r--src/Packet.hpp50
-rw-r--r--src/Renderer.cpp8
-rw-r--r--src/Renderer.hpp4
-rw-r--r--src/RendererEntity.cpp17
-rw-r--r--src/RendererSection.cpp172
-rw-r--r--src/RendererWorld.cpp182
-rw-r--r--src/RendererWorld.hpp6
-rw-r--r--src/Section.cpp250
-rw-r--r--src/Section.hpp38
-rw-r--r--src/World.cpp148
-rw-r--r--src/World.hpp32
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 &section = world->GetSection(sectionPosition);
+ const Section &section = 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 &section = 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