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