141class QbvhTree:
public SplitHeuristics
145 using TSelf = QbvhTree<ObjectType, ObjectTraits, SplitHeuristics>;
147 using TObject = ObjectType;
148 using TObjectTraits = ObjectTraits;
149 using TSplitHeuristics = SplitHeuristics;
151 using TObjectIterator =
typename TObjectTraits::TObjectIterator;
152 using TObjectReference =
typename TObjectTraits::TObjectReference;
153 using TAabb =
typename TObjectTraits::TAabb;
154 using TRay =
typename TObjectTraits::TRay;
155 using TPoint =
typename TObjectTraits::TPoint;
156 using TVector =
typename TObjectTraits::TVector;
157 using TValue =
typename TObjectTraits::TValue;
158 using TParam =
typename TObjectTraits::TParam;
159 using TReference =
typename TObjectTraits::TReference;
160 using TConstReference =
typename TObjectTraits::TConstReference;
161 using TInfo =
typename TObjectTraits::TInfo;
163 using TNumTraits = num::NumTraits<TValue>;
165 using TObjectIterators = std::vector<TObjectIterator>;
171 Neighbour(TObjectIterator
object, TValue squaredDistance):
172 object_(
object), squaredDistance_(squaredDistance) {}
173 TObjectIterator object()
const {
return object_; }
174 TValue squaredDistance()
const {
return squaredDistance_; }
175 TObjectIterator operator->()
const {
return object_; }
176 TObjectReference operator*()
const {
return TObjectTraits::object(object_); }
177 bool operator<(
const Neighbour& other)
const {
return squaredDistance_ < other.squaredDistance_; }
179 TObjectIterator object_;
180 TValue squaredDistance_;
183 constexpr static size_t dimension = TObjectTraits::dimension;
184 constexpr static size_t defaultMaxObjectsPerLeaf = 1;
185 constexpr static size_t defaultMaxDepth = 20;
187 QbvhTree(TSplitHeuristics heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
188 QbvhTree(TObjectIterator first, TObjectIterator last, TSplitHeuristics heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
189 QbvhTree(TSelf&& other)
noexcept;
191 TSelf& operator=(TSelf&& other)
noexcept;
194 void reset(TObjectIterator first, TObjectIterator last);
198 bool contains(
const TPoint& point,
const TInfo* info = 0)
const;
200 template <
typename OutputIterator>
201 OutputIterator
find(
const TPoint& point, OutputIterator result,
const TInfo* info = 0)
const;
202 template <
typename OutputIterator>
203 OutputIterator
find(
const TAabb& box, OutputIterator result,
const TInfo* info = 0)
const;
204 template <
typename OutputIterator>
205 OutputIterator
find(
const TRay& ray, TParam tMin, TParam tMax, OutputIterator result,
const TInfo* info = 0)
const;
207 TObjectIterator
intersect(
const TRay& ray, TReference t, TParam tMin = 0,
const TInfo* info = 0)
const;
208 bool intersects(
const TRay& ray, TParam tMin = 0, TParam tMax = std::numeric_limits<TValue>::infinity(),
const TInfo* info = 0)
const;
211 template <
typename RandomIterator>
212 RandomIterator
rangeSearch(
const TPoint& center, TParam maxRadius,
size_t maxCount, RandomIterator first,
const TInfo* info = 0)
const;
215 const TObjectIterator
end()
const;
220 constexpr static size_t stackSize_ = 128;
222 using TIndex = unsigned;
228 TObjectIterator object;
229 Input(
const TAabb&
aabb, TObjectIterator
object):
aabb(
aabb), object(object) {}
231 using TInputs = std::vector<Input>;
232 using TInputIterator =
typename TInputs::iterator;
237 constexpr static size_t countBits = 4;
238 constexpr static TIndex maxCount = 1 << countBits;
239 constexpr static TIndex maxObject =
static_cast<TIndex
>(std::numeric_limits<int>::max()) >> countBits;
240 constexpr static TIndex maxNode =
static_cast<TIndex
>(std::numeric_limits<int>::max()) - 1;
243 Child(): index_(0) {}
246 explicit Child(TIndex node):
247 index_(static_cast<int>(node + 1))
249 LASS_ASSERT(index_ > 0);
253 Child(TIndex first, TIndex count):
254 index_( -static_cast<int>((first << countBits) | (count - 1)) - 1 )
256 LASS_ASSERT(index_ < 0);
257 LASS_ASSERT((count > 0 && count <= maxCount) && (first + count -1 <= maxObject));
260 bool isEmpty()
const {
return !index_; }
261 bool isInternal()
const {
return index_ > 0; }
262 bool isLeaf()
const {
return index_ < 0; }
263 TIndex node()
const { LASS_ASSERT(index_ > 0);
return static_cast<TIndex
>(index_ - 1); }
264 TIndex first()
const { LASS_ASSERT(index_ < 0);
return static_cast<TIndex
>(-(index_ + 1)) >> countBits; }
265 TIndex count()
const { LASS_ASSERT(index_ < 0);
return (
static_cast<TIndex
>(-(index_ + 1)) & (maxCount - 1)) + 1; }
271 using TPoint_ = impl::qbvh::Point<TValue, dimension>;
272 using TRay_ = impl::qbvh::Ray<TValue, dimension>;
273 using TAabb_ = impl::qbvh::Aabb<TValue, dimension>;
274 using TQAabb_ = impl::qbvh::QAabb<TValue, dimension>;
276 struct alignas(128) Node
284 using TNodes = std::vector<Node>;
286 using TSplitInfo = SplitInfo<TObjectTraits>;
288 Child balance(TInputIterator first, TInputIterator last, TAabb& bounds);
289 TSplitInfo forceSplit(
const TAabb& bounds);
291 bool doContains(Child root,
const TPoint& point,
const TInfo* info)
const;
293 template <
typename OutputIterator>
294 OutputIterator doFind(Child root,
const TPoint& point, OutputIterator result,
const TInfo* info)
const;
295 template <
typename OutputIterator>
296 OutputIterator doFind(Child root,
const TAabb& box, OutputIterator result,
const TInfo* info)
const;
297 template <
typename OutputIterator>
298 OutputIterator doFind(Child root,
const TRay& ray,
const TVector& invDir, TParam tMin, TParam tMax, OutputIterator result,
const TInfo* info)
const;
300 TObjectIterator doIntersect(Child root,
const TRay& ray,
const TVector& invDir, TReference t, TParam tMin,
const TInfo* info)
const;
301 bool doIntersects(Child root,
const TRay& ray,
const TVector& invDir, TParam tMin, TParam tMax,
const TInfo* info)
const;
303 void doNearestNeighbour(Child root,
const TPoint& point,
const TInfo* info, Neighbour& best)
const;
304 template <
typename RandomIterator>
305 RandomIterator doRangeSearch(Child root,
const TPoint& center, TReference squaredRadius,
size_t maxCount, RandomIterator first, RandomIterator last,
const TInfo* info)
const;
307 bool volumeIntersect(
const TAabb& box,
const TRay& ray,
const TVector& invDir, TReference t, TParam tMin)
const;
308 bool volumeIntersects(
const TAabb& box,
const TRay& ray,
const TVector& invDir, TParam tMin, TParam tMax)
const;
310 static TPoint_ makePoint(
const TPoint& point);
311 static TRay_ makeRay(
const TRay& ray);
312 static TAabb_ makeAabb(
const TAabb&
aabb);
316 TObjectIterators objects_;
317 std::unique_ptr<TObjectIterator> end_;