CellRangeDataTreeStrategy.h
Go to the documentation of this file.
1#ifndef GfxTL__CELLRANGEDATATREESTRATEGY_HEADER__
2#define GfxTL__CELLRANGEDATATREESTRATEGY_HEADER__
3#include <vector>
4
5namespace GfxTL
6{
7 template <class InheritedStrategyT, class KernelT>
9 {
10 typedef typename KernelT::value_type value_type;
11
12 class CellData : public InheritedStrategyT::CellData
13 {
14 public:
15 typedef typename KernelT::value_type value_type;
16 typedef typename KernelT::HandleType HandleType;
17 typedef std::pair<HandleType, HandleType> CellRange;
18
19 size_t
20 Size() const
21 {
22 return m_range.second - m_range.first;
23 }
24
25 const CellRange&
26 Range() const
27 {
28 return m_range;
29 }
30
33 {
34 return m_range;
35 }
36
38 };
39
40 template <class BaseT>
41 class StrategyBase : public InheritedStrategyT::template StrategyBase<BaseT>, public KernelT
42 {
43 public:
44 typedef typename InheritedStrategyT::template StrategyBase<BaseT> BaseType;
45 typedef typename BaseT::CellType CellType;
46 typedef typename KernelT::HandleType HandleType;
47 typedef typename KernelT::DereferencedType DereferencedType;
48 typedef std::pair<HandleType, HandleType> CellRange;
49 typedef typename KernelT::value_type value_type;
51
52 protected:
54 {
55 public:
58 {
59 return m_range;
60 }
61
62 const CellRange&
63 Range() const
64 {
65 return m_range;
66 }
67
68 private:
69 CellRange m_range;
70 };
71
72 template <class BaseTraversalT>
73 class GlobalTraversalInformation : public BaseTraversalT
74 {
75 };
76
77 template <class BaseTraversalT>
78 class TraversalInformation : public BaseTraversalT
79 {
80 };
81
82 template <class BaseTraversalT>
83 class CellRangeTraversalInformation : public BaseTraversalT
84 {
85 };
86
87 template <class BuildInformationT>
88 void
89 InitRootBuildInformation(BuildInformationT* bi) const
90 {
91 bi->Range() = CellRange(KernelT::BeginHandle(), KernelT::EndHandle());
92 }
93
94 template <class BuildInformationT>
95 void
97 const BuildInformationT& parentInfo,
98 unsigned int childIdx,
99 BuildInformationT* bi) const
100 {
101 bi->Range() = parent[childIdx].Range();
102 }
103
104 template <class BuildInformationT>
105 void
106 InitRoot(const BuildInformationT& bi, CellType* cell)
107 {
108 cell->m_range.first = KernelT::BeginHandle();
109 cell->m_range.second = KernelT::EndHandle();
110 }
111
112 template <class BuildInformationT>
113 void
114 InitCell(const CellType& parent,
115 const BuildInformationT& parentInfo,
116 unsigned int childIdx,
117 const BuildInformationT& bi,
118 CellType* cell)
119 {
120 cell->Range() = bi.Range();
121 }
122
123 template <class TraversalInformationT>
124 void
125 InitRootTraversalInformation(const CellType& root, TraversalInformationT* ti) const
126 {
127 }
128
129 template <class TraversalInformationT>
130 void
132 const TraversalInformationT& ti,
133 CellRange* range) const
134 {
135 *range = cell.Range();
136 }
137
138 template <class TraversalInformationT>
139 void
141 const TraversalInformationT& pTi,
142 unsigned int childIdx,
143 TraversalInformationT* ti) const
144 {
145 }
146
147 template <class SplitterT, class BuildInformationT>
148 void
149 SplitData(const SplitterT& split,
150 const CellType& parent,
151 const BuildInformationT&,
152 CellType* left,
153 CellType* right)
154 {
155 size_t sizes[2];
156 SplitData(split, parent.Range(), &sizes[0], &sizes[1]);
157 left->m_range.first = parent.m_range.first;
158 left->m_range.second = parent.m_range.first + sizes[0];
159 right->m_range.first = left->m_range.second;
160 right->m_range.second = right->m_range.first + sizes[1];
161 }
162
163 template <class SplitterT, class BuildInformationT>
164 void
165 SplitData(const SplitterT& split,
166 const CellType& parent,
167 const BuildInformationT&,
168 CellType* left,
169 BuildInformationT* leftBi,
170 CellType* right,
171 BuildInformationT* rightBi)
172 {
173 size_t sizes[2];
174 SplitData(split, parent.Range(), &sizes[0], &sizes[1]);
175 left->m_range.first = parent.m_range.first;
176 left->m_range.second = parent.m_range.first + sizes[0];
177 right->m_range.first = left->m_range.second;
178 right->m_range.second = right->m_range.first + sizes[1];
179 }
180
181 template <class SplitterT, class BuildInformationT>
182 void
183 SplitData(const SplitterT* splitters,
184 const unsigned int numSplitters,
185 const CellType& parent,
186 const BuildInformationT& parentInfo,
187 CellType** cells)
188 {
189 size_t* sizes = new size_t[size_t(1u) << numSplitters];
190 SplitData(splitters, numSplitters, parentInfo.Range(), sizes);
191 unsigned int childCount = 0;
192 HandleType begin = parent.m_range.first;
193 for (unsigned int i = 0; i < (1u << numSplitters); ++i)
194 if (sizes[i])
195 {
196 cells[i] = new CellType;
197 cells[i]->m_range.first = begin;
198 cells[i]->m_range.second = begin + sizes[i];
199 begin = cells[i]->m_range.second;
200 ++childCount;
201 }
202 else
203 {
204 cells[i] = NULL;
205 }
206 if (!cells[0] && childCount)
207 {
208 cells[0] = (CellType*)0x1;
209 }
210 delete[] sizes;
211 }
212
213 template <class SplitterT>
214 void
215 SplitData(const SplitterT* splitters,
216 const unsigned int numSplitters,
217 const CellRange& range,
218 size_t* sizes)
219 {
220 const unsigned int numChildren = 1 << numSplitters;
221 SplitData(splitters[0], range, &(sizes[0]), &(sizes[numChildren >> 1]));
222 if (numSplitters == 1)
223 {
224 return;
225 }
226 CellRange leftRange(range.first, range.first + sizes[0]),
227 rightRange(leftRange.second, range.second);
228 SplitData(splitters + 1, numSplitters - 1, leftRange, sizes);
229 SplitData(splitters + 1, numSplitters - 1, rightRange, sizes + (numChildren >> 1));
230 }
231
232 template <class SplitterT>
233 void
234 SplitData(const SplitterT& split, const CellRange& range, size_t* left, size_t* right)
235 {
236 if (range.second - range.first == 0)
237 {
238 *left = 0;
239 *right = 0;
240 return;
241 }
242 HandleType j = range.first;
243 HandleType k = range.second - 1;
244 while (1)
245 {
246 while (j <= k && split(this->at(this->Dereference(j))))
247 {
248 ++j;
249 }
250 while (j < k && !split(this->at(this->Dereference(k))))
251 {
252 --k;
253 }
254 if (j < k)
255 {
256 this->SwapHandles(k, j);
257 ++j;
258 --k;
259 }
260 else
261 {
262 break;
263 }
264 }
265 *left = j - range.first;
266 *right = (range.second - range.first) - *left;
267 }
268
269 void
271 const std::vector<size_t>& clusterid,
272 const std::vector<size_t>& clusterCount,
273 CellType** bis)
274 {
275 std::vector<size_t> clusterPositions(clusterCount.size());
276 clusterPositions[0] = 0;
277 bis[0]->Range() = CellRange(range.first, range.first + clusterCount[0]);
278 for (size_t i = 1; i < clusterCount.size(); ++i)
279 {
280 clusterPositions[i] = clusterPositions[i - 1] + clusterCount[i - 1];
281 bis[i]->Range() =
282 CellRange(range.first + clusterPositions[i],
283 range.first + clusterPositions[i] + clusterCount[i]);
284 }
285 std::vector<size_t> partitioning(clusterid.size());
286 for (size_t i = 0; i < clusterid.size(); ++i)
287 {
288 partitioning[i] = clusterPositions[clusterid[i]]++;
289 }
290 for (size_t i = 0; i < partitioning.size(); ++i)
291 while (i != partitioning[i])
292 {
293 KernelT::SwapHandles(range.first + i, range.first + partitioning[i]);
294 std::swap(partitioning[i], partitioning[partitioning[i]]);
295 }
296 }
297 };
298 };
299}; // namespace GfxTL
300
301#endif
std::pair< HandleType, HandleType > CellRange
void SplitData(const SplitterT *splitters, const unsigned int numSplitters, const CellType &parent, const BuildInformationT &parentInfo, CellType **cells)
void SplitData(const SplitterT &split, const CellType &parent, const BuildInformationT &, CellType *left, BuildInformationT *leftBi, CellType *right, BuildInformationT *rightBi)
void SplitData(const SplitterT &split, const CellType &parent, const BuildInformationT &, CellType *left, CellType *right)
void InitRootTraversalInformation(const CellType &root, TraversalInformationT *ti) const
void InitRoot(const BuildInformationT &bi, CellType *cell)
void SplitData(const SplitterT *splitters, const unsigned int numSplitters, const CellRange &range, size_t *sizes)
void PartitionDataRange(const CellRange &range, const std::vector< size_t > &clusterid, const std::vector< size_t > &clusterCount, CellType **bis)
void InitBuildInformation(const CellType &parent, const BuildInformationT &parentInfo, unsigned int childIdx, BuildInformationT *bi) const
InheritedStrategyT::template StrategyBase< BaseT > BaseType
void SplitData(const SplitterT &split, const CellRange &range, size_t *left, size_t *right)
void GetCellRange(const CellType &cell, const TraversalInformationT &ti, CellRange *range) const
void InitRootBuildInformation(BuildInformationT *bi) const
void InitCell(const CellType &parent, const BuildInformationT &parentInfo, unsigned int childIdx, const BuildInformationT &bi, CellType *cell)
void InitTraversalInformation(const CellType &parent, const TraversalInformationT &pTi, unsigned int childIdx, TraversalInformationT *ti) const
Definition AABox.h:10