PolyVox  0.2.1
Open source voxel management library
LargeVolumeSampler.inl
Go to the documentation of this file.
1 /*******************************************************************************
2 Copyright (c) 2005-2009 David Williams
3 
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7 
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11 
12  1. The origin of this software must not be misrepresented; you must not
13  claim that you wrote the original software. If you use this software
14  in a product, an acknowledgment in the product documentation would be
15  appreciated but is not required.
16 
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19 
20  3. This notice may not be removed or altered from any source
21  distribution.
22 *******************************************************************************/
23 
24 #define BORDER_LOW(x) ((( x >> this->mVolume->m_uBlockSideLengthPower) << this->mVolume->m_uBlockSideLengthPower) != x)
25 #define BORDER_HIGH(x) ((( (x+1) >> this->mVolume->m_uBlockSideLengthPower) << this->mVolume->m_uBlockSideLengthPower) != (x+1))
26 //#define BORDER_LOW(x) (( x % mVolume->m_uBlockSideLength) != 0)
27 //#define BORDER_HIGH(x) (( x % mVolume->m_uBlockSideLength) != mVolume->m_uBlockSideLength - 1)
28 
29 namespace PolyVox
30 {
31  template <typename VoxelType>
33  :BaseVolume<VoxelType>::template Sampler< LargeVolume<VoxelType> >(volume)
34  {
35  }
36 
37  template <typename VoxelType>
39  {
40  }
41 
42  template <typename VoxelType>
44  {
45  if(this == &rhs)
46  {
47  return *this;
48  }
49  this->mVolume = rhs.mVolume;
50  this->mXPosInVolume = rhs.mXPosInVolume;
51  this->mYPosInVolume = rhs.mYPosInVolume;
52  this->mZPosInVolume = rhs.mZPosInVolume;
53  mCurrentVoxel = rhs.mCurrentVoxel;
54  return *this;
55  }
56 
57  template <typename VoxelType>
59  {
60  if(uLevel == 0)
61  {
62  return getVoxel();
63  }
64  else if(uLevel == 1)
65  {
66  VoxelType tValue = getVoxel();
67  tValue = (std::min)(tValue, peekVoxel1px0py0pz());
68  tValue = (std::min)(tValue, peekVoxel0px1py0pz());
69  tValue = (std::min)(tValue, peekVoxel1px1py0pz());
70  tValue = (std::min)(tValue, peekVoxel0px0py1pz());
71  tValue = (std::min)(tValue, peekVoxel1px0py1pz());
72  tValue = (std::min)(tValue, peekVoxel0px1py1pz());
73  tValue = (std::min)(tValue, peekVoxel1px1py1pz());
74  return tValue;
75  }
76  else
77  {
78  const uint8_t uSize = 1 << uLevel;
79 
80  VoxelType tValue = (std::numeric_limits<VoxelType>::max)();
81  for(uint8_t z = 0; z < uSize; ++z)
82  {
83  for(uint8_t y = 0; y < uSize; ++y)
84  {
85  for(uint8_t x = 0; x < uSize; ++x)
86  {
87  tValue = (std::min)(tValue, this->mVolume->getVoxelAt(this->mXPosInVolume + x, this->mYPosInVolume + y, this->mZPosInVolume + z));
88  }
89  }
90  }
91  return tValue;
92  }
93  }
94 
95  template <typename VoxelType>
97  {
98  return *mCurrentVoxel;
99  }
100 
101  template <typename VoxelType>
103  {
104  setPosition(v3dNewPos.getX(), v3dNewPos.getY(), v3dNewPos.getZ());
105  }
106 
107  template <typename VoxelType>
109  {
110  this->mXPosInVolume = xPos;
111  this->mYPosInVolume = yPos;
112  this->mZPosInVolume = zPos;
113 
114  const int32_t uXBlock = this->mXPosInVolume >> this->mVolume->m_uBlockSideLengthPower;
115  const int32_t uYBlock = this->mYPosInVolume >> this->mVolume->m_uBlockSideLengthPower;
116  const int32_t uZBlock = this->mZPosInVolume >> this->mVolume->m_uBlockSideLengthPower;
117 
118  const uint16_t uXPosInBlock = static_cast<uint16_t>(this->mXPosInVolume - (uXBlock << this->mVolume->m_uBlockSideLengthPower));
119  const uint16_t uYPosInBlock = static_cast<uint16_t>(this->mYPosInVolume - (uYBlock << this->mVolume->m_uBlockSideLengthPower));
120  const uint16_t uZPosInBlock = static_cast<uint16_t>(this->mZPosInVolume - (uZBlock << this->mVolume->m_uBlockSideLengthPower));
121 
122  const uint32_t uVoxelIndexInBlock = uXPosInBlock +
123  uYPosInBlock * this->mVolume->m_uBlockSideLength +
124  uZPosInBlock * this->mVolume->m_uBlockSideLength * this->mVolume->m_uBlockSideLength;
125 
126  if(this->mVolume->m_regValidRegionInBlocks.containsPoint(Vector3DInt32(uXBlock, uYBlock, uZBlock)))
127  {
128  Block<VoxelType>* pUncompressedCurrentBlock = this->mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock);
129 
130  mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock;
131  }
132  else
133  {
134  mCurrentVoxel = this->mVolume->m_pUncompressedBorderData + uVoxelIndexInBlock;
135  }
136  }
137 
138  template <typename VoxelType>
140  {
141  //*mCurrentVoxel = tValue;
142  //Need to think what effect this has on any existing iterators.
143  assert(false);
144  return false;
145  }
146 
147  template <typename VoxelType>
149  {
150  //Note the *pre* increament here
151  if((++this->mXPosInVolume) % this->mVolume->m_uBlockSideLength != 0)
152  {
153  //No need to compute new block.
154  ++mCurrentVoxel;
155  }
156  else
157  {
158  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
159  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
160  }
161  }
162 
163  template <typename VoxelType>
165  {
166  //Note the *pre* increament here
167  if((++this->mYPosInVolume) % this->mVolume->m_uBlockSideLength != 0)
168  {
169  //No need to compute new block.
170  mCurrentVoxel += this->mVolume->m_uBlockSideLength;
171  }
172  else
173  {
174  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
175  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
176  }
177  }
178 
179  template <typename VoxelType>
181  {
182  //Note the *pre* increament here
183  if((++this->mZPosInVolume) % this->mVolume->m_uBlockSideLength != 0)
184  {
185  //No need to compute new block.
186  mCurrentVoxel += this->mVolume->m_uBlockSideLength * this->mVolume->m_uBlockSideLength;
187  }
188  else
189  {
190  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
191  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
192  }
193  }
194 
195  template <typename VoxelType>
197  {
198  //Note the *post* decreament here
199  if((this->mXPosInVolume--) % this->mVolume->m_uBlockSideLength != 0)
200  {
201  //No need to compute new block.
202  --mCurrentVoxel;
203  }
204  else
205  {
206  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
207  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
208  }
209  }
210 
211  template <typename VoxelType>
213  {
214  //Note the *post* decreament here
215  if((this->mYPosInVolume--) % this->mVolume->m_uBlockSideLength != 0)
216  {
217  //No need to compute new block.
218  mCurrentVoxel -= this->mVolume->m_uBlockSideLength;
219  }
220  else
221  {
222  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
223  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
224  }
225  }
226 
227  template <typename VoxelType>
229  {
230  //Note the *post* decreament here
231  if((this->mZPosInVolume--) % this->mVolume->m_uBlockSideLength != 0)
232  {
233  //No need to compute new block.
234  mCurrentVoxel -= this->mVolume->m_uBlockSideLength * this->mVolume->m_uBlockSideLength;
235  }
236  else
237  {
238  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
239  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
240  }
241  }
242 
243  template <typename VoxelType>
245  {
246  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
247  {
248  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
249  }
250  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1);
251  }
252 
253  template <typename VoxelType>
255  {
256  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) )
257  {
258  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength);
259  }
260  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume);
261  }
262 
263  template <typename VoxelType>
265  {
266  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
267  {
268  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
269  }
270  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1);
271  }
272 
273  template <typename VoxelType>
275  {
276  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
277  {
278  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
279  }
280  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1);
281  }
282 
283  template <typename VoxelType>
285  {
286  if( BORDER_LOW(this->mXPosInVolume) )
287  {
288  return *(mCurrentVoxel - 1);
289  }
290  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume);
291  }
292 
293  template <typename VoxelType>
295  {
296  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
297  {
298  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
299  }
300  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1);
301  }
302 
303  template <typename VoxelType>
305  {
306  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
307  {
308  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
309  }
310  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1);
311  }
312 
313  template <typename VoxelType>
315  {
316  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) )
317  {
318  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength);
319  }
320  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume);
321  }
322 
323  template <typename VoxelType>
325  {
326  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
327  {
328  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
329  }
330  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1);
331  }
332 
334 
335  template <typename VoxelType>
337  {
338  if( BORDER_LOW(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
339  {
340  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
341  }
342  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1);
343  }
344 
345  template <typename VoxelType>
347  {
348  if( BORDER_LOW(this->mYPosInVolume) )
349  {
350  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength);
351  }
352  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume);
353  }
354 
355  template <typename VoxelType>
357  {
358  if( BORDER_LOW(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
359  {
360  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
361  }
362  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1);
363  }
364 
365  template <typename VoxelType>
367  {
368  if( BORDER_LOW(this->mZPosInVolume) )
369  {
370  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
371  }
372  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1);
373  }
374 
375  template <typename VoxelType>
377  {
378  return *mCurrentVoxel;
379  }
380 
381  template <typename VoxelType>
383  {
384  if( BORDER_HIGH(this->mZPosInVolume) )
385  {
386  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
387  }
388  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1);
389  }
390 
391  template <typename VoxelType>
393  {
394  if( BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
395  {
396  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
397  }
398  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1);
399  }
400 
401  template <typename VoxelType>
403  {
404  if( BORDER_HIGH(this->mYPosInVolume) )
405  {
406  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength);
407  }
408  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume);
409  }
410 
411  template <typename VoxelType>
413  {
414  if( BORDER_HIGH(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
415  {
416  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
417  }
418  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1);
419  }
420 
422 
423  template <typename VoxelType>
425  {
426  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
427  {
428  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
429  }
430  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1);
431  }
432 
433  template <typename VoxelType>
435  {
436  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) )
437  {
438  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength);
439  }
440  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume);
441  }
442 
443  template <typename VoxelType>
445  {
446  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
447  {
448  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
449  }
450  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1);
451  }
452 
453  template <typename VoxelType>
455  {
456  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
457  {
458  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
459  }
460  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1);
461  }
462 
463  template <typename VoxelType>
465  {
466  if( BORDER_HIGH(this->mXPosInVolume) )
467  {
468  return *(mCurrentVoxel + 1);
469  }
470  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume);
471  }
472 
473  template <typename VoxelType>
475  {
476  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
477  {
478  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
479  }
480  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1);
481  }
482 
483  template <typename VoxelType>
485  {
486  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
487  {
488  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
489  }
490  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1);
491  }
492 
493  template <typename VoxelType>
495  {
496  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) )
497  {
498  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength);
499  }
500  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume);
501  }
502 
503  template <typename VoxelType>
505  {
506  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
507  {
508  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
509  }
510  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1);
511  }
512 }
513 
514 #undef BORDER_LOW
515 #undef BORDER_HIGH