summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaG1924 <12997935+LaG1924@users.noreply.github.com>2018-03-16 17:19:18 +0100
committerLaG1924 <12997935+LaG1924@users.noreply.github.com>2018-03-16 17:19:18 +0100
commita493d1521a7f6ba19ce411598d6f8814bd2111f5 (patch)
tree65ff2fbf8b7d79ff57e2b8eabe268b1931006622
parentOptimized light parsing (diff)
downloadAltCraft-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.cpp140
-rw-r--r--src/RendererSectionData.hpp17
-rw-r--r--src/RendererWorld.cpp20
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> &sectionsList, 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 &sectionPos, 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 &sections, 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 &sectionPos) {
- const Section& section = world->GetSection(sectionPos);
+std::array<BlockId, 4096> SetBlockIdData(const SectionsData &sections) {
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 &sections)
{
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 &section = 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), &section, xp, xn, yp, yn, zp, zn);
- unsigned char skyLight = world->GetBlockSkyLight(Vector(x, y, z), &section, 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 &sections); \ 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));