8 #ifndef META_OCEAN_GEOMETRY_OCTREE_H
9 #define META_OCEAN_GEOMETRY_OCTREE_H
78 inline Parameters(
const unsigned int maximalPointsPerLeaf,
const bool useTightBoundingBoxes);
261 template <
typename T>
263 maximalPointsPerLeaf_(maximalPointsPerLeaf),
264 useTightBoundingBoxes_(useTightBoundingBoxes)
269 template <
typename T>
272 return maximalPointsPerLeaf_ >= 1u;
275 template <
typename T>
278 *
this = std::move(octree);
281 template <
typename T>
284 ocean_assert(parameters.
isValid());
286 if (numberTreePoints == 0)
291 ocean_assert(treePoints !=
nullptr);
293 Indices32 reusablePointIndicesInput(createIndices<Index32>(numberTreePoints, 0u));
294 Indices32 reusablePointIndicesOutput(reusablePointIndicesInput.size());
300 for (
size_t n = 0; n < numberTreePoints; ++n)
306 *
this =
Octree(parameters, treePoints, reusablePointIndicesInput.
data(), reusablePointIndicesOutput.data(), numberTreePoints,
boundingBox);
309 template <
typename T>
312 ocean_assert(parameters.
isValid());
313 ocean_assert(treePoints !=
nullptr);
315 if (numberPointIndices == 0)
320 ocean_assert(reusablePointIndicesInput !=
nullptr && reusablePointIndicesOutput !=
nullptr);
328 const Vector3& firstPoint = treePoints[reusablePointIndicesInput[0]];
330 bool allPointsIdentical =
true;
332 for (
size_t n = 1; n < numberPointIndices; ++n)
334 const Index32& index = reusablePointIndicesInput[n];
337 if (firstPoint != point)
339 allPointsIdentical =
false;
344 isLeafNode = allPointsIdentical;
353 for (
size_t n = 0; n < numberPointIndices; ++n)
355 const Index32& index = reusablePointIndicesInput[n];
366 for (
size_t n = 0; n < numberPointIndices; ++n)
368 const Index32& index = reusablePointIndicesInput[n];
383 for (
size_t n = 0; n < numberPointIndices; ++n)
385 const Index32& index = reusablePointIndicesInput[n];
398 for (
size_t n = 0; n < numberPointIndices; ++n)
400 const Index32& index = reusablePointIndicesInput[n];
411 size_t lowLowLow = 0;
412 size_t lowLowHigh = 0;
413 size_t lowHighLow = 0;
414 size_t lowHighHigh = 0;
416 size_t highLowLow = 0;
417 size_t highLowHigh = 0;
418 size_t highHighLow = 0;
419 size_t highHighHigh = 0;
421 for (
size_t n = 0; n < numberPointIndices; ++n)
423 const Index32& index = reusablePointIndicesInput[n];
426 if (point.
x() < center.
x())
428 if (point.
y() < center.
y())
430 if (point.
z() < center.
z())
441 if (point.
z() < center.
z())
453 if (point.
y() < center.
y())
455 if (point.
z() < center.
z())
466 if (point.
z() < center.
z())
480 Index32* lowLowLowPointer = reusablePointIndicesOutput;
481 Index32* lowLowHighPointer = lowLowLowPointer + lowLowLow;
482 Index32* lowHighLowPointer = lowLowHighPointer + lowLowHigh;
483 Index32* lowHighHighPointer = lowHighLowPointer + lowHighLow;
485 Index32* highLowLowPointer = lowHighHighPointer + lowHighHigh;
486 Index32* highLowHighPointer = highLowLowPointer + highLowLow;
487 Index32* highHighLowPointer = highLowHighPointer + highLowHigh;
488 Index32* highHighHighPointer = highHighLowPointer + highHighLow;
490 ocean_assert(highHighHighPointer + highHighHigh == reusablePointIndicesOutput + numberPointIndices);
492 for (
size_t n = 0; n < numberPointIndices; ++n)
494 const Index32& index = reusablePointIndicesInput[n];
497 if (point.
x() < center.
x())
499 if (point.
y() < center.
y())
501 if (point.
z() < center.
z())
503 *lowLowLowPointer++ = index;
507 *lowLowHighPointer++ = index;
512 if (point.
z() < center.
z())
514 *lowHighLowPointer++ = index;
518 *lowHighHighPointer++ = index;
524 if (point.
y() < center.
y())
526 if (point.
z() < center.
z())
528 *highLowLowPointer++ = index;
532 *highLowHighPointer++ = index;
537 if (point.
z() < center.
z())
539 *highHighLowPointer++ = index;
543 *highHighHighPointer++ = index;
549 ocean_assert(lowLowLowPointer == reusablePointIndicesOutput + lowLowLow);
550 ocean_assert(lowLowHighPointer == lowLowLowPointer + lowLowHigh);
551 ocean_assert(lowHighLowPointer == lowLowHighPointer + lowHighLow);
552 ocean_assert(lowHighHighPointer == lowHighLowPointer + lowHighHigh);
554 ocean_assert(highLowLowPointer == lowHighHighPointer + highLowLow);
555 ocean_assert(highLowHighPointer == highLowLowPointer + highLowHigh);
556 ocean_assert(highHighLowPointer == highLowHighPointer + highHighLow);
557 ocean_assert(highHighHighPointer == highHighLowPointer + highHighHigh);
562 childNodes_[1] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowLowLow, reusablePointIndicesInput += lowLowLow, lowLowHigh,
BoundingBox());
563 childNodes_[2] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowLowHigh, reusablePointIndicesInput += lowLowHigh, lowHighLow,
BoundingBox());
564 childNodes_[3] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowHighLow, reusablePointIndicesInput += lowHighLow, lowHighHigh,
BoundingBox());
566 childNodes_[4] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowHighHigh, reusablePointIndicesInput += lowHighHigh, highLowLow,
BoundingBox());
567 childNodes_[5] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += highLowLow, reusablePointIndicesInput += highLowLow, highLowHigh,
BoundingBox());
568 childNodes_[6] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += highLowHigh, reusablePointIndicesInput += highLowHigh, highHighLow,
BoundingBox());
569 childNodes_[7] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += highHighLow, reusablePointIndicesInput += highHighLow, highHighHigh,
BoundingBox());
583 childNodes_[0] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput, reusablePointIndicesInput, lowLowLow, boxLowLowLow);
584 childNodes_[1] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowLowLow, reusablePointIndicesInput += lowLowLow, lowLowHigh, boxLowLowHigh);
585 childNodes_[2] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowLowHigh, reusablePointIndicesInput += lowLowHigh, lowHighLow, boxLowHighLow);
586 childNodes_[3] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowHighLow, reusablePointIndicesInput += lowHighLow, lowHighHigh, boxLowHighHigh);
588 childNodes_[4] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += lowHighHigh, reusablePointIndicesInput += lowHighHigh, highLowLow, boxHighLowLow);
589 childNodes_[5] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += highLowLow, reusablePointIndicesInput += highLowLow, highLowHigh, boxHighLowHigh);
590 childNodes_[6] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += highLowHigh, reusablePointIndicesInput += highLowHigh, highHighLow, boxHighHighLow);
591 childNodes_[7] =
new OctreeT<T>(parameters, treePoints, reusablePointIndicesOutput += highHighLow, reusablePointIndicesInput += highHighLow, highHighHigh, boxHighHighHigh);
595 template <
typename T>
598 for (
unsigned int n = 0u; n < 8u; ++n)
604 template <
typename T>
610 template <
typename T>
616 template <
typename T>
627 template <
typename T>
635 const Vector3 scalarPoint(queryPoint);
637 const T maximalSqrDistance =
Scalar(maximalDistance * maximalDistance);
644 std::vector<const OctreeT<T>*>& nodes = reusableData.
internalData_;
645 nodes.emplace_back(
this);
647 while (!nodes.empty())
652 ocean_assert(node !=
nullptr);
657 for (
unsigned int n = 0u; n < 8u; ++n)
664 nodes.emplace_back(&childNode);
675 template <
typename T>
678 ocean_assert(queryRay.
isValid());
679 ocean_assert(leafs.empty());
686 const Line3 scalarRay(queryRay);
693 std::vector<const OctreeT<T>*>& nodes = reusableData.
internalData_;
694 nodes.emplace_back(
this);
696 while (!nodes.empty())
701 ocean_assert(node !=
nullptr);
706 for (
unsigned int n = 0u; n < 8u; ++n)
713 nodes.emplace_back(&childNode);
724 template <
typename T>
727 ocean_assert(queryRay.
isValid());
728 ocean_assert(tanHalfAngle >= 0 && tanHalfAngle < 1);
729 ocean_assert(leafs.empty());
736 const Line3 scalarRay(queryRay);
738 const Scalar& epsPerDistance = tanHalfAngle;
745 std::vector<const OctreeT<T>*>& nodes = reusableData.
internalData_;
746 nodes.emplace_back(
this);
748 while (!nodes.empty())
753 ocean_assert(node !=
nullptr);
758 for (
unsigned int n = 0u; n < 8u; ++n)
765 nodes.emplace_back(&childNode);
776 template <
typename T>
779 ocean_assert(treePoints !=
nullptr);
782 ocean_assert(points ==
nullptr || points->empty());
789 const Vector3 scalarPoint(queryPoint);
791 const T maximalSqrDistance =
Scalar(maximalDistance * maximalDistance);
798 std::vector<const OctreeT<T>*>& nodes = reusableData.
internalData_;
799 nodes.emplace_back(
this);
801 while (!nodes.empty())
806 ocean_assert(node !=
nullptr);
811 for (
unsigned int n = 0u; n < 8u; ++n)
817 nodes.emplace_back(&childNode);
825 const VectorT3<T>& treePoint = treePoints[pointIndex];
827 if (points !=
nullptr)
829 if (treePoint.
sqrDistance(queryPoint) <= maximalSqrDistance)
832 points->emplace_back(treePoints[pointIndex]);
837 if (treePoint.
sqrDistance(queryPoint) <= maximalSqrDistance)
847 template <
typename T>
853 template <
typename T>
863 for (
unsigned int n = 0u; n < 8u; ++n)
866 octree.childNodes_[n] =
nullptr;
This class implements a 3D bounding box.
Definition: BoundingBox.h:23
bool isInside(const VectorT3< T > &point, const T eps=T(0)) const
Returns whether a given point is inside this bounding box.
bool isValid() const
Returns whether the bounding box is valid.
const VectorT3< T > & lower() const
Returns the lower corner of the box.
VectorT3< T > center() const
Returns the center of the box.
bool hasIntersection(const LineT3< T > &ray) const
Returns whether a given ray has an intersection with this box.
const VectorT3< T > & higher() const
Returns the higher corner of the box.
This class stores construction parameters for an octree.
Definition: Octree.h:65
bool useTightBoundingBoxes_
True, to use tight bounding boxes for each individual node (only covering the actual points); False,...
Definition: Octree.h:92
bool isValid() const
Returns whether this object holds valid parameters.
Definition: Octree.h:270
Parameters()=default
Default constructor.
unsigned int maximalPointsPerLeaf_
The maximal number of points each leaf node can have.
Definition: Octree.h:89
Definition of a class which holds reusable data for internal use.
Definition: Octree.h:111
std::vector< const OctreeT< T > * > internalData_
The internal reusable data.
Definition: Octree.h:124
ReusableData()=default
Creates a new object.
Forward declaration.
Definition: Octree.h:55
void closestLeafs(const VectorT3< T > &queryPoint, const T maximalDistance, std::vector< const Indices32 * > &leafs, const ReusableData &reusableData=ReusableData()) const
Returns the closest leaf nodes for a given query point.
Definition: Octree.h:628
Indices32 pointIndices_
The indicies of the tree points which belong to this leaf node, empty if this node is not a leaf node...
Definition: Octree.h:255
void intersectingLeafs(const LineT3< T > &queryRay, std::vector< const Indices32 * > &leafs, const ReusableData &reusableData=ReusableData()) const
Returns the intersecting leaf nodes for a given query ray.
Definition: Octree.h:676
OctreeT< T > * childNodes_[8]
The eight child nodes.
Definition: Octree.h:258
OctreeT(const OctreeT &octree)=delete
Disabled copy constructor.
OctreeT()=default
Default constructor creating an empty tree.
T Type
The data type of this octree.
Definition: Octree.h:59
OctreeT & operator=(OctreeT &&octree)
Move operator.
Definition: Octree.h:854
const BoundingBox & boundingBox() const
Returns the bounding box containing all points of this node (of all points in all child leaf nodes)
Definition: Octree.h:605
~OctreeT()
Destructs this tree node.
Definition: Octree.h:596
void closestPoints(const VectorT3< T > *treePoints, const VectorT3< T > &queryPoint, const T maximalDistance, Indices32 &pointIndices, VectorsT3< T > *points=nullptr, const ReusableData &reusableData=ReusableData()) const
Returns the closest tree points for a given query point.
Definition: Octree.h:777
BoundingBox boundingBox_
The bounding box of this tree node.
Definition: Octree.h:252
OctreeT & operator=(const OctreeT &octree)=delete
Disabled copy constructor.
const Indices32 & pointIndices() const
Returns the indices of the tree points which belong to this leaf node.
Definition: Octree.h:611
const OctreeT< T > *const * childNodes() const
Returns the eight child nodes of this tree node.
Definition: Octree.h:617
bool isValid() const
Returns whether this node is valid (if this node has a valid bounding box)
Definition: Octree.h:848
This class implements an infinite line in 3D space.
Definition: Line3.h:70
bool isValid() const
Returns whether this line has valid parameters.
Definition: Line3.h:303
This class implements a vector with three elements.
Definition: Vector3.h:97
const T & y() const noexcept
Returns the y value.
Definition: Vector3.h:812
const T & x() const noexcept
Returns the x value.
Definition: Vector3.h:800
const T & z() const noexcept
Returns the z value.
Definition: Vector3.h:824
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition: Vector3.h:842
T sqrDistance(const VectorT3< T > &right) const
Returns the square distance between this 3D position and a second 3D position.
Definition: Vector3.h:682
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition: Base.h:96
uint32_t Index32
Definition of a 32 bit index value.
Definition: Base.h:84
OctreeT< double > OctreeD
Definition of an Octree using double as data type.
Definition: Octree.h:39
OctreeT< float > OctreeF
Definition of an Octree using float as data type.
Definition: Octree.h:46
OctreeT< Scalar > Octree
Definition of an Octree using Scalar as data type.
Definition: Octree.h:25
float Scalar
Definition of a scalar type.
Definition: Math.h:128
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition: Vector3.h:22
std::vector< VectorT3< T > > VectorsT3
Definition of a typename alias for vectors with VectorT3 objects.
Definition: Vector3.h:58
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15