1 #ifndef OCTREE_CONTAINER_HPP
2 #define OCTREE_CONTAINER_HPP
4 #include "blub/core/hashList.hpp"
5 #include "blub/core/hashMap.hpp"
6 #include "blub/core/list.hpp"
7 #include "blub/core/sharedPointer.hpp"
8 #include "blub/math/axisAlignedBoxInt32.hpp"
9 #include "blub/math/vector3.hpp"
10 #include "blub/math/vector3int.hpp"
19 template <
typename dataType>
29 : m_position(position)
32 for (int8 ind = 0; ind < 8; ++ind)
34 m_nodes[ind] =
nullptr;
38 t_nodePtr getNode(
const int32& index)
const
43 return m_nodes[index];
48 return pos >= m_position && pos < (m_position + m_size);
80 :
node(position, size)
85 const t_dataList& getData()
const
93 bool insert(
const dataType& toAdd)
95 BASSERT(m_data.find(toAdd) == m_data.cend());
100 void remove(
const dataType toRemove)
102 typename t_dataList::const_iterator it = m_data.find(toRemove);
103 BASSERT(it != m_data.cend());
113 typedef dataType t_data;
123 : m_minNodeSize(minNodeSize)
125 m_root =
new node(-m_minNodeSize, m_minNodeSize*2);
130 destroyNodeAndChildren(m_root);
134 bool insert(
const dataType&
data,
const vector3& pos)
136 return insert(data, convertAbsolutVector3PositionToVectorInt32(pos));
139 bool insert(
const dataType& data,
const vector3int32& pos)
141 typename t_dataLeafMap::const_iterator it = m_data.find(data);
142 if (it != m_data.cend())
147 BASSERT(m_dataCoords.find(data) == m_dataCoords.cend());
148 m_dataCoords.insert(data, pos);
150 const vector3int32 leafCoords(convertCoordToLeafCoord(pos));
153 const vector3int32 leafPosMinAbs(leafCoords*m_minNodeSize);
154 if (!m_root->isInside(leafPosMinAbs))
156 while (!m_root->isInside(leafPosMinAbs))
158 t_nodePtr rootCopy(m_root);
159 m_root =
new node(rootCopy->getPosition()*2, rootCopy->getSize()*2);
160 for (int32 ind = 0; ind < 8; ++ind)
162 if (rootCopy->m_nodes[ind] !=
nullptr)
164 insertNodeInNode(rootCopy->m_nodes[ind], m_root);
172 const vector3int32& leafCoord(leafCoords);
175 typename t_coordLeafMap::const_iterator itLeaf(m_leafs.find(leafCoord));
176 if (itLeaf != m_leafs.cend())
178 workLeaf = itLeaf->second;
183 workLeaf =
new leaf(leafCoord*m_minNodeSize, m_minNodeSize);
184 insertNodeInNode(workLeaf, m_root);
185 m_leafs.insert(leafCoord, workLeaf);
188 BASSERT(workLeaf !=
nullptr);
190 workLeaf->insert(data);
191 m_data.insert(data, workLeaf);
196 bool remove(
const dataType data)
198 auto it_range = m_data.equal_range(data);
199 if (it_range.first == it_range.second)
203 for (
auto it = it_range.first; it != it_range.second; ++it)
205 it->second->remove(data);
208 m_dataCoords.erase(data);
212 bool update(
const dataType& data,
const vector3int32& updateCoord)
214 typename t_dataLeafMap::const_iterator it = m_data.find(data);
215 if (it == m_data.cend())
219 const t_leafPtr currentLeaf(it->second);
220 if (currentLeaf->isInside(updateCoord))
228 return insert(data, updateCoord);
230 bool update(
const dataType& data,
const vector3& updateCoord)
232 return update(data, convertAbsolutVector3PositionToVectorInt32(updateCoord));
235 t_nodeList getNodes(
const dataType& data)
237 auto it_range = m_data.equal_range(data);
238 if (it_range.first == it_range.second)
243 for (
auto it = it_range.first; it != it_range.second; ++it)
245 result.insert(it->second);
255 t_nodePtr getRootNode()
const
260 t_leafPtr isLeaf(t_nodePtr nd)
const
262 if (nd->getSize() == getMinNodeSize())
264 return static_cast<t_leafPtr
>(nd);
272 const vector3int32& getMinNodeSize()
const
274 return m_minNodeSize;
278 void destroyNodeAndChildren(t_nodePtr toDestory)
280 BASSERT(toDestory !=
nullptr);
282 for (int8 ind = 0; ind < 8; ++ind)
284 if (toDestory->m_nodes[ind] !=
nullptr)
286 destroyNodeAndChildren(toDestory->m_nodes[ind]);
287 toDestory->m_nodes[ind] =
nullptr;
290 leaf *lf(isLeaf(toDestory));
293 while (!lf->m_data.empty())
296 const bool resultRemove =
298 remove(*lf->m_data.cbegin());
299 BASSERT(resultRemove);
309 vector3int32 convertCoordToLeafCoord(
const vector3int32& coord)
const
311 return convertCoordToLeafCoord(coord, m_minNodeSize);
313 static vector3int32 convertCoordToLeafCoord(
const vector3int32& coord,
const vector3int32& size)
315 vector3int32 result(coord / size);
316 if (coord.x < 0 && coord.x%size.x != 0)
320 if (coord.y < 0 && coord.y%size.y != 0)
324 if (coord.z < 0 && coord.z%size.z != 0)
330 vector3int32 convertAbsolutVector3PositionToVectorInt32(
const vector3& pos)
const
332 const vector3int32 posResult(pos.getFloor());
336 static bool insertNodeInNode(t_nodePtr toInsert, t_nodePtr into)
338 BASSERT(toInsert !=
nullptr);
339 BASSERT(into !=
nullptr);
341 BASSERT(into->isInside(toInsert->getPosition()));
342 BASSERT(into->isInside(toInsert->getPosition() + (toInsert->getSize()-vector3int32(1, 1, 1))));
345 BASSERT(into->getSize() > toInsert->getSize());
349 vector3int32 posChild;
350 const vector3int32 intoCenter(into->getPosition() + into->getSize() / 2);
352 if (toInsert->getPosition().x < intoCenter.x &&
353 toInsert->getPosition().y < intoCenter.y &&
354 toInsert->getPosition().z < intoCenter.z)
357 posChild = vector3int32(0, 0, 0);
359 if (toInsert->getPosition().x >= intoCenter.x &&
360 toInsert->getPosition().y < intoCenter.y &&
361 toInsert->getPosition().z < intoCenter.z)
364 posChild = vector3int32(1, 0, 0);
366 if (toInsert->getPosition().x < intoCenter.x &&
367 toInsert->getPosition().y >= intoCenter.y &&
368 toInsert->getPosition().z < intoCenter.z)
371 posChild = vector3int32(0, 1, 0);
373 if (toInsert->getPosition().x >= intoCenter.x &&
374 toInsert->getPosition().y >= intoCenter.y &&
375 toInsert->getPosition().z < intoCenter.z)
378 posChild = vector3int32(1, 1, 0);
380 if (toInsert->getPosition().x < intoCenter.x &&
381 toInsert->getPosition().y < intoCenter.y &&
382 toInsert->getPosition().z >= intoCenter.z)
385 posChild = vector3int32(0, 0, 1);
387 if (toInsert->getPosition().x >= intoCenter.x &&
388 toInsert->getPosition().y < intoCenter.y &&
389 toInsert->getPosition().z >= intoCenter.z)
392 posChild = vector3int32(1, 0, 1);
394 if (toInsert->getPosition().x < intoCenter.x &&
395 toInsert->getPosition().y >= intoCenter.y &&
396 toInsert->getPosition().z >= intoCenter.z)
399 posChild = vector3int32(0, 1, 1);
401 if (toInsert->getPosition().x >= intoCenter.x &&
402 toInsert->getPosition().y >= intoCenter.y &&
403 toInsert->getPosition().z >= intoCenter.z)
406 posChild = vector3int32(1, 1, 1);
409 const vector3int32 sizeChild(into->getSize()/2);
410 if (into->m_nodes[index] ==
nullptr)
412 if (sizeChild == toInsert->getSize())
414 into->m_nodes[index] = toInsert;
417 into->m_nodes[index] =
new node(into->getPosition() + posChild*sizeChild, sizeChild);
418 return insertNodeInNode(toInsert, into->m_nodes[index]);
422 return insertNodeInNode(toInsert, into->m_nodes[index]);
427 const vector3int32 m_minNodeSize;
430 t_dataLeafMap m_data;
431 t_dataCoordsMap m_dataCoords;
432 t_coordLeafMap m_leafs;
440 #endif // OCTREE_CONTAINER_HPP
Definition: container.hpp:74
Definition: axisAlignedBoxInt32.hpp:12
Definition: container.hpp:20
Definition: vector3.hpp:26
Definition: container.hpp:23
Definition: deadlineTimer.hpp:10
Definition: customVertexInformation.cpp:177