From bc49bcbb795c45cdb91efc6b03d93e4202e766b2 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Mon, 20 Aug 2018 17:38:11 +0500 Subject: More correct face culling for rotated blocks --- src/AssetManager.cpp | 87 ++++++-------------------------- src/AssetManager.hpp | 4 +- src/Render.cpp | 5 +- src/RendererSectionData.cpp | 120 ++++++++++---------------------------------- 4 files changed, 48 insertions(+), 168 deletions(-) diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 2329e8d..9231bf3 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -505,7 +505,9 @@ BlockFaces &AssetManager::GetBlockModelByBlockId(BlockId block) { BlockFaces blockFaces; blockFaces.faces = GetAsset("/minecraft/models/block/error")->blockModel.parsedFaces; blockFaces.isBlock = GetAsset("/minecraft/models/block/error")->blockModel.IsBlock; - blockFaces.direction = FaceDirection::none; + for (int i = 0; i < FaceDirection::none; i++) { + blockFaces.faceDirectionVector[i] = FaceDirectionVector[i]; + } blockIdToBlockFaces.insert(std::make_pair(block, blockFaces)); return blockIdToBlockFaces.find(block)->second; } @@ -531,82 +533,25 @@ BlockFaces &AssetManager::GetBlockModelByBlockId(BlockId block) { BlockFaces blockFaces; blockFaces.faces = assetModel->blockModel.parsedFaces; blockFaces.isBlock = assetModel->blockModel.IsBlock; - blockFaces.direction = FaceDirection::west; + glm::mat4 transform; + + if (model.y != 0) { + blockFaces.transform = glm::translate(blockFaces.transform, glm::vec3(0.5f, 0.0f, 0.5f)); + blockFaces.transform = glm::rotate(blockFaces.transform, glm::radians((float)model.y), glm::vec3(0.0f, 1.0f, 0.0f)); + blockFaces.transform = glm::translate(blockFaces.transform, glm::vec3(-0.5f, 0.0f, -0.5f)); + transform = glm::rotate(transform, glm::radians((float)model.y), glm::vec3(0.0f, 1.0f, 0)); + } if (model.x != 0) { blockFaces.transform = glm::translate(blockFaces.transform, glm::vec3(0.0f, 0.5f, 0.5f)); blockFaces.transform = glm::rotate(blockFaces.transform, glm::radians((float)model.x), glm::vec3(1.0f, 0.0f, 0.0f)); blockFaces.transform = glm::translate(blockFaces.transform, glm::vec3(0.0f, -0.5f, -0.5f)); - switch (model.x) { - case 90: - blockFaces.direction = FaceDirection::down; - break; - case 180: - blockFaces.direction = FaceDirection::east; - break; - case 270: - blockFaces.direction = FaceDirection::up; - break; - default: - break; - } + transform = glm::rotate(transform, glm::radians((float)model.x), glm::vec3(1.0f, 0.0f, 0)); } - if (model.y != 0) { - blockFaces.transform = glm::translate(blockFaces.transform, glm::vec3(0.5f, 0.0f, 0.5f)); - blockFaces.transform = glm::rotate(blockFaces.transform, glm::radians((float)model.y), glm::vec3(0.0f, 1.0f, 0.0f)); - blockFaces.transform = glm::translate(blockFaces.transform, glm::vec3(-0.5f, 0.0f, -0.5f)); - switch (model.y) { - case 90: - switch (blockFaces.direction) { - case FaceDirection::west: - blockFaces.direction = FaceDirection::north; - break; - case FaceDirection::up: - blockFaces.direction = FaceDirection::up; - break; - case FaceDirection::east: - blockFaces.direction = FaceDirection::south; - break; - case FaceDirection::down: - blockFaces.direction = FaceDirection::down; - break; - } - break; - case 180: - switch (blockFaces.direction) { - case FaceDirection::west: - blockFaces.direction = FaceDirection::east; - break; - case FaceDirection::up: - blockFaces.direction = FaceDirection::up; - break; - case FaceDirection::east: - blockFaces.direction = FaceDirection::west; - break; - case FaceDirection::down: - blockFaces.direction = FaceDirection::down; - break; - } - break; - case 270: - switch (blockFaces.direction) { - case FaceDirection::west: - blockFaces.direction = FaceDirection::south; - break; - case FaceDirection::up: - blockFaces.direction = FaceDirection::up; - break; - case FaceDirection::east: - blockFaces.direction = FaceDirection::north; - break; - case FaceDirection::down: - blockFaces.direction = FaceDirection::down; - break; - } - break; - default: - break; - } + + for (int i = 0; i < FaceDirection::none; i++) { + glm::vec4 vec = transform * glm::vec4(FaceDirectionVector[i].glm(), 1.0f); + blockFaces.faceDirectionVector[i] = Vector(roundf(vec.x), roundf(vec.y), roundf(vec.z)); } blockIdToBlockFaces.insert(std::make_pair(block, blockFaces)); diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp index 1996c9e..5d86d9c 100644 --- a/src/AssetManager.hpp +++ b/src/AssetManager.hpp @@ -39,14 +39,14 @@ struct ParsedFace { glm::mat4 transform; glm::vec4 texture; float layer; - glm::vec3 color; + glm::vec3 color; }; struct BlockFaces { glm::mat4 transform; std::vector faces; bool isBlock; - FaceDirection direction; + Vector faceDirectionVector[FaceDirection::none]; }; struct BlockModel { diff --git a/src/Render.cpp b/src/Render.cpp index 7f11dd9..58cf53d 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -420,8 +420,9 @@ void Render::RenderGui() { world->GameStatePtr()->world.GetBlockId(world->GameStatePtr()->selectedBlock).state, AssetManager::GetAssetNameByBlockId(BlockId{ world->GameStatePtr()->world.GetBlockId(world->GameStatePtr()->selectedBlock).id,0 }).c_str()); - ImGui::Text("Selected block direction: %d", - AssetManager::GetBlockModelByBlockId(world->GameStatePtr()->world.GetBlockId(world->GameStatePtr()->selectedBlock)).direction); + ImGui::Text("Selected block variant: %s:%s", + TransformBlockIdToBlockStateName(world->GameStatePtr()->world.GetBlockId(world->GameStatePtr()->selectedBlock)).first.c_str(), + TransformBlockIdToBlockStateName(world->GameStatePtr()->world.GetBlockId(world->GameStatePtr()->selectedBlock)).second.c_str()); } ImGui::End(); diff --git a/src/RendererSectionData.cpp b/src/RendererSectionData.cpp index 245dc95..d67fe5b 100644 --- a/src/RendererSectionData.cpp +++ b/src/RendererSectionData.cpp @@ -14,50 +14,25 @@ inline const BlockId& GetBlockId(int x, int y, int z, const std::array> 0 & 0x1) - continue; - lightness = glm::vec2(light.face[FaceDirection::down], skyLight.face[FaceDirection::down]); - break; - } - case FaceDirection::up: { - if (visibility >> 1 & 0x1) - continue; - lightness = glm::vec2(light.face[FaceDirection::up], skyLight.face[FaceDirection::up]); - break; - } - case FaceDirection::north: { - if (visibility >> 2 & 0x1) - continue; - lightness = glm::vec2(light.face[FaceDirection::north], skyLight.face[FaceDirection::north]); - break; - } - case FaceDirection::south: { - if (visibility >> 3 & 0x1) - continue; - lightness = glm::vec2(light.face[FaceDirection::south], skyLight.face[FaceDirection::south]); - break; - } - case FaceDirection::west: { - if (visibility >> 4 & 0x1) - continue; - lightness = glm::vec2(light.face[FaceDirection::west], skyLight.face[FaceDirection::west]); - break; - } - case FaceDirection::east: { - if (visibility >> 5 & 0x1) - continue; - lightness = glm::vec2(light.face[FaceDirection::east], skyLight.face[FaceDirection::east]); + FaceDirection direction = face.visibility; + Vector directionVec = model.faceDirectionVector[direction]; + FaceDirection faceDirection = FaceDirection::none; + for (int i = 0; i < FaceDirection::none; i++) { + if (FaceDirectionVector[i] == directionVec) { + faceDirection = FaceDirection(i); break; } } + + if (visibility[faceDirection]) + continue; + lightness = glm::vec2(light.face[faceDirection], skyLight.face[faceDirection]); } data.models.push_back(transform * model.transform * face.transform); data.textures.push_back(face.texture); @@ -76,8 +51,8 @@ BlockFaces *GetInternalBlockModel(const BlockId& id, std::vector GetBlockVisibilityData(const SectionsData §ions, const std::array &blockIdData, std::vector> &idModels) { - std::array arr; +std::array GetBlockVisibilityData(const SectionsData §ions, const std::array &blockIdData, std::vector> &idModels) { + std::array arr; for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { @@ -141,60 +116,19 @@ std::array GetBlockVisibilityData(const SectionsData §i auto blockModelWest = GetInternalBlockModel(blockIdWest, idModels); auto blockModelEast = GetInternalBlockModel(blockIdEast, idModels); - switch (GetInternalBlockModel(GetBlockId(x, y, z, blockIdData), idModels)->direction) { - case FaceDirection::west: - value |= (blockIdDown.id != 0 && !blockModelDown->faces.empty() && blockModelDown->isBlock) << 0; - value |= (blockIdUp.id != 0 && !blockModelUp->faces.empty() && blockModelUp->isBlock) << 1; - value |= (blockIdNorth.id != 0 && !blockModelNorth->faces.empty() && blockModelNorth->isBlock) << 2; - value |= (blockIdSouth.id != 0 && !blockModelSouth->faces.empty() && blockModelSouth->isBlock) << 3; - value |= (blockIdWest.id != 0 && !blockModelWest->faces.empty() && blockModelWest->isBlock) << 4; - value |= (blockIdEast.id != 0 && !blockModelEast->faces.empty() && blockModelEast->isBlock) << 5; - break; - case FaceDirection::east: - value |= (blockIdDown.id != 0 && !blockModelDown->faces.empty() && blockModelDown->isBlock) << 0; - value |= (blockIdUp.id != 0 && !blockModelUp->faces.empty() && blockModelUp->isBlock) << 1; - value |= (blockIdNorth.id != 0 && !blockModelNorth->faces.empty() && blockModelNorth->isBlock) << 3; - value |= (blockIdSouth.id != 0 && !blockModelSouth->faces.empty() && blockModelSouth->isBlock) << 2; - value |= (blockIdWest.id != 0 && !blockModelWest->faces.empty() && blockModelWest->isBlock) << 5; - value |= (blockIdEast.id != 0 && !blockModelEast->faces.empty() && blockModelEast->isBlock) << 4; - break; - case FaceDirection::up: - value |= (blockIdDown.id != 0 && !blockModelDown->faces.empty() && blockModelDown->isBlock) << 4; - value |= (blockIdUp.id != 0 && !blockModelUp->faces.empty() && blockModelUp->isBlock) << 5; - value |= (blockIdNorth.id != 0 && !blockModelNorth->faces.empty() && blockModelNorth->isBlock) << 2; - value |= (blockIdSouth.id != 0 && !blockModelSouth->faces.empty() && blockModelSouth->isBlock) << 3; - value |= (blockIdWest.id != 0 && !blockModelWest->faces.empty() && blockModelWest->isBlock) << 1; - value |= (blockIdEast.id != 0 && !blockModelEast->faces.empty() && blockModelEast->isBlock) << 0; - break; - case FaceDirection::down: - value |= (blockIdDown.id != 0 && !blockModelDown->faces.empty() && blockModelDown->isBlock) << 4; - value |= (blockIdUp.id != 0 && !blockModelUp->faces.empty() && blockModelUp->isBlock) << 5; - value |= (blockIdNorth.id != 0 && !blockModelNorth->faces.empty() && blockModelNorth->isBlock) << 2; - value |= (blockIdSouth.id != 0 && !blockModelSouth->faces.empty() && blockModelSouth->isBlock) << 3; - value |= (blockIdWest.id != 0 && !blockModelWest->faces.empty() && blockModelWest->isBlock) << 0; - value |= (blockIdEast.id != 0 && !blockModelEast->faces.empty() && blockModelEast->isBlock) << 1; - break; - case FaceDirection::north: - value |= (blockIdDown.id != 0 && !blockModelDown->faces.empty() && blockModelDown->isBlock) << 0; - value |= (blockIdUp.id != 0 && !blockModelUp->faces.empty() && blockModelUp->isBlock) << 1; - value |= (blockIdNorth.id != 0 && !blockModelNorth->faces.empty() && blockModelNorth->isBlock) << 5; - value |= (blockIdSouth.id != 0 && !blockModelSouth->faces.empty() && blockModelSouth->isBlock) << 4; - value |= (blockIdWest.id != 0 && !blockModelWest->faces.empty() && blockModelWest->isBlock) << 2; - value |= (blockIdEast.id != 0 && !blockModelEast->faces.empty() && blockModelEast->isBlock) << 3; - break; - case FaceDirection::south: - value |= (blockIdDown.id != 0 && !blockModelDown->faces.empty() && blockModelDown->isBlock) << 0; - value |= (blockIdUp.id != 0 && !blockModelUp->faces.empty() && blockModelUp->isBlock) << 1; - value |= (blockIdNorth.id != 0 && !blockModelNorth->faces.empty() && blockModelNorth->isBlock) << 4; - value |= (blockIdSouth.id != 0 && !blockModelSouth->faces.empty() && blockModelSouth->isBlock) << 5; - value |= (blockIdWest.id != 0 && !blockModelWest->faces.empty() && blockModelWest->isBlock) << 3; - value |= (blockIdEast.id != 0 && !blockModelEast->faces.empty() && blockModelEast->isBlock) << 2; - break; - case FaceDirection::none: - value = 0; - break; - } - arr[y * 256 + z * 16 + x] = value; + value |= (blockIdDown.id != 0 && !blockModelDown->faces.empty() && blockModelDown->isBlock) << 0; + value |= (blockIdUp.id != 0 && !blockModelUp->faces.empty() && blockModelUp->isBlock) << 1; + value |= (blockIdNorth.id != 0 && !blockModelNorth->faces.empty() && blockModelNorth->isBlock) << 2; + value |= (blockIdSouth.id != 0 && !blockModelSouth->faces.empty() && blockModelSouth->isBlock) << 3; + value |= (blockIdWest.id != 0 && !blockModelWest->faces.empty() && blockModelWest->isBlock) << 4; + value |= (blockIdEast.id != 0 && !blockModelEast->faces.empty() && blockModelEast->isBlock) << 5; + + arr[y * 256 + z * 16 + x][FaceDirection::down] = (value >> 0) & 1; + arr[y * 256 + z * 16 + x][FaceDirection::up] = (value >> 1) & 1; + arr[y * 256 + z * 16 + x][FaceDirection::north] = (value >> 2) & 1; + arr[y * 256 + z * 16 + x][FaceDirection::south] = (value >> 3) & 1; + arr[y * 256 + z * 16 + x][FaceDirection::west] = (value >> 4) & 1; + arr[y * 256 + z * 16 + x][FaceDirection::east] = (value >> 5) & 1; } } } @@ -219,7 +153,7 @@ RendererSectionData ParseSection(const SectionsData §ions) std::vector> idModels; std::array blockIdData = SetBlockIdData(sections); - std::array blockVisibility = GetBlockVisibilityData(sections, blockIdData, idModels); + std::array blockVisibility = GetBlockVisibilityData(sections, blockIdData, idModels); std::string textureName; data.hash = sections.section.GetHash(); -- cgit v1.2.3