137class Aabb8Tree:
public SplitHeuristics
141 using TSelf = Aabb8Tree<ObjectType, ObjectTraits, SplitHeuristics>;
143 using TObject = ObjectType;
144 using TObjectTraits = ObjectTraits;
145 using TSplitHeuristics = SplitHeuristics;
147 using TObjectIterator =
typename TObjectTraits::TObjectIterator;
148 using TObjectReference =
typename TObjectTraits::TObjectReference;
149 using TAabb =
typename TObjectTraits::TAabb;
150 using TRay =
typename TObjectTraits::TRay;
151 using TPoint =
typename TObjectTraits::TPoint;
152 using TVector =
typename TObjectTraits::TVector;
153 using TValue =
typename TObjectTraits::TValue;
154 using TParam =
typename TObjectTraits::TParam;
155 using TReference =
typename TObjectTraits::TReference;
156 using TConstReference =
typename TObjectTraits::TConstReference;
157 using TInfo =
typename TObjectTraits::TInfo;
159 using TNumTraits = num::NumTraits<TValue>;
161 using TObjectIterators = std::vector<TObjectIterator>;
167 Neighbour(TObjectIterator
object, TValue squaredDistance):
168 object_(
object), squaredDistance_(squaredDistance) {}
169 TObjectIterator object()
const {
return object_; }
170 TValue squaredDistance()
const {
return squaredDistance_; }
171 TObjectIterator operator->()
const {
return object_; }
172 TObjectReference operator*()
const {
return TObjectTraits::object(object_); }
173 bool operator<(
const Neighbour& other)
const {
return squaredDistance_ < other.squaredDistance_; }
175 TObjectIterator object_;
176 TValue squaredDistance_;
179 constexpr static size_t dimension = TObjectTraits::dimension;
180 constexpr static size_t defaultMaxObjectsPerLeaf = 1;
181 constexpr static size_t defaultMaxDepth = 20;
183 Aabb8Tree(TSplitHeuristics heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
184 Aabb8Tree(TObjectIterator first, TObjectIterator last, TSplitHeuristics heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
185 Aabb8Tree(TSelf&& other)
noexcept;
187 TSelf& operator=(TSelf&& other)
noexcept;
190 void reset(TObjectIterator first, TObjectIterator last);
194 bool contains(
const TPoint& point,
const TInfo* info = 0)
const;
196 template <
typename OutputIterator>
197 OutputIterator
find(
const TPoint& point, OutputIterator result,
const TInfo* info = 0)
const;
198 template <
typename OutputIterator>
199 OutputIterator
find(
const TAabb& box, OutputIterator result,
const TInfo* info = 0)
const;
200 template <
typename OutputIterator>
201 OutputIterator
find(
const TRay& ray, TParam tMin, TParam tMax, OutputIterator result,
const TInfo* info = 0)
const;
203 TObjectIterator
intersect(
const TRay& ray, TReference t, TParam tMin = 0,
const TInfo* info = 0)
const;
204 bool intersects(
const TRay& ray, TParam tMin = 0, TParam tMax = std::numeric_limits<TValue>::infinity(),
const TInfo* info = 0)
const;
207 template <
typename RandomIterator>
208 RandomIterator
rangeSearch(
const TPoint& center, TParam maxRadius,
size_t maxCount, RandomIterator first,
const TInfo* info = 0)
const;
211 const TObjectIterator
end()
const;
216 constexpr static size_t stackSize_ = 256;
218 using TIndex = unsigned;
224 TObjectIterator object;
225 Input(
const TAabb&
aabb, TObjectIterator
object):
aabb(
aabb), object(object) {}
227 using TInputs = std::vector<Input>;
228 using TInputIterator =
typename TInputs::iterator;
233 constexpr static size_t countBits = 4;
234 constexpr static TIndex maxCount = 1 << countBits;
235 constexpr static TIndex maxObject =
static_cast<TIndex
>(std::numeric_limits<int>::max()) >> countBits;
236 constexpr static TIndex maxNode =
static_cast<TIndex
>(std::numeric_limits<int>::max()) - 1;
239 Child(): index_(0) {}
242 explicit Child(TIndex node):
243 index_(static_cast<int>(node + 1))
245 LASS_ASSERT(index_ > 0);
249 Child(TIndex first, TIndex count):
250 index_( -static_cast<int>((first << countBits) | (count - 1)) - 1 )
252 LASS_ASSERT(index_ < 0);
253 LASS_ASSERT((first >= 0) && (count > 0 && count <= maxCount) && (first + count -1 <= maxObject));
256 bool isEmpty()
const {
return !index_; }
257 bool isInternal()
const {
return index_ > 0; }
258 bool isLeaf()
const {
return index_ < 0; }
259 TIndex node()
const { LASS_ASSERT(index_ > 0);
return static_cast<TIndex
>(index_ - 1); }
260 TIndex first()
const { LASS_ASSERT(index_ < 0);
return static_cast<TIndex
>(-(index_ + 1)) >> countBits; }
261 TIndex count()
const { LASS_ASSERT(index_ < 0);
return (
static_cast<TIndex
>(-(index_ + 1)) & (maxCount - 1)) + 1; }
267 using TPoint_ = impl::aabb8::Point<TValue, dimension>;
268 using TRay_ = impl::aabb8::Ray<TValue, dimension>;
269 using TAabb_ = impl::aabb8::Aabb<TValue, dimension>;
270 using TQAabb_ = impl::aabb8::Aabb8<TValue, dimension>;
272 struct alignas(64) Node
279 using TNodes = std::vector<Node>;
281 using TSplitInfo = SplitInfo<TObjectTraits>;
283 Child balance(TInputIterator first, TInputIterator last, TAabb& bounds);
284 TSplitInfo forceSplit(
const TAabb& bounds);
286 bool doContains(Child root,
const TPoint& point,
const TInfo* info)
const;
288 template <
typename OutputIterator>
289 OutputIterator doFind(Child root,
const TPoint& point, OutputIterator result,
const TInfo* info)
const;
290 template <
typename OutputIterator>
291 OutputIterator doFind(Child root,
const TAabb& box, OutputIterator result,
const TInfo* info)
const;
292 template <
typename OutputIterator>
293 OutputIterator doFind(Child root,
const TRay& ray,
const TVector& invDir, TParam tMin, TParam tMax, OutputIterator result,
const TInfo* info)
const;
295 TObjectIterator doIntersect(Child root,
const TRay& ray,
const TVector& invDir, TReference t, TParam tMin,
const TInfo* info)
const;
296 bool doIntersects(Child root,
const TRay& ray,
const TVector& invDir, TParam tMin, TParam tMax,
const TInfo* info)
const;
298 void doNearestNeighbour(Child root,
const TPoint& point,
const TInfo* info, Neighbour& best)
const;
299 template <
typename RandomIterator>
300 RandomIterator doRangeSearch(Child root,
const TPoint& center, TReference squaredRadius,
size_t maxCount, RandomIterator first, RandomIterator last,
const TInfo* info)
const;
302 bool volumeIntersect(
const TAabb& box,
const TRay& ray,
const TVector& invDir, TReference t, TParam tMin)
const;
303 bool volumeIntersects(
const TAabb& box,
const TRay& ray,
const TVector& invDir, TParam tMin, TParam tMax)
const;
305 static TPoint_ makePoint(
const TPoint& point);
306 static TRay_ makeRay(
const TRay& ray);
307 static TAabb_ makeAabb(
const TAabb&
aabb);
311 TObjectIterators objects_;
312 std::unique_ptr<TObjectIterator> end_;