summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AssetManager.cpp155
-rw-r--r--src/AssetManager.hpp13
-rw-r--r--src/RendererSectionData.cpp169
3 files changed, 203 insertions, 134 deletions
diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp
index 8403700..bffc246 100644
--- a/src/AssetManager.cpp
+++ b/src/AssetManager.cpp
@@ -5,6 +5,7 @@
#include <nlohmann/json.hpp>
#include <easylogging++.h>
+#include <glm/gtc/matrix_transform.hpp>
#include "Texture.hpp"
@@ -22,6 +23,7 @@ AssetManager::AssetManager() {
LoadIds();
LoadTextureResources();
LoadBlockModels();
+ ParseBlockModels();
}
void AssetManager::LoadIds() {
@@ -331,7 +333,7 @@ void AssetManager::LoadBlockModels() {
faceData.uv = uv;
}
- BlockModel::ElementData::FaceDirection cullface = faceDir;
+ BlockModel::ElementData::FaceDirection cullface = BlockModel::ElementData::FaceDirection::none;
if (face.find("cullface") != face.end()) {
if (face["cullface"] == "down")
cullface = BlockModel::ElementData::FaceDirection::down;
@@ -374,7 +376,7 @@ void AssetManager::LoadBlockModels() {
std::string modelName = dirEntry.path().stem().generic_string();
parseModel("block/" + modelName);
- }
+ }
}
std::string AssetManager::GetAssetNameByBlockId(BlockId block) {
@@ -385,4 +387,153 @@ std::string AssetManager::GetAssetNameByBlockId(BlockId block) {
return it.first;
}
return "#NF";
+}
+
+void AssetManager::ParseBlockModels() {
+ std::string textureName;
+
+ for (auto &modelIt : models) {
+ const auto &modelName = modelIt.first;
+ auto &model = modelIt.second;
+
+ for (const auto& element : model.Elements) {
+ Vector t = element.to - element.from;
+ VectorF elementSize(VectorF(t.x, t.y, t.z) / 16.0f);
+ VectorF elementOrigin(VectorF(element.from.x, element.from.y, element.from.z) / 16.0f);
+
+ glm::mat4 elementTransform;
+
+ if (element.rotationAngle != 0) {
+ static const glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
+ static const glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
+ static const glm::vec3 zAxis(0.0f, 0.0f, 1.0f);
+
+ const glm::vec3 *targetAxis = nullptr;
+ switch (element.rotationAxis) {
+ case BlockModel::ElementData::Axis::x:
+ targetAxis = &xAxis;
+ break;
+ case BlockModel::ElementData::Axis::y:
+ targetAxis = &yAxis;
+ break;
+ case BlockModel::ElementData::Axis::z:
+ targetAxis = &zAxis;
+ break;
+ }
+
+ VectorF rotateOrigin(VectorF(element.rotationOrigin.x, element.rotationOrigin.y, element.rotationOrigin.z) / 16.0f);
+
+ glm::mat4 rotationMat;
+ rotationMat = glm::translate(rotationMat, rotateOrigin.glm());
+
+ rotationMat = glm::rotate(rotationMat, glm::radians((float)element.rotationAngle), *targetAxis);
+ if (element.rotationRescale) {
+ glm::vec3 scaleFactor{ 1.0f,1.0f,1.0f };
+ double coef = 1.0f / cos(glm::radians((double)element.rotationAngle));
+ switch (element.rotationAxis) {
+ case BlockModel::ElementData::Axis::x:
+ scaleFactor.y *= coef;
+ scaleFactor.z *= coef;
+ break;
+ case BlockModel::ElementData::Axis::y:
+ scaleFactor.x *= coef;
+ scaleFactor.z *= coef;
+ break;
+ case BlockModel::ElementData::Axis::z:
+ scaleFactor.x *= coef;
+ scaleFactor.y *= coef;
+ break;
+ }
+ rotationMat = glm::scale(rotationMat, scaleFactor);
+ }
+
+ rotationMat = glm::translate(rotationMat, -rotateOrigin.glm());
+
+ elementTransform = rotationMat * elementTransform;
+ }
+
+ elementTransform = glm::translate(elementTransform, elementOrigin.glm());
+ elementTransform = glm::scale(elementTransform, elementSize.glm());
+
+ for (const auto& face : element.faces) {
+ BlockModel::ParsedFace parsedFace;
+ parsedFace.visibility = face.second.cullface;
+
+ glm::mat4 faceTransform;
+ 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;
+ }
+ parsedFace.transform = faceTransform;
+ glm::vec4 texture;
+ textureName = face.second.texture;
+ if (model.Textures.empty()) {
+ texture = GetTextureByAssetName("minecraft/texture/blocks/tnt_side");
+ }
+ else {
+ while (textureName[0] == '#') {
+ textureName.erase(0, 1);
+ auto textureIt = model.Textures.find(textureName);
+ textureName = textureIt != model.Textures.end() ? textureIt->second : "minecraft/texture/blocks/tnt_side";
+ }
+ textureName.insert(0, "minecraft/textures/");
+ texture = GetTextureByAssetName(textureName);
+
+ if (!(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,16,0,16 }) && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,0,0 })
+ && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,16,16 })) {
+ double x = face.second.uv.x1;
+ double y = face.second.uv.x1;
+ double w = face.second.uv.x2 - face.second.uv.x1;
+ double h = face.second.uv.y2 - face.second.uv.y1;
+ x /= 16.0;
+ y /= 16.0;
+ w /= 16.0;
+ h /= 16.0;
+ double X = texture.x;
+ double Y = texture.y;
+ double W = texture.z;
+ double H = texture.w;
+
+ texture = glm::vec4{ X + x * W, Y + y * H, w * W , h * H };
+ }
+ }
+ parsedFace.texture = texture;
+ if (face.second.tintIndex)
+ parsedFace.color = glm::vec3(0.275, 0.63, 0.1);
+ else
+ parsedFace.color = glm::vec3(0, 0, 0);
+
+ model.parsedFaces.push_back(parsedFace);
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp
index 37031be..c386f7c 100644
--- a/src/AssetManager.hpp
+++ b/src/AssetManager.hpp
@@ -6,6 +6,8 @@
#include <GL/glew.h>
#include <glm/vec4.hpp>
+#include <glm/vec3.hpp>
+#include <glm/mat4x4.hpp>
#include "Vector.hpp"
#include "Block.hpp"
@@ -124,6 +126,15 @@ struct BlockModel {
};
std::vector<ElementData> Elements;
+
+ struct ParsedFace {
+ ElementData::FaceDirection visibility;
+ glm::mat4 transform;
+ glm::vec4 texture;
+ glm::vec3 color;
+ };
+
+ std::vector<ParsedFace> parsedFaces;
};
inline bool operator==(const BlockModel::ElementData::FaceData::Uv &lhs,
@@ -164,4 +175,6 @@ public:
void LoadBlockModels();
std::string GetAssetNameByBlockId(BlockId block);
+
+ void ParseBlockModels();
};
diff --git a/src/RendererSectionData.cpp b/src/RendererSectionData.cpp
index f7f0baa..96d78e0 100644
--- a/src/RendererSectionData.cpp
+++ b/src/RendererSectionData.cpp
@@ -15,137 +15,42 @@ inline const BlockId& GetBlockId(int x, int y, int z, const std::array<BlockId,
return blockIdData[y * 256 + z * 16 + x];
}
-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;
- VectorF elementSize(VectorF(t.x, t.y, t.z) / 16.0f);
- VectorF elementOrigin(VectorF(element.from.x, element.from.y, element.from.z) / 16.0f);
- elementTransform = transform;
-
- /*if (element.rotationAngle != 0) {
- const glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
- const glm::vec3 yAxis(0.0f, 1.0f, 0.0f);
- const glm::vec3 zAxis(0.0f, 0.0f, 1.0f);
- const glm::vec3 *targetAxis = nullptr;
- switch (element.rotationAxis) {
- case BlockModel::ElementData::Axis::x:
- targetAxis = &xAxis;
- break;
- case BlockModel::ElementData::Axis::y:
- targetAxis = &yAxis;
- break;
- case BlockModel::ElementData::Axis::z:
- targetAxis = &zAxis;
- break;
- }
- VectorF rotateOrigin(VectorF(element.rotationOrigin.x, element.rotationOrigin.y, element.rotationOrigin.z) / 16.0f);
- elementTransform = glm::translate(elementTransform, -rotateOrigin.glm());
- elementTransform = glm::rotate(elementTransform, glm::radians(float(45)), yAxis);
- elementTransform = glm::translate(elementTransform, rotateOrigin.glm());
- }*/
- elementTransform = glm::translate(elementTransform, elementOrigin.glm());
- elementTransform = glm::scale(elementTransform, elementSize.glm());
-
- for (const auto& face : element.faces) {
- if (face.second.cullface != BlockModel::ElementData::FaceDirection::none) {
- unsigned char visible = visibility[blockPos.y * 256 + blockPos.z * 16 + blockPos.x];
-
- switch (face.second.cullface) {
- case BlockModel::ElementData::FaceDirection::down:
- if (visible >> 0 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::up:
- if (visible >> 1 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::north:
- if (visible >> 2 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::south:
- if (visible >> 3 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::west:
- if (visible >> 4 & 0x1)
- continue;
- break;
- case BlockModel::ElementData::FaceDirection::east:
- if (visible >> 5 & 0x1)
- 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;
- }
- data.models.push_back(faceTransform);
- textureName = face.second.texture;
- while (textureName[0] == '#') {
- textureName.erase(0, 1);
- textureName = model.Textures.find(textureName)->second;
- }
- textureName.insert(0, "minecraft/textures/");
- glm::vec4 texture = AssetManager::Instance().GetTextureByAssetName(textureName);
-
- if (!(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,16,0,16 }) && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,0,0 })
- && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,16,16 })) {
- double x = face.second.uv.x1;
- double y = face.second.uv.x1;
- double w = face.second.uv.x2 - face.second.uv.x1;
- double h = face.second.uv.y2 - face.second.uv.y1;
- x /= 16.0;
- y /= 16.0;
- w /= 16.0;
- h /= 16.0;
- double X = texture.x;
- double Y = texture.y;
- double W = texture.z;
- double H = texture.w;
-
- texture = glm::vec4{ X + x * W, Y + y * H, w * W , h * H };
- }
- data.textures.push_back(texture);
- if (face.second.tintIndex)
- data.colors.push_back(glm::vec3(0.275, 0.63, 0.1));
- else
- data.colors.push_back(glm::vec3(0, 0, 0));
- data.lights.push_back(glm::vec2(light, skyLight));
- }
- }
+void AddFacesByBlockModel(RendererSectionData &data, const BlockModel &model, const glm::mat4 &transform, unsigned char visibility, unsigned char light, unsigned char skyLight) {
+ for (const auto &face : model.parsedFaces) {
+ if (face.visibility != BlockModel::ElementData::FaceDirection::none) {
+ switch (face.visibility) {
+ case BlockModel::ElementData::FaceDirection::down:
+ if (visibility >> 0 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::up:
+ if (visibility >> 1 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::north:
+ if (visibility >> 2 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::south:
+ if (visibility >> 3 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::west:
+ if (visibility >> 4 & 0x1)
+ continue;
+ break;
+ case BlockModel::ElementData::FaceDirection::east:
+ if (visibility >> 5 & 0x1)
+ continue;
+ break;
+ }
+ }
+
+ data.models.push_back(transform * face.transform);
+ data.textures.push_back(face.texture);
+ data.colors.push_back(face.color);
+ data.lights.push_back(glm::vec2(light, skyLight));
+ }
}
const BlockModel* GetInternalBlockModel(const BlockId& id, std::vector<std::pair<BlockId, const BlockModel *>> &idModels) {
@@ -279,7 +184,7 @@ RendererSectionData ParseSection(const SectionsData &sections)
const BlockModel* model = GetInternalBlockModel(block, idModels);
if (model) {
- AddFacesByBlockModel(vec, *model, transform, light, skyLight, blockVisibility, textureName, data);
+ AddFacesByBlockModel(data, *model, transform, blockVisibility[y * 256 + z * 16 + x], light, skyLight);
}
else {
transform = glm::translate(transform, glm::vec3(0, 1, 0));