43#ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_SPLIT_HEURISTICS_H
44#define LASS_GUARDIAN_OF_INCLUSION_SPAT_SPLIT_HEURISTICS_H
56 template <
typename ObjectTraits>
57 typename ObjectTraits::TValue aabbCenterForAxis(
const typename ObjectTraits::TAabb& box,
size_t axis)
59 return (ObjectTraits::coord(ObjectTraits::aabbMin(box), axis) + ObjectTraits::coord(ObjectTraits::aabbMax(box), axis)) / 2;
62 template <
typename ObjectTraits>
66 LessAxis(
size_t iAxis): axis_(iAxis) {}
67 template <
typename Input>
bool operator()(
const Input& a,
const Input& b)
const
69 return aabbCenterForAxis<ObjectTraits>(a.aabb, axis_) < aabbCenterForAxis<ObjectTraits>(b.aabb, axis_);
78template <
typename ObjectTraits>
81 typedef typename ObjectTraits::TAabb TAabb;
82 typedef typename ObjectTraits::TValue TValue;
85 constexpr static TAxis dontSplit = size_t(-1);
87 SplitInfo(
const TAabb& aabb, TValue x, TAxis axis):
88 aabb(aabb), x(x), axis(axis)
92 static SplitInfo makeLeaf(
const TAabb& aabb)
94 return SplitInfo(aabb, 0, dontSplit);
97 bool isLeaf()
const {
return axis == dontSplit; }
110 template <
typename ObjectTraits>
114 Splitter(
const SplitInfo<ObjectTraits>& split): split_(
split) {}
115 template <
typename Input>
bool operator()(
const Input& input)
const
117 return aabbCenterForAxis<ObjectTraits>(input.aabb, split_.axis) <= split_.x;
120 SplitInfo<ObjectTraits> split_;
126class DefaultSplitHeuristics
129 DefaultSplitHeuristics(
size_t maxObjectsPerLeaf,
size_t maxDepth):
130 maxObjectsPerLeaf_(maxObjectsPerLeaf),
135 size_t maxObjectsPerLeaf()
const {
return maxObjectsPerLeaf_; }
136 size_t maxDepth()
const {
return maxDepth_; }
140 void swap(DefaultSplitHeuristics& other)
142 std::swap(maxObjectsPerLeaf_, other.maxObjectsPerLeaf_);
143 std::swap(maxDepth_, other.maxDepth_);
146 template <
typename ObjectTraits,
typename RandomIterator>
147 SplitInfo<ObjectTraits> split(RandomIterator first, RandomIterator last)
149 typedef typename ObjectTraits::TAabb TAabb;
150 typedef typename ObjectTraits::TPoint TPoint;
151 typedef typename ObjectTraits::TValue TValue;
153 LASS_ASSERT(maxObjectsPerLeaf_ > 0);
155 TAabb aabb = ObjectTraits::aabbEmpty();
156 for (RandomIterator i = first; i != last; ++i)
158 aabb = ObjectTraits::aabbJoin(aabb, i->aabb);
161 const size_t n =
static_cast<size_t>(last - first);
162 if (n <= maxObjectsPerLeaf_)
164 return SplitInfo<ObjectTraits>::makeLeaf(aabb);
167 const TPoint min = ObjectTraits::aabbMin(aabb);
168 const TPoint max = ObjectTraits::aabbMax(aabb);
170 TValue maxDistance = ObjectTraits::coord(max, 0) - ObjectTraits::coord(min, 0);
171 for (
size_t k = 1; k < ObjectTraits::dimension; ++k)
173 const TValue distance = ObjectTraits::coord(max, k) - ObjectTraits::coord(min, k);
174 if (distance > maxDistance)
177 maxDistance = distance;
181 const TValue x = impl::aabbCenterForAxis<ObjectTraits>(aabb, axis);
182 return SplitInfo<ObjectTraits>(aabb, x, axis);
186 size_t maxObjectsPerLeaf_;
192class SAHSplitHeuristics
195 SAHSplitHeuristics(
size_t maxObjectsPerLeaf,
size_t maxDepth):
196 maxObjectsPerLeaf_(maxObjectsPerLeaf),
201 size_t maxObjectsPerLeaf()
const {
return maxObjectsPerLeaf_; }
202 size_t maxDepth()
const {
return maxDepth_; }
206 void swap(SAHSplitHeuristics& other)
208 std::swap(maxObjectsPerLeaf_, other.maxObjectsPerLeaf_);
209 std::swap(maxDepth_, other.maxDepth_);
212 template <
typename ObjectTraits,
typename RandomIterator>
213 SplitInfo<ObjectTraits> split(RandomIterator first, RandomIterator last)
215 typedef typename ObjectTraits::TAabb TAabb;
216 typedef typename ObjectTraits::TValue TValue;
218 const TValue costNode = 1;
219 const TValue costObject = 1000;
221 LASS_ASSERT(maxObjectsPerLeaf_ > 0);
223 const size_t n =
static_cast<size_t>(last - first);
224 if (n <= maxObjectsPerLeaf_)
226 TAabb aabb = ObjectTraits::aabbEmpty();
227 for (RandomIterator i = first; i != last; ++i)
229 aabb = ObjectTraits::aabbJoin(aabb, i->aabb);
231 return SplitInfo<ObjectTraits>::makeLeaf(aabb);
234 TValue bestCost = n * costObject;
235 size_t bestAxis = SplitInfo<ObjectTraits>::dontSplit;
237 std::vector<TValue> leftArea(n);
238 TAabb totalBox = ObjectTraits::aabbEmpty();
239 TValue totalArea = 0;
241 for (
size_t axis = 0; axis < ObjectTraits::dimension; ++axis)
243 std::sort(first, last, impl::LessAxis<ObjectTraits>(axis));
245 TAabb box = ObjectTraits::aabbEmpty();
246 for (
size_t k = 0; k < n; ++k)
248 RandomIterator i = first +
static_cast<std::ptrdiff_t
>(k);
249 box = ObjectTraits::aabbJoin(box, i->aabb);
250 leftArea[k] = ObjectTraits::aabbSurfaceArea(box);
256 totalArea = ObjectTraits::aabbSurfaceArea(totalBox);
259 return SplitInfo<ObjectTraits>::makeLeaf(totalBox);
263 box = ObjectTraits::aabbEmpty();
264 for (
size_t k = n; k > 0; --k)
266 RandomIterator i = first +
static_cast<std::ptrdiff_t
>(k) - 1;
267 const TValue rightArea = ObjectTraits::aabbSurfaceArea(box);
268 const TValue cost = 2 * costNode + (leftArea[k - 1] * k + rightArea * (n - k)) * costObject / totalArea;
273 bestX = impl::aabbCenterForAxis<ObjectTraits>(i->aabb, axis);
275 box = ObjectTraits::aabbJoin(box, i->aabb);
279 return SplitInfo<ObjectTraits>(totalBox, bestX, bestAxis);
284 size_t maxObjectsPerLeaf_;
std::vector< std::basic_string< Char, Traits, Alloc > > split(const std::basic_string< Char, Traits, Alloc > &to_be_split)
Reflects the Python function split without seperator argument.
spatial subdivisions, quadtrees, octrees, meshes in 2D and 3D, triangulators, ...
Library for Assembled Shared Sources.