Toast Engine
Loading...
Searching...
No Matches
connectivity.hpp
Go to the documentation of this file.
1
6
7#pragma once
8#include "brick.hpp"
9#include "voxel_constants.hpp"
10#include "voxel_volume.hpp"
11
12#include <cstdint>
13#include <glm/glm.hpp>
14#include <toast/export.hpp>
15#include <vector>
16
17namespace voxel {
18
19inline constexpr uint32_t k_no_component = 0xFFFFFFFFu;
20
22[[nodiscard]]
23inline auto brickComponents(const BrickOccupancy& brick) -> std::vector<BrickOccupancy> {
24 if (isEmpty(brick)) {
25 return {};
26 }
27 if (isFull(brick)) {
28 return std::vector<BrickOccupancy>(1, brick);
29 }
30
31 std::vector<BrickOccupancy> out;
32 BrickOccupancy remaining = brick;
33 while (!isEmpty(remaining)) {
34 // x & (~x + 1) isolates the lowest set bit
35 BrickOccupancy region {};
36 for (uint32_t z = 0; z < k_brick_dim; ++z) {
37 if (remaining[z] != 0ull) {
38 region[z] = remaining[z] & (~remaining[z] + 1ull);
39 break;
40 }
41 }
42
43 for (;;) {
44 const BrickOccupancy grown = dilate(region) & remaining;
45 if (grown == region) {
46 break;
47 }
48 region = grown;
49 }
50
51 out.push_back(region);
52 remaining = remaining & ~region;
53 }
54 return out;
55}
56
57struct BrickPiece {
58 glm::ivec3 brick {0};
59 BrickOccupancy voxels {};
60
61 uint32_t component = 0;
62};
63
66 std::vector<BrickPiece> pieces;
67 uint32_t component_count = 0;
68
69 [[nodiscard]]
70 auto componentOf(glm::ivec3 voxel) const -> uint32_t {
71 const glm::ivec3 brick(voxel.x >> 3, voxel.y >> 3, voxel.z >> 3);
72 const auto x = static_cast<uint32_t>(voxel.x & 7);
73 const auto y = static_cast<uint32_t>(voxel.y & 7);
74 const auto z = static_cast<uint32_t>(voxel.z & 7);
75 for (const BrickPiece& piece : pieces) {
76 if (piece.brick == brick && isSolid(piece.voxels, x, y, z)) {
77 return piece.component;
78 }
79 }
80 return k_no_component;
81 }
82
83 [[nodiscard]]
84 auto voxelCount(uint32_t component) const -> uint32_t {
85 uint32_t total = 0;
86 for (const BrickPiece& piece : pieces) {
87 if (piece.component == component) {
88 total += popCount(piece.voxels);
89 }
90 }
91 return total;
92 }
93};
94
95[[nodiscard]]
96TOAST_API auto analyseConnectivity(const Volume& volume) -> Connectivity;
97
98}
Definition voxel_volume.hpp:21
auto brickComponents(const BrickOccupancy &brick) -> std::vector< BrickOccupancy >
Edge or corner contact does not connect.
Definition connectivity.hpp:23
One 64-bit word per z-slice with bit y * 8 + x.
Definition brick.hpp:18
Definition connectivity.hpp:57
Labels are deterministic with pieces in brick order and components by first appearance.
Definition connectivity.hpp:65