Seperated Planular 2d logic from threedee logic in mesher

Very interesting commit, creates some seperation between chunk logic and
planular logic. impliments some key needed code to allow all this to
work with projecting the planular into chunk coords and all.

No regressions so far, hopefully we keep going on a roll because
everything working is really really nice.
This commit is contained in:
Rebekah 2024-02-22 13:16:18 -05:00
parent fa73fb3ec3
commit f1d876e6f4
Signed by: oneechanhax
GPG Key ID: 183EB7902964DAE5

View File

@ -235,7 +235,9 @@ public:
using BlockType = uint8_t; using BlockType = uint8_t;
// Using a single digit to locate the exact voxel's byte in the chunk, for very fast use. // Using a single digit to locate the exact voxel's byte in the chunk, for very fast use.
using ChunkDataType = std::array<uint8_t, _chunk_array_size>; using ChunkDataType = std::array<uint8_t, _chunk_array_size>;
using ChunkVecType = geo::internal::BVec2<uint8_t>; using PlaneVecType = geo::internal::BVec2<uint8_t>; // flat plane of blocks
// using ChunkVecType = geo::internal::BVec2<uint8_t>;
using ChunkVecType = Vector3i;
ChunkDataType raw_chunk_data = { ChunkDataType raw_chunk_data = {
ENUM_BLOCK_TYPE::E_BLOCK_STONE, ENUM_BLOCK_TYPE::E_BLOCK_STONE,
ENUM_BLOCK_TYPE::E_BLOCK_STONE, ENUM_BLOCK_TYPE::E_BLOCK_STONE,
@ -494,14 +496,7 @@ public:
ENUM_BLOCK_TYPE::E_BLOCK_AIR, ENUM_BLOCK_TYPE::E_BLOCK_AIR,
ENUM_BLOCK_TYPE::E_BLOCK_STONE, ENUM_BLOCK_TYPE::E_BLOCK_STONE,
}; };
static ChunkVecType ExtractVec(std::size_t blockidx) { static std::size_t MakeIndexFromPlanularPosition(PlaneVecType in_pos) {
auto coord = cChunkDef::IndexToCoordinate(blockidx);
ChunkVecType ret_pos;
ret_pos.x = coord.x;
ret_pos.y = coord.z;
return ret_pos;
}
static std::size_t GetVoxelFromPosInChunk(geo::internal::BVec2<uint8_t> in_pos) {
return cChunkDef::MakeIndex(in_pos.x, 0, in_pos.y); return cChunkDef::MakeIndex(in_pos.x, 0, in_pos.y);
} }
BlockType GetVoxelType(std::size_t v) const { BlockType GetVoxelType(std::size_t v) const {
@ -512,11 +507,12 @@ public:
ChunkVecType cur; ChunkVecType cur;
public: public:
using VecMaskType = glm::bvec2; using VecMaskType = glm::bvec3;
const VecMaskType mask, reverse_mask; // stick it in reverse spongebob! const VecMaskType mask = { false, false, false }, reverse_mask = { false, false, false }; // stick it in reverse spongebob!
constexpr AxisIterator(const ChunkVecType& src, std::pair<glm::bvec2, glm::bvec2> mask) using FullMaskType = std::pair<VecMaskType, VecMaskType>;
constexpr AxisIterator(const ChunkVecType& src, FullMaskType mask)
: AxisIterator(src, mask.first, mask.second) { } : AxisIterator(src, mask.first, mask.second) { }
constexpr AxisIterator(const ChunkVecType& src, glm::bvec2 mask, glm::bvec2 reverse_mask = { false, false }) constexpr AxisIterator(const ChunkVecType& src, VecMaskType mask, VecMaskType reverse_mask = { false, false, false })
: cur(src) : cur(src)
, mask(mask) , mask(mask)
, reverse_mask(reverse_mask) { } , reverse_mask(reverse_mask) { }
@ -538,30 +534,34 @@ public:
return !(*this == other); return !(*this == other);
} }
static constexpr AxisIterator end() { static constexpr AxisIterator end() {
AxisIterator ret({}, glm::bvec2 {}); AxisIterator ret({}, glm::bvec3 {});
ret.end_flagged = true; ret.end_flagged = true;
return ret; return ret;
} }
ChunkVecType GetPosToAdd() const { ChunkVecType GetPosToAdd() const {
ChunkVecType pos_to_add = { 0, 0 }; ChunkVecType pos_to_add = { 0, 0, 0 };
if (mask.x) if (mask.x)
pos_to_add.x = 1; pos_to_add.x = 1;
if (mask.y) if (mask.y)
pos_to_add.y = 1; pos_to_add.y = 1;
if (mask.z)
pos_to_add.z = 1;
if (reverse_mask.x && pos_to_add.x) if (reverse_mask.x && pos_to_add.x)
pos_to_add.x = -pos_to_add.x; pos_to_add.x = -pos_to_add.x;
if (reverse_mask.y && pos_to_add.y) if (reverse_mask.y && pos_to_add.y)
pos_to_add.y = -pos_to_add.y; pos_to_add.y = -pos_to_add.y;
if (reverse_mask.z && pos_to_add.z)
pos_to_add.z = -pos_to_add.z;
return pos_to_add; return pos_to_add;
} }
static constexpr auto CreateCardinalDirectionalMask(const CardinalDirections dir) { static constexpr auto CreateCardinalDirectionalMask(const CardinalDirections dir) {
VecMaskType mask = { false, false }, reverse_mask = { false, false }; VecMaskType mask = { false, false, false }, reverse_mask = { false, false, false };
switch (dir) { // THIS ONLY WORKS FOR THE CURRENT VEC ORDERING + its stuck on only xz looking top down... switch (dir) {
case CardinalDirections::kNorth: case CardinalDirections::kNorth:
reverse_mask.y = true; reverse_mask.z = true;
[[fallthrough]]; [[fallthrough]];
case CardinalDirections::kSouth: case CardinalDirections::kSouth:
mask.y = true; mask.z = true;
break; break;
case CardinalDirections::kWest: case CardinalDirections::kWest:
reverse_mask.x = true; reverse_mask.x = true;
@ -569,6 +569,12 @@ public:
case CardinalDirections::kEast: case CardinalDirections::kEast:
mask.x = true; mask.x = true;
break; break;
case CardinalDirections::kDown:
reverse_mask.y = true;
[[fallthrough]];
case CardinalDirections::kUp:
mask.y = true;
break;
default: default:
throw std::logic_error("Trying to access a cardinal Direction that does not work!"); throw std::logic_error("Trying to access a cardinal Direction that does not work!");
} }
@ -612,6 +618,15 @@ public:
return axis_directions; return axis_directions;
} }
}; };
static constexpr ChunkVecType ProjectPlanularToChunkVec(PlaneVecType plane_coords, const CardinalDirections facing_chunk_from_dir, std::size_t depth) {
ChunkVecType ret;
switch (facing_chunk_from_dir) {
case CardinalDirections::kUp:
return ChunkVecType(plane_coords.x, depth, plane_coords.y);
default:
throw std::logic_error("Trying to access a cardinal Direction that does not work!");
};
}
bool IsEmpty() const { bool IsEmpty() const {
for (auto i : this->raw_chunk_data) for (auto i : this->raw_chunk_data)
if (i != ENUM_BLOCK_TYPE::E_BLOCK_AIR) if (i != ENUM_BLOCK_TYPE::E_BLOCK_AIR)
@ -651,6 +666,8 @@ public:
const auto south_dir_mask = blockface_plane_geo_axis_info.first; const auto south_dir_mask = blockface_plane_geo_axis_info.first;
const auto east_dir_mask = blockface_plane_geo_axis_info.second; const auto east_dir_mask = blockface_plane_geo_axis_info.second;
const auto plane_facing_us_size = AxisIterator::GetPlaneSliceFacingFromDirectionSize(facing_direction_from);
std::vector<ChunkMeshedQuad> finished_quads; std::vector<ChunkMeshedQuad> finished_quads;
if (gfx_mesher_debuglog) if (gfx_mesher_debuglog)
std::cout << "Start Meshing: "; std::cout << "Start Meshing: ";
@ -661,19 +678,16 @@ public:
if (gfx_mesher_debuglog) if (gfx_mesher_debuglog)
std::cout << "Plain" << std::endl; std::cout << "Plain" << std::endl;
auto south_axis_crawl = AxisIterator({ 0, 0 }, south_dir_mask); for (std::size_t south = 0; south < plane_facing_us_size.first; south++) {
assert(south_axis_crawl.GetNumAxisDirections() == 1); for (std::size_t east = 0; east < plane_facing_us_size.second; east++) {
for (; south_axis_crawl != AxisIterator::end(); south_axis_crawl++) { const auto planular_block_coords = PlaneVecType { south, east };
auto east_axis_crawl = AxisIterator(*south_axis_crawl, east_dir_mask); const auto block_coords = ProjectPlanularToChunkVec(planular_block_coords, facing_direction_from, depth);
assert(east_axis_crawl.GetNumAxisDirections() == 1); const std::size_t blockidx = cChunkDef::MakeIndex(block_coords);
for (; east_axis_crawl != AxisIterator::end(); east_axis_crawl++) {
const auto block_coords = *east_axis_crawl;
const std::size_t blockidx = GetVoxelFromPosInChunk(block_coords);
const auto type = this->GetVoxelType(blockidx); const auto type = this->GetVoxelType(blockidx);
if (type == ENUM_BLOCK_TYPE::E_BLOCK_AIR) if (type == ENUM_BLOCK_TYPE::E_BLOCK_AIR)
continue; continue;
ChunkMeshedQuad new_face; ChunkMeshedQuad new_face;
const auto start = geo::Vec2(block_coords.x * box_size, block_coords.y * box_size); const auto start = geo::Vec2(planular_block_coords.x * box_size, planular_block_coords.y * box_size);
// auto end = /*start +*/ geo::Vec2(box_size, box_size); // auto end = /*start +*/ geo::Vec2(box_size, box_size);
const auto size = /*start +*/ geo::Vec2(box_size, box_size); const auto size = /*start +*/ geo::Vec2(box_size, box_size);
new_face.quad = geo::Box<geo::Vec2>(start, size); new_face.quad = geo::Box<geo::Vec2>(start, size);
@ -695,16 +709,17 @@ public:
if (gfx_mesher_debuglog) if (gfx_mesher_debuglog)
std::cout << "Greedy" << std::endl; std::cout << "Greedy" << std::endl;
// The Greedy mesher checksum utils use PLANULAR COORDS only, please convert between the two.
std::vector<bool> chunk_finished_checksum(AxisIterator::GetPlaneSliceFacingFromDirectionBlockCount(facing_direction_from), false); // i believe its faster(vs an array) when checking the entire thing for boolean std::vector<bool> chunk_finished_checksum(AxisIterator::GetPlaneSliceFacingFromDirectionBlockCount(facing_direction_from), false); // i believe its faster(vs an array) when checking the entire thing for boolean
const auto IsBlockMarkedOff = [&](std::size_t blockidx) -> bool { return chunk_finished_checksum[blockidx]; }; const auto IsBlockMarkedOff = [&](std::size_t blockidx) -> bool { return chunk_finished_checksum[blockidx]; };
using UnmeshedOpenSpacePosType = std::optional<std::pair<std::size_t, ChunkVecType>>; using UnmeshedOpenSpacePosType = std::optional<std::pair<std::size_t, PlaneVecType>>; // WITHIN PLANULAR SPACE WARNING!!!
const auto FindOpenSpace = [&]() -> UnmeshedOpenSpacePosType { const auto FindOpenSpace = [&]() -> UnmeshedOpenSpacePosType {
for (std::size_t x = 0; x < cChunkDef::Width; x++) { for (std::size_t south = 0; south < plane_facing_us_size.first; south++) {
for (std::size_t z = 0; z < cChunkDef::Width; z++) { for (std::size_t east = 0; east < plane_facing_us_size.second; east++) {
auto blockidx = this->GetVoxelFromPosInChunk({ x, z }); const PlaneVecType planular_block_coords = { south, east };
auto block_coords = ExtractVec(blockidx); // lmao const auto planular_blockidx = MakeIndexFromPlanularPosition(planular_block_coords);
if (!IsBlockMarkedOff(blockidx)) if (!IsBlockMarkedOff(planular_blockidx))
return std::make_pair(blockidx, block_coords); return std::make_pair(planular_blockidx, planular_block_coords);
} }
} }
return UnmeshedOpenSpacePosType(); return UnmeshedOpenSpacePosType();
@ -721,21 +736,25 @@ public:
if (!unmeshed_face.has_value()) if (!unmeshed_face.has_value())
throw std::logic_error("Greedy ChunkMesher checksum thinks there is a unmeshed chunk but unable to find it!"); throw std::logic_error("Greedy ChunkMesher checksum thinks there is a unmeshed chunk but unable to find it!");
const auto seed_blockpos = unmeshed_face.value(); const auto seed_planular_blockpos = unmeshed_face.value();
const auto seed_blockidx = seed_blockpos.first; // const auto seed_planular_blockidx = seed_planular_blockpos.first;
const auto seed_planular_block_coords = seed_planular_blockpos.second;
// if (gfx_mesher_debuglog) // TOO MUCH LOGS! enable it if ur debugging rly hard.
// std::cout << "Greedy found Seed block at planular coords: {" << (int)seed_planular_block_coords.x << ", " << (int)seed_planular_block_coords.y << "}" << std::endl;
const auto seed_block_coords = ProjectPlanularToChunkVec(seed_planular_block_coords, facing_direction_from, depth);
const auto seed_blockidx = cChunkDef::MakeIndex(seed_block_coords);
const auto seed_block_type = this->GetVoxelType(seed_blockidx); const auto seed_block_type = this->GetVoxelType(seed_blockidx);
if (seed_block_type == ENUM_BLOCK_TYPE::E_BLOCK_AIR) { if (seed_block_type == ENUM_BLOCK_TYPE::E_BLOCK_AIR) {
chunk_finished_checksum[seed_blockidx] = true; chunk_finished_checksum[seed_blockidx] = true;
continue; continue;
} }
if (gfx_mesher_debuglog) { if (gfx_mesher_debuglog)
const auto seed_block_coords = seed_blockpos.second; std::cout << " Seed Block Real Coords: \"" << (int)seed_block_type << "\": {" << (int)seed_block_coords.x << ", " << (int)seed_block_coords.y << ", " << (int)seed_block_coords.z << "}" << std::endl;
std::cout << "Greedy found Seed block \"" << (int)seed_block_type << "\": {" << (int)seed_block_coords.x << ", " << (int)seed_block_coords.y << "}" << std::endl;
} PlaneVecType block_quad_size = { 1, 1 }; // in coords
ChunkVecType block_quad_size = { 1, 1 }; // in coords
const auto seed_block_coords = seed_blockpos.second;
// Need a better "search line down" func... instead of one block we need to check multiple and return how many are the same. // Need a better "search line down" func... instead of one block we need to check multiple and return how many are the same.
auto SearchLineSouthForSameTypes = [&](ChunkVecType src_line, std::uint8_t max_size = cChunkDef::Width) -> std::uint8_t { auto SearchLineSouthForSameTypes = [&](ChunkVecType src_line, std::uint8_t max_size = cChunkDef::Width) -> std::uint8_t {
std::size_t alike_counter = 0; std::size_t alike_counter = 0;
@ -743,7 +762,7 @@ public:
auto south_axis_crawl = AxisIterator(src_line, south_dir_mask); auto south_axis_crawl = AxisIterator(src_line, south_dir_mask);
assert(south_axis_crawl.GetNumAxisDirections() == 1); assert(south_axis_crawl.GetNumAxisDirections() == 1);
for (; south_axis_crawl != AxisIterator::end(); south_axis_crawl++) { for (; south_axis_crawl != AxisIterator::end(); south_axis_crawl++) {
const std::size_t south_blockidx_to_check = GetVoxelFromPosInChunk(*south_axis_crawl); const std::size_t south_blockidx_to_check = cChunkDef::MakeIndex(*south_axis_crawl);
auto south_block_type = this->GetVoxelType(south_blockidx_to_check); auto south_block_type = this->GetVoxelType(south_blockidx_to_check);
if (south_block_type != seed_block_type) if (south_block_type != seed_block_type)
break; break;
@ -773,7 +792,7 @@ public:
east_axis_crawl++; // starting one ahead east_axis_crawl++; // starting one ahead
std::size_t alike_counter = 1; std::size_t alike_counter = 1;
for (; east_axis_crawl != AxisIterator::end(); east_axis_crawl++) { for (; east_axis_crawl != AxisIterator::end(); east_axis_crawl++) {
const std::size_t east_blockidx_to_check = GetVoxelFromPosInChunk(*east_axis_crawl); const std::size_t east_blockidx_to_check = cChunkDef::MakeIndex(*east_axis_crawl);
const auto east_block_type = this->GetVoxelType(east_blockidx_to_check); const auto east_block_type = this->GetVoxelType(east_blockidx_to_check);
if (east_block_type != seed_block_type) if (east_block_type != seed_block_type)
break; break;
@ -797,7 +816,7 @@ public:
} }
ChunkMeshedQuad new_face; ChunkMeshedQuad new_face;
const auto quad_start = geo::Vec2(seed_block_coords.x * box_size, seed_block_coords.y * box_size); const auto quad_start = geo::Vec2(seed_planular_block_coords.x * box_size, seed_planular_block_coords.y * box_size);
const auto quad_size = geo::Vec2(block_quad_size.x * box_size, block_quad_size.y * box_size); const auto quad_size = geo::Vec2(block_quad_size.x * box_size, block_quad_size.y * box_size);
new_face.quad = geo::Box<geo::Vec2>(quad_start, quad_size); new_face.quad = geo::Box<geo::Vec2>(quad_start, quad_size);
@ -806,20 +825,21 @@ public:
std::cout << " *Added quad! : {" << quad_start.x << ", " << quad_start.y << "} with size {" << quad_size.x << ", " << quad_size.y << "}" << std::endl; std::cout << " *Added quad! : {" << quad_start.x << ", " << quad_start.y << "} with size {" << quad_size.x << ", " << quad_size.y << "}" << std::endl;
finished_quads.push_back(new_face); finished_quads.push_back(new_face);
const auto MarkAreaFinished = [&](ChunkVecType origin, ChunkVecType size) { const auto MarkAreaFinished = [&](PlaneVecType origin_block, PlaneVecType size_in_blocks) {
assert(size.x && size.y); assert(size_in_blocks.x && size_in_blocks.y);
for (std::size_t x = 0; x < size.x; x++) { for (std::size_t x = 0; x < size_in_blocks.x; x++) { // in faceing_planular space
for (std::size_t z = 0; z < size.y; z++) { for (std::size_t z = 0; z < size_in_blocks.y; z++) {
auto block_coords_to_clear = origin + ChunkVecType(x, z); auto block_coords_to_clear = origin_block + PlaneVecType(x, z);
if (gfx_mesher_debuglog) if (gfx_mesher_debuglog)
std::cout << " ------Marking Block Finished: {" << (int)block_coords_to_clear.x << ", " << (int)block_coords_to_clear.y << "}" << std::endl; std::cout << " ------Marking Block Finished: {" << (int)block_coords_to_clear.x << ", " << (int)block_coords_to_clear.y << "}" << std::endl;
auto blockidx = this->GetVoxelFromPosInChunk(block_coords_to_clear); auto blockidx = MakeIndexFromPlanularPosition(block_coords_to_clear);
assert(blockidx < chunk_finished_checksum.size());
assert(!IsBlockMarkedOff(blockidx)); assert(!IsBlockMarkedOff(blockidx));
chunk_finished_checksum[blockidx] = true; chunk_finished_checksum[blockidx] = true;
} }
} }
}; };
MarkAreaFinished(seed_block_coords, block_quad_size); MarkAreaFinished(seed_planular_block_coords, block_quad_size);
// mark it off of the chunk_finished_checksum by setting the chunk_finished_checksum[i] to 1 // mark it off of the chunk_finished_checksum by setting the chunk_finished_checksum[i] to 1
} }
if (gfx_mesher_debuglog) if (gfx_mesher_debuglog)
@ -837,10 +857,13 @@ public:
return finished_quads; return finished_quads;
} }
// static bool IsPosValidWithinPlane(ChunkVecType block_coords) {
static bool IsPosValidWithinChunk(ChunkVecType block_coords) { static bool IsPosValidWithinChunk(ChunkVecType block_coords) {
if (!cChunkDef::IsValidWidth(block_coords.x)) if (!cChunkDef::IsValidWidth(block_coords.x))
return false; return false;
if (!cChunkDef::IsValidWidth(block_coords.y)) if (!cChunkDef::IsValidHeight(block_coords))
return false;
if (!cChunkDef::IsValidWidth(block_coords.z))
return false; return false;
return true; return true;
} }