diff options
author | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2018-03-16 17:19:18 +0100 |
---|---|---|
committer | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2018-03-16 17:19:18 +0100 |
commit | a493d1521a7f6ba19ce411598d6f8814bd2111f5 (patch) | |
tree | 65ff2fbf8b7d79ff57e2b8eabe268b1931006622 | |
parent | Optimized light parsing (diff) | |
download | AltCraft-a493d1521a7f6ba19ce411598d6f8814bd2111f5.tar AltCraft-a493d1521a7f6ba19ce411598d6f8814bd2111f5.tar.gz AltCraft-a493d1521a7f6ba19ce411598d6f8814bd2111f5.tar.bz2 AltCraft-a493d1521a7f6ba19ce411598d6f8814bd2111f5.tar.lz AltCraft-a493d1521a7f6ba19ce411598d6f8814bd2111f5.tar.xz AltCraft-a493d1521a7f6ba19ce411598d6f8814bd2111f5.tar.zst AltCraft-a493d1521a7f6ba19ce411598d6f8814bd2111f5.zip |
-rw-r--r-- | src/RendererSectionData.cpp | 140 | ||||
-rw-r--r-- | src/RendererSectionData.hpp | 17 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 20 |
3 files changed, 133 insertions, 44 deletions
diff --git a/src/RendererSectionData.cpp b/src/RendererSectionData.cpp index e3c4870..f7f0baa 100644 --- a/src/RendererSectionData.cpp +++ b/src/RendererSectionData.cpp @@ -6,7 +6,6 @@ #include "World.hpp" #include "AssetManager.hpp" -#include "Section.hpp" inline const BlockId& GetBlockId(const Vector& pos, const std::array<BlockId, 4096> &blockIdData) { return blockIdData[pos.y * 256 + pos.z * 16 + pos.x]; @@ -16,7 +15,7 @@ inline const BlockId& GetBlockId(int x, int y, int z, const std::array<BlockId, return blockIdData[y * 256 + z * 16 + x]; } -void AddFacesByBlockModel(const std::vector<Vector> §ionsList, World *world, Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight, const std::array<unsigned char, 16 * 16 * 16>& visibility, std::string &textureName, RendererSectionData &data) { +void AddFacesByBlockModel(Vector blockPos, const BlockModel &model, glm::mat4 transform, unsigned char light, unsigned char skyLight, const std::array<unsigned char, 16 * 16 * 16>& visibility, std::string &textureName, RendererSectionData &data) { glm::mat4 elementTransform, faceTransform; for (const auto& element : model.Elements) { Vector t = element.to - element.from; @@ -158,14 +157,7 @@ const BlockModel* GetInternalBlockModel(const BlockId& id, std::vector<std::pair return idModels.back().second; } -std::array<unsigned char, 4096> GetBlockVisibilityData(World *world, const Vector §ionPos, const std::array<BlockId, 4096> &blockIdData, std::vector<std::pair<BlockId, const BlockModel *>> &idModels) { - const auto& sectionDown = world->GetSection(sectionPos + Vector(0, -1, 0)); - const auto& sectionUp = world->GetSection(sectionPos + Vector(0, +1, 0)); - const auto& sectionNorth = world->GetSection(sectionPos + Vector(0, 0, +1)); - const auto& sectionSouth = world->GetSection(sectionPos + Vector(0, 0, -1)); - const auto& sectionWest = world->GetSection(sectionPos + Vector(+1, 0, 0)); - const auto& sectionEast = world->GetSection(sectionPos + Vector(-1, 0, 0)); - +std::array<unsigned char, 4096> GetBlockVisibilityData(const SectionsData §ions, const std::array<BlockId, 4096> &blockIdData, std::vector<std::pair<BlockId, const BlockModel *>> &idModels) { std::array<unsigned char, 4096> arr; for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { @@ -180,12 +172,12 @@ std::array<unsigned char, 4096> GetBlockVisibilityData(World *world, const Vecto switch (y) { case 0: - blockIdDown = sectionDown.GetBlockId(Vector(x, 15, z)); + blockIdDown = sections.bottom.GetBlockId(Vector(x, 15, z)); blockIdUp = GetBlockId(x, 1, z, blockIdData); break; case 15: blockIdDown = GetBlockId(x, 14, z, blockIdData); - blockIdUp = sectionUp.GetBlockId(Vector(x, 0, z)); + blockIdUp = sections.top.GetBlockId(Vector(x, 0, z)); break; default: blockIdDown = GetBlockId(x, y - 1, z, blockIdData); @@ -196,10 +188,10 @@ std::array<unsigned char, 4096> GetBlockVisibilityData(World *world, const Vecto switch (z) { case 0: blockIdNorth = GetBlockId(x, y, 1, blockIdData); - blockIdSouth = sectionSouth.GetBlockId(Vector(x, y, 15)); + blockIdSouth = sections.south.GetBlockId(Vector(x, y, 15)); break; case 15: - blockIdNorth = sectionNorth.GetBlockId(Vector(x, y, 0)); + blockIdNorth = sections.north.GetBlockId(Vector(x, y, 0)); blockIdSouth = GetBlockId(x, y, 14, blockIdData); break; default: @@ -211,10 +203,10 @@ std::array<unsigned char, 4096> GetBlockVisibilityData(World *world, const Vecto switch (x) { case 0: blockIdWest = GetBlockId(1, y, z, blockIdData); - blockIdEast = sectionEast.GetBlockId(Vector(15, y, z)); + blockIdEast = sections.east.GetBlockId(Vector(15, y, z)); break; case 15: - blockIdWest = sectionWest.GetBlockId(Vector(0, y, z)); + blockIdWest = sections.west.GetBlockId(Vector(0, y, z)); blockIdEast = GetBlockId(14, y, z, blockIdData); break; default: @@ -244,43 +236,32 @@ std::array<unsigned char, 4096> GetBlockVisibilityData(World *world, const Vecto return arr; } -std::array<BlockId, 4096> SetBlockIdData(World* world, const Vector §ionPos) { - const Section& section = world->GetSection(sectionPos); +std::array<BlockId, 4096> SetBlockIdData(const SectionsData §ions) { std::array<BlockId, 4096> blockIdData; for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { - blockIdData[y * 256 + z * 16 + x] = section.GetBlockId(Vector(x, y, z)); + blockIdData[y * 256 + z * 16 + x] = sections.section.GetBlockId(Vector(x, y, z)); } } } return blockIdData; } -RendererSectionData ParseSection(World * world, Vector sectionPosition) +RendererSectionData ParseSection(const SectionsData §ions) { RendererSectionData data; std::vector<std::pair<BlockId, const BlockModel *>> idModels; - std::array<BlockId, 4096> blockIdData = SetBlockIdData(world, sectionPosition); - std::array<unsigned char, 4096> blockVisibility = GetBlockVisibilityData(world, sectionPosition, blockIdData, idModels); + std::array<BlockId, 4096> blockIdData = SetBlockIdData(sections); + std::array<unsigned char, 4096> blockVisibility = GetBlockVisibilityData(sections, blockIdData, idModels); std::string textureName; - - Section* yp = world->GetSectionPtr(sectionPosition + Vector(0, 1, 0)); - Section* yn = world->GetSectionPtr(sectionPosition + Vector(0, -1, 0)); - Section* xp = world->GetSectionPtr(sectionPosition + Vector(1, 0, 0)); - Section* xn = world->GetSectionPtr(sectionPosition + Vector(-1, 0, 0)); - Section* zp = world->GetSectionPtr(sectionPosition + Vector(0, 0, 1)); - Section* zn = world->GetSectionPtr(sectionPosition + Vector(0, 0, -1)); const std::map<BlockTextureId, glm::vec4> &textureAtlas = AssetManager::Instance().GetTextureAtlasIndexes(); - const Section §ion = world->GetSection(sectionPosition); - data.hash = section.GetHash(); - data.sectionPos = sectionPosition; + data.hash = sections.section.GetHash(); + data.sectionPos = sections.section.GetPosition(); - glm::mat4 baseOffset = glm::translate(glm::mat4(), (section.GetPosition() * 16).glm()), transform; - - auto sectionsList = world->GetSectionsList(); + glm::mat4 baseOffset = glm::translate(glm::mat4(), (sections.section.GetPosition() * 16).glm()), transform; for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { @@ -289,17 +270,16 @@ RendererSectionData ParseSection(World * world, Vector sectionPosition) if (block.id == 0) continue; - const bool useNewMethod = true; - + Vector vec(x, y, z); - transform = glm::translate(baseOffset, Vector(x, y, z).glm()); + transform = glm::translate(baseOffset, vec.glm()); - unsigned char light = world->GetBlockLight(Vector(x, y, z), §ion, xp, xn, yp, yn, zp, zn); - unsigned char skyLight = world->GetBlockSkyLight(Vector(x, y, z), §ion, xp, xn, yp, yn, zp, zn); + unsigned char light = sections.GetLight(vec); + unsigned char skyLight = sections.GetSkyLight(vec); const BlockModel* model = GetInternalBlockModel(block, idModels); if (model) { - AddFacesByBlockModel(sectionsList, world, Vector(x, y, z), *model, transform, light, skyLight, blockVisibility, textureName, data); + AddFacesByBlockModel(vec, *model, transform, light, skyLight, blockVisibility, textureName, data); } else { transform = glm::translate(transform, glm::vec3(0, 1, 0)); @@ -326,3 +306,81 @@ RendererSectionData ParseSection(World * world, Vector sectionPosition) return data; } + +unsigned char SectionsData::GetLight(const Vector & pos) const { + const Vector directions[] = { + Vector(0,0,0), + Vector(1,0,0), + Vector(-1,0,0), + Vector(0,1,0), + Vector(0,-1,0), + Vector(0,0,1), + Vector(0,0,-1), + }; + + unsigned char value = 0; + + for (const Vector &dir : directions) { + Vector vec = pos + dir; + unsigned char dirValue = 0; + + if (vec.x < 0 || vec.x > 15 || vec.y < 0 || vec.y > 15 || vec.z < 0 || vec.z > 15) { + if (vec.x < 0) + dirValue = east.GetBlockLight(Vector(15, vec.y, vec.z)); + if (vec.x > 15) + dirValue = west.GetBlockLight(Vector(0, vec.y, vec.z)); + if (vec.y < 0) + dirValue = bottom.GetBlockLight(Vector(vec.x, 15, vec.z)); + if (vec.y > 15) + dirValue = top.GetBlockLight(Vector(vec.x, 0, vec.z)); + if (vec.z < 0) + dirValue = south.GetBlockLight(Vector(vec.x, vec.y, 15)); + if (vec.z > 15) + dirValue = north.GetBlockLight(Vector(vec.x, vec.y, 0)); + } + else + dirValue = section.GetBlockLight(vec); + + value = _max(value, dirValue); + } + return value; +} + +unsigned char SectionsData::GetSkyLight(const Vector & pos) const { + const Vector directions[] = { + Vector(0,0,0), + Vector(1,0,0), + Vector(-1,0,0), + Vector(0,1,0), + Vector(0,-1,0), + Vector(0,0,1), + Vector(0,0,-1), + }; + + unsigned char value = 0; + + for (const Vector &dir : directions) { + Vector vec = pos + dir; + unsigned char dirValue = 0; + + if (vec.x < 0 || vec.x > 15 || vec.y < 0 || vec.y > 15 || vec.z < 0 || vec.z > 15) { + if (vec.x < 0) + dirValue = east.GetBlockSkyLight(Vector(15, vec.y, vec.z)); + if (vec.x > 15) + dirValue = west.GetBlockSkyLight(Vector(0, vec.y, vec.z)); + if (vec.y < 0) + dirValue = bottom.GetBlockSkyLight(Vector(vec.x, 15, vec.z)); + if (vec.y > 15) + dirValue = top.GetBlockSkyLight(Vector(vec.x, 0, vec.z)); + if (vec.z < 0) + dirValue = south.GetBlockSkyLight(Vector(vec.x, vec.y, 15)); + if (vec.z > 15) + dirValue = north.GetBlockSkyLight(Vector(vec.x, vec.y, 0)); + } + else + dirValue = section.GetBlockSkyLight(vec); + + value = _max(value, dirValue); + } + return value; +} diff --git a/src/RendererSectionData.hpp b/src/RendererSectionData.hpp index 42e1a06..134eef6 100644 --- a/src/RendererSectionData.hpp +++ b/src/RendererSectionData.hpp @@ -5,9 +5,24 @@ #include <glm/mat4x4.hpp> #include "Vector.hpp" +#include "Section.hpp" class World; +struct SectionsData { + Section section; + Section west; + Section east; + Section top; + Section bottom; + Section north; + Section south; + + unsigned char GetLight(const Vector &pos) const; + + unsigned char GetSkyLight(const Vector &pos) const; +}; + struct RendererSectionData { std::vector<glm::mat4> models; std::vector<glm::vec4> textures; @@ -18,4 +33,4 @@ struct RendererSectionData { bool forced = false; }; -RendererSectionData ParseSection(World *world, Vector sectionPosition);
\ No newline at end of file +RendererSectionData ParseSection(const SectionsData §ions);
\ No newline at end of file diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 64cdffc..50d1fce 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -28,7 +28,15 @@ void RendererWorld::WorkerFunction(size_t workerId) { if (result != sections.end()) { if (result->second.GetHash() != gs->world.GetSection(result->first).GetHash() || forced) { sectionsMutex.unlock(); - auto data = std::make_unique<RendererSectionData>(ParseSection(&gs->world, vec)); + SectionsData sections; + sections.section = gs->world.GetSection(vec); + sections.west = gs->world.GetSection(vec + Vector(1, 0, 0)); + sections.east = gs->world.GetSection(vec + Vector(-1, 0, 0)); + sections.top = gs->world.GetSection(vec + Vector(0, 1, 0)); + sections.bottom = gs->world.GetSection(vec + Vector(0, -1, 0)); + sections.north = gs->world.GetSection(vec + Vector(0, 0, 1)); + sections.south = gs->world.GetSection(vec + Vector(0, 0, -1)); + auto data = std::make_unique<RendererSectionData>(ParseSection(sections)); data->forced = true; renderDataMutex.lock(); renderData.push(std::move(data)); @@ -44,7 +52,15 @@ void RendererWorld::WorkerFunction(size_t workerId) { } else { sectionsMutex.unlock(); - auto data = std::make_unique<RendererSectionData>(ParseSection(&gs->world, vec)); + SectionsData sections; + sections.section = gs->world.GetSection(vec); + sections.west = gs->world.GetSection(vec + Vector(1, 0, 0)); + sections.east = gs->world.GetSection(vec + Vector(-1, 0, 0)); + sections.top = gs->world.GetSection(vec + Vector(0, 1, 0)); + sections.bottom = gs->world.GetSection(vec + Vector(0, -1, 0)); + sections.north = gs->world.GetSection(vec + Vector(0, 0, 1)); + sections.south = gs->world.GetSection(vec + Vector(0, 0, -1)); + auto data = std::make_unique<RendererSectionData>(ParseSection(sections)); data->forced = true; renderDataMutex.lock(); renderData.push(std::move(data)); |