From 145ba8e157f79db64203db9684af2e6ed33af075 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Sun, 3 Sep 2017 20:45:52 +0500 Subject: 2017-09-03 --- src/AssetManager.cpp | 157 ++++++++++++++++++++++++++++++++++- src/AssetManager.hpp | 77 ++++++++++++++++- src/Block.cpp | 6 +- src/Block.hpp | 4 +- src/Render.cpp | 9 +- src/RendererSection.cpp | 216 +++++++++++++++++++++++++++++++++++++++--------- src/RendererSection.hpp | 4 + src/RendererWorld.cpp | 8 +- src/Section.cpp | 8 +- src/Section.hpp | 4 +- src/Utility.cpp | 3 - src/Vector.hpp | 5 ++ src/World.cpp | 30 ++++--- src/World.hpp | 8 +- src/main.cpp | 13 ++- 15 files changed, 466 insertions(+), 86 deletions(-) diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 22dac8d..6e35160 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -1,5 +1,8 @@ #include -#include "AssetManager.hpp" +#include "AssetManager.hpp" +#include + +namespace fs = std::experimental::filesystem::v1; //const fs::path pathToAssets = "./assets/"; //const fs::path pathToAssetsList = "./items.json"; @@ -7,9 +10,12 @@ const std::string pathToAssetsList = "./items.json"; const std::string pathToTextureIndex = "./textures.json"; +const fs::path pathToModels = "./assets/minecraft/models/"; + AssetManager::AssetManager() { LoadIds(); LoadTextureResources(); + //LoadBlockModels(); } void AssetManager::LoadIds() { @@ -17,10 +23,10 @@ void AssetManager::LoadIds() { nlohmann::json index; in >> index; for (auto &it:index) { - int id = it["type"].get(); - int state = it["meta"].get(); + unsigned short id = it["type"].get(); + unsigned char state = it["meta"].get(); std::string blockName = it["text_type"].get(); - assetIds[blockName] = Block(id, state, 0, 0); + assetIds[blockName] = BlockId{ id, state }; } LOG(INFO) << "Loaded " << assetIds.size() << " ids"; } @@ -186,3 +192,146 @@ AssetManager &AssetManager::Instance() { static AssetManager assetManager; return assetManager; } + +const BlockModel *AssetManager::GetBlockModelByBlockId(BlockId block) { + std::string blockName = ""; + for (const auto& it : assetIds) { + if (BlockId{ it.second.id,0 } == BlockId{ block.id,0 }) { + blockName = it.first; + break; + } + } + + blockName = "block/" + blockName; + + if (blockName == "" || models.find(blockName) == models.end()) + return nullptr; + + return &models[blockName]; +} + +void AssetManager::LoadBlockModels() { + + std::function parseModel = [&](std::string ModelName) { + fs::path ModelPath = pathToModels / fs::path(ModelName + ".json"); + std::ifstream in(ModelPath); + if (!in.is_open()) + throw std::runtime_error("Trying to load unknown model \"" + ModelName + "\" at " + ModelPath.generic_string()); + nlohmann::json modelData; + in >> modelData; + BlockModel model; + + if (modelData.find("parent") != modelData.end()) { + if (models.find(modelData["parent"]) == models.end()) + parseModel(modelData["parent"].get()); + + model = models.find(modelData["parent"])->second; + } + + if (modelData.find("ambientocclusion") != modelData.end()) + model.AmbientOcclusion = modelData["ambientocclusion"].get(); + + //models.Display + + if (modelData.find("textures") != modelData.end()) { + for (nlohmann::json::iterator texture = modelData["textures"].begin(); texture != modelData["textures"].end(); ++texture) { + model.Textures[texture.key()] = texture.value().get(); + } + } + + if (modelData.find("elements") != modelData.end()) { + for (auto& it : modelData["elements"]) { + BlockModel::ElementData element; + + auto vec = it["from"]; + Vector from (vec[0].get(), vec[1].get(), vec[2].get()); + vec = it["to"]; + Vector to(vec[0].get(), vec[1].get(), vec[2].get()); + + element.from = from; + element.to = to; + + if (it.find("rotation") != it.end()) { + vec = it["rotation"]["origin"]; + Vector rotOrig(vec[0].get(), vec[1].get(), vec[2].get()); + + element.rotationOrigin = rotOrig; + element.rotationAxis = (it["rotation"]["axis"].get() == "x") ? BlockModel::ElementData::Axis::x : ((it["rotation"]["axis"].get() == "y") ? BlockModel::ElementData::Axis::y : BlockModel::ElementData::Axis::z); + element.rotationAngle = it["rotation"]["angle"].get(); + element.rotationRescale = it["rotation"]["recale"].get(); + } + + if (it.find("shade") != it.end()) + element.shade = it["shade"].get(); + + for (nlohmann::json::iterator faceIt = it["faces"].begin(); faceIt != it["faces"].end(); ++faceIt) { + auto face = faceIt.value(); + BlockModel::ElementData::FaceData faceData; + + BlockModel::ElementData::FaceDirection faceDir; + if (faceIt.key() == "down") + faceDir = BlockModel::ElementData::FaceDirection::down; + else if (faceIt.key() == "up") + faceDir = BlockModel::ElementData::FaceDirection::up; + else if (faceIt.key() == "north") + faceDir = BlockModel::ElementData::FaceDirection::north; + else if (faceIt.key() == "south") + faceDir = BlockModel::ElementData::FaceDirection::south; + else if (faceIt.key() == "west") + faceDir = BlockModel::ElementData::FaceDirection::west; + else if (faceIt.key() == "east") + faceDir = BlockModel::ElementData::FaceDirection::east; + + if (face.find("uv") != face.end()) { + BlockModel::ElementData::FaceData::Uv uv; + uv.x1 = face["uv"][0]; + uv.y1 = face["uv"][1]; + uv.x2 = face["uv"][2]; + uv.y2 = face["uv"][3]; + faceData.uv = uv; + } + + BlockModel::ElementData::FaceDirection cullface; + if (face.find("cullface") != face.end()) { + if (face["cullface"] == "down") + cullface = BlockModel::ElementData::FaceDirection::down; + else if (face["cullface"] == "up") + cullface = BlockModel::ElementData::FaceDirection::up; + else if (face["cullface"] == "north") + cullface = BlockModel::ElementData::FaceDirection::north; + else if (face["cullface"] == "south") + cullface = BlockModel::ElementData::FaceDirection::south; + else if (face["cullface"] == "west") + cullface = BlockModel::ElementData::FaceDirection::west; + else if (face["cullface"] == "east") + cullface = BlockModel::ElementData::FaceDirection::east; + faceData.cullface = cullface; + } + + faceData.texture = face["texture"].get(); + + if (face.find("rotation") != face.end()) + faceData.rotation = face["rotation"].get(); + + if (face.find("tintindex") != face.end()) + faceData.tintIndex = face["tintindex"]; + + element.faces[faceDir] = faceData; + } + + model.Elements.push_back(element); + } + } + + models.insert(std::make_pair(ModelName, model)); + }; + + parseModel("block/stone"); + + /*for (auto& dirEntry : fs::directory_iterator(pathToBlockModels)) { + if (dirEntry.path().extension() != ".json") + continue; + + parseModel(dirEntry.path().generic_string()); + }*/ +} \ No newline at end of file diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp index ca8bd35..96f9741 100644 --- a/src/AssetManager.hpp +++ b/src/AssetManager.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include #include @@ -9,6 +9,7 @@ #include "Block.hpp" #include "Texture.hpp" +#include "Vector.hpp" struct TextureCoordinates { TextureCoordinates(float x = -1, float y = -1, float w = -1, float h = -1) : x(x), y(y), w(w), h(h) {} @@ -25,6 +26,10 @@ struct TextureCoordinates { } double x, y, w, h; + + operator glm::vec4() const { + return glm::vec4(x, y, w, h); + } }; struct BlockTextureId { @@ -49,11 +54,75 @@ struct BlockTextureId { } }; +struct BlockModel { + bool AmbientOcclusion=true; + + enum DisplayVariants { + thirdperson_righthand, + thirdperson_lefthand, + firstperson_righthand, + firstperson_lefthand, + gui, + head, + ground, + fixed, + DisplayVariantsCount, + }; + struct DisplayData { + Vector rotation; + Vector translation; + Vector scale; + }; + std::map Display; + + std::map Textures; + + struct ElementData { + Vector from; + Vector to; + + Vector rotationOrigin = Vector(8, 8, 8); + enum Axis { + x, + y, + z, + } rotationAxis = Axis::x; + int rotationAngle = 0; + bool rotationRescale = false; + + bool shade = true; + + enum FaceDirection { + down, + up, + north, + south, + west, + east, + none, + }; + struct FaceData { + struct Uv { + int x1, y1, x2, y2; + } uv = { 0,0,0,0 }; + std::string texture; + FaceDirection cullface = FaceDirection::none; + int rotation = 0; + bool tintIndex = false; + + }; + std::map faces; + }; + + std::vector Elements; +}; + class AssetManager { Texture *textureAtlas; - std::map assetIds; + std::map assetIds; std::map assetTextures; std::map textureAtlasIndexes; + std::map models; public: AssetManager(); @@ -74,4 +143,8 @@ public: TextureCoordinates GetTextureByBlock(BlockTextureId block); static AssetManager& Instance(); + + const BlockModel *GetBlockModelByBlockId(BlockId block); + + void LoadBlockModels(); }; diff --git a/src/Block.cpp b/src/Block.cpp index 4c907d6..840dbcf 100644 --- a/src/Block.cpp +++ b/src/Block.cpp @@ -4,4 +4,8 @@ Block::~Block() {} Block::Block(unsigned short id, unsigned char state, unsigned char light, unsigned char sky) : id(id), state(state), light(light), sky (sky) {} -Block::Block() : id(0), state(0), light(0), sky(0) {} \ No newline at end of file +Block::Block() : id(0), state(0), light(0), sky(0) {} + +bool operator==(const BlockId& lhs, const BlockId &rhs) { + return (lhs.id == rhs.id) && (lhs.state == rhs.state); +} \ No newline at end of file diff --git a/src/Block.hpp b/src/Block.hpp index 6bd4e93..78c9cca 100644 --- a/src/Block.hpp +++ b/src/Block.hpp @@ -16,4 +16,6 @@ struct Block { struct BlockId { unsigned short id : 13; unsigned char state : 4; -}; \ No newline at end of file +}; + +bool operator==(const BlockId& lhs, const BlockId &rhs); \ No newline at end of file diff --git a/src/Render.cpp b/src/Render.cpp index 19e89f6..0504d0a 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -61,12 +61,15 @@ void Render::InitGlew() { SDL_GL_GetDrawableSize(window, &width, &height); glViewport(0, 0, width, height); glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); + /*glEnable(GL_CULL_FACE); glCullFace(GL_BACK); - glFrontFace(GL_CCW); + glFrontFace(GL_CCW);*/ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glCheckError(); + if (glActiveTexture == nullptr) { + throw std::runtime_error("GLEW initialization failed with unknown reason"); + } } void Render::PrepareToRendering() { @@ -138,11 +141,11 @@ void Render::HandleEvents() { break; } case SDL_WINDOWEVENT_FOCUS_GAINED: - HasFocus = true; break; case SDL_WINDOWEVENT_FOCUS_LOST: HasFocus = false; SetMouseCapture(false); + state = GlobalState::Paused; break; } break; diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index bb1a888..2b5fc1e 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -26,35 +26,6 @@ const GLuint magicUniqueConstant = 88375; GLuint RendererSection::VboVertices = magicUniqueConstant; GLuint RendererSection::VboUvs = magicUniqueConstant; -RendererSection::~RendererSection() { - if (Vao != 0) - glDeleteVertexArrays(1, &Vao); - - for (int i = 0; i < VBOCOUNT; i++) - if (Vbo[i] != 0) { - glBindBuffer(GL_ARRAY_BUFFER, Vbo[i]); - glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW); - } - - glDeleteBuffers(VBOCOUNT, Vbo); -} - -void RendererSection::Render(RenderState &renderState) { - renderState.SetActiveVao(Vao); - glDrawArraysInstanced(GL_TRIANGLES, 0, 6, numOfFaces); - glCheckError(); -} - -Vector RendererSection::GetPosition() -{ - return sectionPos; -} - -size_t RendererSection::GetHash() -{ - return hash; -} - RendererSection::RendererSection(RendererSectionData data) { if (VboVertices == magicUniqueConstant) { glGenBuffers(1, &VboVertices); @@ -160,9 +131,52 @@ RendererSection::RendererSection(RendererSection && other) { swap(*this, other); } -RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) { +RendererSection::~RendererSection() { + if (Vao != 0) + glDeleteVertexArrays(1, &Vao); + + for (int i = 0; i < VBOCOUNT; i++) + if (Vbo[i] != 0) { + glBindBuffer(GL_ARRAY_BUFFER, Vbo[i]); + glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STATIC_DRAW); + } + + glDeleteBuffers(VBOCOUNT, Vbo); +} + +void swap(RendererSection & lhs, RendererSection & rhs) { + std::swap(lhs.Vbo, rhs.Vbo); + std::swap(lhs.Vao, rhs.Vao); + std::swap(lhs.hash, rhs.hash); + std::swap(lhs.numOfFaces, rhs.numOfFaces); + std::swap(lhs.sectionPos, rhs.sectionPos); +} + +void RendererSection::Render(RenderState &renderState) { + renderState.SetActiveVao(Vao); + glDrawArraysInstanced(GL_TRIANGLES, 0, 6, numOfFaces); + glCheckError(); +} + +Vector RendererSection::GetPosition() +{ + return sectionPos; +} + +size_t RendererSection::GetHash() +{ + return hash; +} + +RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) { const std::map &textureAtlas = AssetManager::Instance().GetTextureAtlasIndexes(); - const Section §ion = world->GetSection(sectionPosition); + if (!world->GetSection(sectionPosition)) + return; + const Section §ion = *world->GetSection(sectionPosition); + hash = section.GetHash(); + sectionPos = sectionPosition; + + glm::mat4 baseOffset = glm::translate(glm::mat4(), (section.GetPosition() * 16).glm()),transform; auto sectionsList = world->GetSectionsList(); @@ -173,6 +187,19 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) if (block.id == 0) continue; + /*transform = glm::translate(baseOffset, Vector(x, y, z).glm()); + + const BlockModel* model = AssetManager::Instance().GetBlockModelByBlockId(block); + if (model ) { + this->AddFacesByBlockModel(world, Vector(x,y,z), *model, transform, section.GetBlockLight(Vector(x,y,z)),section.GetBlockSkyLight(Vector(x,y,z))); + } else { + transform = glm::translate(transform, glm::vec3(0, 1, 0)); + models.push_back(transform); + textures.push_back(glm::vec4(0.0546875, 0.00442477876106194690, 0.0078125, 0.00442477876106194690)); //Fallback TNT texture + colors.push_back(glm::vec3(0, 0, 0)); + lights.push_back(glm::vec2(16, 16)); + }*/ + auto testBlockNonExist = [&](Vector block) -> bool { Vector offset; if (block.x == -1) { @@ -197,7 +224,7 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) 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); + const Section& blockSection = *world->GetSection(sectionPosition + offset); return blockSection.GetBlockId(block).id == 0 || blockSection.GetBlockId(block).id == 31 || blockSection.GetBlockId(block).id == 18; } return section.GetBlockId(block).id == 0 || section.GetBlockId(block).id == 31 || section.GetBlockId(block).id == 18; @@ -332,18 +359,125 @@ RendererSectionData::RendererSectionData(World * world, Vector sectionPosition) } } } - } - hash = section.GetHash(); - sectionPos = sectionPosition; + } textures.shrink_to_fit(); models.shrink_to_fit(); colors.shrink_to_fit(); } -void swap(RendererSection & lhs, RendererSection & rhs) { - std::swap(lhs.Vbo, rhs.Vbo); - std::swap(lhs.Vao, rhs.Vao); - std::swap(lhs.hash, rhs.hash); - std::swap(lhs.numOfFaces, rhs.numOfFaces); - std::swap(lhs.sectionPos, rhs.sectionPos); +void RendererSectionData::AddFacesByBlockModel(World *world, Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight) { + glm::mat4 elementTransform, faceTransform; + for (const auto& element : model.Elements) { + VectorF elementSize(VectorF(element.to - element.from) / 16.0f); + VectorF elementOrigin(VectorF(element.from) / 16.0f); + elementTransform = glm::translate(transform, elementOrigin.glm()); + elementTransform = glm::scale(elementTransform, elementSize.glm()); + + for (const auto& face : element.faces) { + if (face.second.cullface != BlockModel::ElementData::FaceDirection::none) { + switch (face.second.cullface) { + case BlockModel::ElementData::FaceDirection::down: + if (TestBlockExists(world, blockPos - Vector(0, -1, 0))) + continue; + break; + case BlockModel::ElementData::FaceDirection::up: + if (TestBlockExists(world, blockPos - Vector(0, +1, 0))) + continue; + break; + case BlockModel::ElementData::FaceDirection::north: + if (TestBlockExists(world, blockPos - Vector(0, 0, -1))) + continue; + break; + case BlockModel::ElementData::FaceDirection::south: + if (TestBlockExists(world, blockPos - Vector(0, 0, +1))) + continue; + break; + case BlockModel::ElementData::FaceDirection::west: + if (TestBlockExists(world, blockPos - Vector(-1, 0, 0))) + continue; + break; + case BlockModel::ElementData::FaceDirection::east: + if (TestBlockExists(world, blockPos - Vector(+1, 0, 0))) + continue; + break; + } + } + + switch (face.first) { + case BlockModel::ElementData::FaceDirection::down: + faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 0)); + faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0, 0)); + faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1)); + break; + case BlockModel::ElementData::FaceDirection::up: + faceTransform = glm::translate(elementTransform, glm::vec3(0.0f, 1.0f, 0.0f)); + break; + case BlockModel::ElementData::FaceDirection::north: + faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 1)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f)); + faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1)); + faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1, 0, 0.0f)); + faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1.0f)); + break; + case BlockModel::ElementData::FaceDirection::south: + faceTransform = glm::translate(elementTransform, glm::vec3(1, 0, 0)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(-1.0f, 0.0f, 0.0f)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0.0f, -1.0f, 0.0f)); + break; + case BlockModel::ElementData::FaceDirection::west: + faceTransform = glm::translate(elementTransform, glm::vec3(1, 0, 0)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); + faceTransform = glm::rotate(faceTransform, glm::radians(180.0f), glm::vec3(1.0f, 0.0f, 0.0f)); + faceTransform = glm::translate(faceTransform, glm::vec3(0, 0, -1)); + break; + case BlockModel::ElementData::FaceDirection::east: + faceTransform = glm::translate(elementTransform, glm::vec3(0, 0, 0)); + faceTransform = glm::rotate(faceTransform, glm::radians(90.0f), glm::vec3(0, 0.0f, 1.0f)); + break; + } + models.push_back(faceTransform); + std::string textureName = face.second.texture; + while (textureName[0] == '#') { + textureName = model.Textures.find(std::string(textureName.begin()+1,textureName.end()))->second; + } + glm::vec4 texture = AssetManager::Instance().GetTextureByAssetName("minecraft/textures/" + textureName); + textures.push_back(texture); + colors.push_back(glm::vec3(0, 0, 0)); + lights.push_back(glm::vec2(light, skyLight)); + } + } } + +bool RendererSectionData::TestBlockExists(World *world, Vector blockPos) { + Vector section = sectionPos; + if (blockPos.x == -1) { + section = section - Vector(-1, 0, 0); + blockPos.x = 15; + } + else if (blockPos.x == 16) { + section = section - Vector(+1, 0, 0); + blockPos.x = 0; + } + else if (blockPos.y == -1) { + section = section - Vector(0, -1, 0); + blockPos.y = 15; + } + else if (blockPos.y == 16) { + section = section - Vector(0, +1, 0); + blockPos.y = 0; + } + else if (blockPos.z == -1) { + section = section - Vector(0, 0, -1); + blockPos.z = 15; + } + else if (blockPos.z == 16) { + section = section - Vector(0, 0, +1); + blockPos.z = 0; + } + auto ptr = world->GetSection(sectionPos); + if (!ptr) + return true; + + return ptr->GetBlockId(blockPos).id != 0; +} \ No newline at end of file diff --git a/src/RendererSection.hpp b/src/RendererSection.hpp index 12a169e..9931239 100644 --- a/src/RendererSection.hpp +++ b/src/RendererSection.hpp @@ -21,6 +21,10 @@ struct RendererSectionData { size_t hash; Vector sectionPos; + bool TestBlockExists(World *world, Vector blockPos); + + void AddFacesByBlockModel(World *world, Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight); + RendererSectionData(World *world, Vector sectionPosition); }; class RendererSection { diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index c90e1fb..a0cb8a7 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -13,7 +13,7 @@ void RendererWorld::WorkerFunction(size_t workerId) { sectionsMutex.lock(); auto result = sections.find(vec); if (result != sections.end()) { - if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash()) { + if (result->second.GetHash() != gs->world.GetSection(result->first)->GetHash()) { sectionsMutex.unlock(); RendererSectionData data(&gs->world, vec); renderDataMutex.lock(); @@ -85,8 +85,8 @@ void RendererWorld::UpdateAllSections(VectorF playerPos) } RendererWorld::RendererWorld(std::shared_ptr ptr):gs(ptr) { - MaxRenderingDistance = 4; - numOfWorkers = 4; + MaxRenderingDistance = 1; + numOfWorkers = 1; PrepareRender(); @@ -206,6 +206,8 @@ RendererWorld::~RendererWorld() { delete blockShader; delete entityShader; delete skyShader; + DebugInfo::renderSections = 0; + DebugInfo::readyRenderer = 0; } void RendererWorld::Render(RenderState & renderState) { diff --git a/src/Section.cpp b/src/Section.cpp index 9b4292b..554cdbf 100644 --- a/src/Section.cpp +++ b/src/Section.cpp @@ -93,17 +93,17 @@ BlockId Section::GetBlockId(Vector pos) const { return blockId; } -unsigned char Section::GetBlockLight(Vector pos) +unsigned char Section::GetBlockLight(Vector pos) const { int blockNumber = pos.y * 256 + pos.z * 16 + pos.x; - unsigned char lightValue = this->light[blockNumber]; + unsigned char lightValue = this->light[blockNumber / 2]; return (blockNumber % 2 == 0) ? (lightValue & 0xF) : (lightValue >> 4); } -unsigned char Section::GetBlockSkyLight(Vector pos) +unsigned char Section::GetBlockSkyLight(Vector pos) const { int blockNumber = pos.y * 256 + pos.z * 16 + pos.x; - unsigned char skyValue = this->sky[blockNumber]; + unsigned char skyValue = this->sky[blockNumber / 2]; return (blockNumber % 2 == 0) ? (skyValue & 0xF) : (skyValue >> 4); } diff --git a/src/Section.hpp b/src/Section.hpp index bda3584..7a7a3d0 100644 --- a/src/Section.hpp +++ b/src/Section.hpp @@ -37,9 +37,9 @@ public: BlockId GetBlockId(Vector pos) const; - unsigned char GetBlockLight(Vector pos); + unsigned char GetBlockLight(Vector pos) const; - unsigned char GetBlockSkyLight(Vector pos); + unsigned char GetBlockSkyLight(Vector pos) const; void SetBlockId(Vector pos, BlockId value); diff --git a/src/Utility.cpp b/src/Utility.cpp index 30561c4..8be82d6 100644 --- a/src/Utility.cpp +++ b/src/Utility.cpp @@ -29,9 +29,6 @@ GLenum glCheckError_(const char *file, int line) { break; } static int t = 0; - //t++; - if (t > 10) - LOG(FATAL); LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; } return errorCode; diff --git a/src/Vector.hpp b/src/Vector.hpp index c89154f..6389bbb 100644 --- a/src/Vector.hpp +++ b/src/Vector.hpp @@ -14,6 +14,11 @@ struct Vector3 { Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {} + template + Vector3(const Vector3 &rhs) : x(rhs.x), y(rhs.y), z(rhs.z) {} + + Vector3(Vector3 &&rhs) = default; + ~Vector3() = default; double GetLength() const { return std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2)); } diff --git a/src/World.cpp b/src/World.cpp index 8f6bb5c..19eddbf 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -14,6 +14,7 @@ void World::ParseChunkData(std::shared_ptr packet) { if (!sections.insert(std::make_pair(chunkPosition, section)).second) { LOG(ERROR) << "New chunk not created " << chunkPosition << " potential memory leak"; } + UpdateSectionList(); } else { using std::swap; swap(sections.at(chunkPosition), section); @@ -48,6 +49,7 @@ Section World::ParseSection(StreamInput *data, Vector position) { } World::~World() { + DebugInfo::totalSections = 0; } World::World() { @@ -86,7 +88,7 @@ bool World::isPlayerCollides(double X, double Y, double Z) { playerColl.z = Z - PlayerLength / 2.0; playerColl.l = PlayerLength; - const Section §ion = this->GetSection(it); + 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++) { @@ -105,24 +107,18 @@ bool World::isPlayerCollides(double X, double Y, double Z) { return false; } -std::vector World::GetSectionsList() { - std::vector sectionsList; - for (auto& it : sections) { - if (std::find(sectionsList.begin(), sectionsList.end(), it.first) == sectionsList.end()) - sectionsList.push_back(it.first); - } - return sectionsList; +const std::vector& World::GetSectionsList() { + return sectionsList; } static Section fallbackSection; -const Section &World::GetSection(Vector sectionPos) { +const Section* World::GetSection(Vector sectionPos) { auto result = sections.find(sectionPos); if (result == sections.end()) { - LOG(ERROR) << "Accessed not loaded section " << sectionPos; - return fallbackSection; + return nullptr; } else { - return result->second; + return &result->second; } } @@ -226,6 +222,14 @@ void World::ParseChunkData(std::shared_ptr packet) { } for (auto& it : toRemove) { EventAgregator::PushEvent(EventType::ChunkDeleted, ChunkDeletedData{ it->first }); - sections.erase(it); + sections.erase(it); + } + UpdateSectionList(); +} + +void World::UpdateSectionList() { + sectionsList.clear(); + for (auto& it : sections) { + sectionsList.push_back(it.first); } } \ No newline at end of file diff --git a/src/World.hpp b/src/World.hpp index a5cf60c..89c40d4 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -25,6 +25,10 @@ class World { std::mutex entitiesMutex; + std::vector sectionsList; + + void UpdateSectionList(); + public: World(); @@ -40,9 +44,9 @@ public: bool isPlayerCollides(double X, double Y, double Z); - std::vector GetSectionsList(); + const std::vector& GetSectionsList(); - const Section &GetSection(Vector sectionPos); + const Section* GetSection(Vector sectionPos); glm::vec3 Raycast(glm::vec3 position, glm::vec3 direction, float maxLength = 1000.0f, float minPrecision = 0.01f); diff --git a/src/main.cpp b/src/main.cpp index 9c38814..4130bf3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,17 +5,16 @@ #include "ThreadNetwork.hpp" const char *getTimeSinceProgramStart(void) { - static auto initialTime = std::chrono::steady_clock().now(); - auto now = std::chrono::steady_clock().now(); - std::chrono::duration seconds = now - initialTime; - static char buffer[30]; - sprintf(buffer, "%.2f", seconds.count()); - return buffer; + static auto initialTime = std::chrono::steady_clock().now(); + auto now = std::chrono::steady_clock().now(); + std::chrono::duration seconds = now - initialTime; + static char buffer[30]; + sprintf(buffer, "%.2f", seconds.count()); + return buffer; } INITIALIZE_EASYLOGGINGPP - #undef main int main(int argc, char** argv) { -- cgit v1.2.3