34 : _volumeDimensions(
Vector3ui(0u, 0u, 0u))
37 CORE_INFO(
"Number of points: " << points.size() / 5);
38 Vector3ui octreeSize(_pow2roundup(std::ceil((maxAABB.x - minAABB.x) / voxelSize)),
39 _pow2roundup(std::ceil((maxAABB.y - minAABB.y) / voxelSize)),
40 _pow2roundup(std::ceil((maxAABB.z - minAABB.z) / voxelSize)));
43 _octreeSize = std::max(std::max(octreeSize.x, octreeSize.y), octreeSize.z);
45 CORE_INFO(
"Point Octree size : " << _octreeSize);
47 _depth = std::log2(_octreeSize) + 1u;
48 std::vector<PointOctreeLevelMap> octree(_depth);
50 CORE_INFO(
"Point Octree depth : " << _depth <<
" " << octree.size());
55 for (uint32_t i = 0; i < points.size(); ++i)
57 CORE_PROGRESS(
"Building octree from points", i, points.size());
58 const uint32_t xpos = std::floor((points[i].position.x - minAABB.x) / voxelSize);
59 const uint32_t ypos = std::floor((points[i].position.y - minAABB.y) / voxelSize);
60 const uint32_t zpos = std::floor((points[i].position.z - minAABB.z) / voxelSize);
61 const double value = points[i].value;
63 const uint32_t indexX = xpos;
64 const uint32_t indexY = ypos * (uint32_t)_octreeSize;
65 const uint32_t indexZ = zpos * (uint32_t)_octreeSize * (uint32_t)_octreeSize;
67 auto it = octree[0].find(indexX + indexY + indexZ);
68 if (it == octree[0].end())
71 for (uint32_t level = 0; level < _depth; ++level)
74 const uint32_t divisor = std::pow(2, level);
75 const Vector3f center(xpos, ypos, zpos);
77 const uint32_t nBlock = _octreeSize / divisor;
78 const uint32_t index = std::floor(xpos / divisor) + nBlock * std::floor(ypos / divisor) +
79 nBlock * nBlock * std::floor(zpos / divisor);
81 const double size = voxelSize * (level + 1u);
83 if (octree[level].find(index) == octree[level].end())
85 Vector3f p{(points[i].position.x - minAABB.x) / voxelSize,
86 (points[i].position.y - minAABB.y) / voxelSize,
87 (points[i].position.z - minAABB.z) / voxelSize};
89 octree[level].insert(PointOctreeLevelMap::value_type(index,
PointOctreeNode(p, size)));
93 octree[level].at(index).addValue(value);
95 if ((level > 0) && (child !=
nullptr))
96 octree[level].at(index).setChild(child);
99 child = &(octree[level].at(index));
106 for (uint32_t level = 0; level < _depth; ++level)
108 const uint32_t divisor = std::pow(2, level);
109 const uint32_t nBlock = _octreeSize / divisor;
110 const uint32_t index = std::floor(xpos / divisor) + nBlock * std::floor(ypos / divisor) +
111 nBlock * nBlock * std::floor(zpos / divisor);
112 octree[level].at(index).addValue(value);
116 for (uint32_t i = 0; i < octree.size(); ++i)
117 CORE_DEBUG(
"Number of leaves [" << i <<
"]: " << octree[i].size());
119 _offsetPerLevel.resize(_depth);
120 _offsetPerLevel[_depth - 1u] = 0;
121 uint32_t previousOffset = 0u;
122 for (uint32_t i = _depth - 1u; i > 0u; --i)
124 _offsetPerLevel[i - 1u] = previousOffset + octree[i].size();
125 previousOffset = _offsetPerLevel[i - 1u];
128 uint32_t totalNodeNumber = 0;
130 for (uint32_t i = 0; i < octree.size(); ++i)
131 totalNodeNumber += octree[i].size();
134 _flatIndices.resize(totalNodeNumber * 2u, 0);
138 _flattenChildren(&(octree[_depth - 1u].at(0)), _depth - 1u);
140 Vector3ui(std::ceil((maxAABB.x - minAABB.x) / voxelSize), std::ceil((maxAABB.y - minAABB.y) / voxelSize),
141 std::ceil((maxAABB.z - minAABB.z) / voxelSize));
142 _volumeSize = (uint32_t)_volumeDimensions.x * (uint32_t)_volumeDimensions.y * (uint32_t)_volumeDimensions.z;
147 void PointOctree::_flattenChildren(
PointOctreeNode *node, uint32_t level)
149 const std::vector<PointOctreeNode *> children = node->getChildren();
150 const auto &position = node->getCenter();
151 const auto value = node->getValue();
152 if ((children.empty()) || (level == 0))
159 _offsetPerLevel[level] += 1u;
167 _flatIndices[_offsetPerLevel[level] * 2u] = _offsetPerLevel[level - 1];
168 _flatIndices[_offsetPerLevel[level] * 2u + 1] = _offsetPerLevel[level - 1] + children.size() - 1u;
169 _offsetPerLevel[level] += 1u;
171 for (PointOctreeNode *child : children)
172 _flattenChildren(child, level - 1u);
The PointOctreeNode class implement a spherical node of the Octree acceleration structure used by the...
~PointOctree()
Destroy the PointOctree object.
PointOctree(const OctreePoints &points, double voxelSize, const Vector3f &minAABB, const Vector3f &maxAABB)
Construct a new PointOctree object.
glm::vec< 3, uint32_t > Vector3ui
std::map< uint32_t, PointOctreeNode > PointOctreeLevelMap
std::vector< OctreePoint > OctreePoints