Library of Assembled Shared Sources
aabb_tree.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2024 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45/** @class lass::spat::AabbTree
46 * @brief an AABB bounding volume tree that looks similar to a KdTree
47 * @author Bram de Greve [BdG]
48 *
49 * the AabbTree does NOT own the objects. You must keep them yourself!
50 */
51
52#ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_AABB_TREE_H
53#define LASS_GUARDIAN_OF_INCLUSION_SPAT_AABB_TREE_H
54
55//#define LASS_SPAT_AABB_TREE_DIAGNOSTICS
56
57#ifndef LASS_SPAT_AABB_TREE_STACK_SIZE
58# define LASS_SPAT_AABB_TREE_STACK_SIZE 32
59#endif
60
61#include "spat_common.h"
63#include "split_heuristics.h"
64#include "../util/shared_ptr.h"
65
66namespace lass
67{
68namespace spat
69{
70
71template
72<
73 typename ObjectType,
74 typename ObjectTraits = DefaultObjectTraits<ObjectType>,
75 typename SplitHeuristics = DefaultSplitHeuristics
76>
77class AabbTree: public SplitHeuristics
78{
79public:
80
81 typedef AabbTree<ObjectType, ObjectTraits, SplitHeuristics> TSelf;
82
83 typedef ObjectType TObject;
84 typedef ObjectTraits TObjectTraits;
85 typedef SplitHeuristics TSplitHeuristics;
86
87 typedef typename TObjectTraits::TObjectIterator TObjectIterator;
88 typedef typename TObjectTraits::TObjectReference TObjectReference;
89 typedef typename TObjectTraits::TAabb TAabb;
90 typedef typename TObjectTraits::TRay TRay;
91 typedef typename TObjectTraits::TPoint TPoint;
92 typedef typename TObjectTraits::TVector TVector;
93 typedef typename TObjectTraits::TValue TValue;
94 typedef typename TObjectTraits::TParam TParam;
95 typedef typename TObjectTraits::TReference TReference;
96 typedef typename TObjectTraits::TConstReference TConstReference;
97 typedef typename TObjectTraits::TInfo TInfo;
98
99 enum
100 {
101 dimension = TObjectTraits::dimension,
102 defaultMaxObjectsPerLeaf = 1,
103 defaultMaxDepth = 20
104 };
105
106 typedef std::vector<TObjectIterator> TObjectIterators;
107
108 class Neighbour
109 {
110 public:
111 Neighbour() {}
112 Neighbour(TObjectIterator object, TValue squaredDistance):
113 object_(object), squaredDistance_(squaredDistance) {}
114 TObjectIterator object() const { return object_; }
115 TValue squaredDistance() const { return squaredDistance_; }
116 TObjectIterator operator->() const { return object_; }
117 TObjectReference operator*() const { return TObjectTraits::object(object_); }
118 bool operator<(const Neighbour& other) const { return squaredDistance_ < other.squaredDistance_; }
119 private:
120 TObjectIterator object_;
121 TValue squaredDistance_;
122 };
123
124 AabbTree(const TSplitHeuristics& heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
125 AabbTree(TObjectIterator first, TObjectIterator last, const TSplitHeuristics& heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
126 AabbTree(TSelf&& other) noexcept;
127
128 TSelf & operator=(TSelf&& other) noexcept;
129
130 void reset();
131 void reset(TObjectIterator first, TObjectIterator last);
132
133 const TAabb aabb() const;
134
135 bool contains(const TPoint& point, const TInfo* info = 0) const;
136
137 template <typename OutputIterator>
138 OutputIterator find(const TPoint& point, OutputIterator result, const TInfo* info = 0) const;
139 template <typename OutputIterator>
140 OutputIterator find(const TAabb& box, OutputIterator result, const TInfo* info = 0) const;
141 template <typename OutputIterator>
142 OutputIterator find(const TRay& ray, TParam tMin, TParam tMax, OutputIterator result, const TInfo* info = 0) const;
143
144 TObjectIterator intersect(const TRay& ray, TReference t, TParam tMin = 0, const TInfo* info = 0) const;
145 bool intersects(const TRay& ray, TParam tMin = 0,
146 TParam tMax = std::numeric_limits<TValue>::infinity(), const TInfo* info = 0) const;
147 const Neighbour nearestNeighbour(const TPoint& point, const TInfo* info = 0) const;
148 template <typename RandomIterator>
149 RandomIterator rangeSearch(const TPoint& center, TParam maxRadius, size_t maxCount,
150 RandomIterator first, const TInfo* info = 0) const;
151
152 bool isEmpty() const;
153 const TObjectIterator end() const;
154 void swap(TSelf& other);
155
156private:
157
158 typedef unsigned TIndex;
159 struct Input
160 {
161 TAabb aabb;
162 TObjectIterator object;
163 Input(const TAabb& aabb, TObjectIterator object): aabb(aabb), object(object) {}
164 };
165 typedef std::vector<Input> TInputs;
166 typedef typename TInputs::iterator TInputIterator;
167
168 class Node
169 {
170 public:
171 static constexpr TIndex sentinelInternal = std::numeric_limits<TIndex>::max();
172
173 explicit Node(const TAabb& aabb):
174 aabb_(aabb),
175 first_(sentinelInternal)
176 {
177 }
178 Node(const TAabb& aabb, TIndex first, TIndex last):
179 aabb_(aabb),
180 first_(first)
181 {
182 LASS_ASSERT(first < sentinelInternal && last < sentinelInternal && last > first);
183 last_ = last; // do union stuff here
184 }
185
186 bool isInternal() const { return first_ == sentinelInternal; }
187 const TAabb& aabb() const { return aabb_; }
188 TIndex right() const { LASS_ASSERT(isInternal()); return right_; }
189 void setRight(TIndex right) { LASS_ASSERT(isInternal()); right_ = right; }
190
191 bool isLeaf() const { return !isInternal(); }
192 TIndex first() const { LASS_ASSERT(isLeaf()); return first_; }
193 TIndex last() const { LASS_ASSERT(isLeaf()); return last_; }
194 private:
195 TAabb aabb_; // both
196 TIndex first_; // ==sentinelInternal:internal, else:leaf
197 union
198 {
199 TIndex right_; // internal
200 TIndex last_; // leaf
201 };
202 };
203 typedef std::vector<Node> TNodes;
204
205 TIndex balance(TInputIterator first, TInputIterator last);
206 TIndex addLeafNode(const TAabb& aabb, TInputIterator first, TInputIterator last);
207 TIndex addInternalNode(const TAabb& aabb);
208
209 bool doContains(TIndex index, const TPoint& point, const TInfo* info) const;
210
211 template <typename OutputIterator>
212 OutputIterator doFind(TIndex index, const TPoint& point, OutputIterator first, const TInfo* info) const;
213 template <typename OutputIterator>
214 OutputIterator doFind(TIndex index, const TAabb& aabb, OutputIterator first, const TInfo* info) const;
215 template <typename OutputIterator>
216 OutputIterator doFind(TIndex index, const TRay& ray, const TVector& invDir, TParam tMin, TParam tMax, OutputIterator first, const TInfo* info) const;
217
218 TObjectIterator doIntersect(TIndex index, const TRay& ray, const TVector& invDir, TReference t, TParam tMin, const TInfo* info) const;
219 bool doIntersects(TIndex iIndex, const TRay& ray, const TVector& invDir, TParam tMin, TParam tMax, const TInfo* info) const;
220 void doNearestNeighbour(TIndex index, const TPoint& point, const TInfo* info, Neighbour& best) const;
221 template <typename RandomIterator>
222 RandomIterator doRangeSearch(TIndex index, const TPoint& point, TReference squaredRadius,
223 size_t maxCount, RandomIterator first, RandomIterator last, const TInfo* info) const;
224
225 void getChildren(TIndex index, const TPoint& target, TIndex indices[2], TValue squaredDistances[2]) const;
226 bool volumeIntersect(const TAabb& box, const TRay& ray, const TVector& invDir, TReference t, TParam tMin) const;
227 bool volumeIntersects(const TAabb& box, const TRay& ray, const TVector& invDir, TParam tMin, TParam tMax) const;
228
229 TObjectIterators objects_;
230 TNodes nodes_;
231 std::unique_ptr<TObjectIterator> end_;
232};
233
234
235}
236
237}
238
239#include "aabb_tree.inl"
240
241#endif
242
243// EOF
OutputIterator find(const TRay &ray, TParam tMin, TParam tMax, OutputIterator result, const TInfo *info=0) const
Find all objects that have an intersection with ray between tMin and tMax.
bool contains(const TPoint &point, const TInfo *info=0) const
Check whether there's any object in the tree that contains point.
OutputIterator find(const TAabb &box, OutputIterator result, const TInfo *info=0) const
Find all objects that intersect (overlap) with box.
OutputIterator find(const TPoint &point, OutputIterator result, const TInfo *info=0) const
Find all objects that contain point.
spatial subdivisions, quadtrees, octrees, meshes in 2D and 3D, triangulators, ...
Definition aabb8_tree.h:80
Library for Assembled Shared Sources.
Definition config.h:53
default traits for objects to be stored in spatial subdivision trees