PolyVox  0.2.1
Open source voxel management library
SimpleVolumeSampler.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 % this->mVolume->m_uBlockSideLength) != 0)
27 //#define BORDER_HIGH(x) (( x % this->mVolume->m_uBlockSideLength) != this->mVolume->m_uBlockSideLength - 1)
28 
29 namespace PolyVox
30 {
34  template <typename VoxelType>
36  :BaseVolume<VoxelType>::template Sampler< SimpleVolume<VoxelType> >(volume)
37  {
38  }
39 
40  template <typename VoxelType>
42  {
43  }
44 
45  template <typename VoxelType>
47  {
48  if(this == &rhs)
49  {
50  return *this;
51  }
52  this->mVolume = rhs.mVolume;
53  this->mXPosInVolume = rhs.mXPosInVolume;
54  this->mYPosInVolume = rhs.mYPosInVolume;
55  this->mZPosInVolume = rhs.mZPosInVolume;
56  mCurrentVoxel = rhs.mCurrentVoxel;
57  return *this;
58  }
59 
60  template <typename VoxelType>
62  {
63  if(uLevel == 0)
64  {
65  return getVoxel();
66  }
67  else if(uLevel == 1)
68  {
69  VoxelType tValue = getVoxel();
70  tValue = (std::min)(tValue, peekVoxel1px0py0pz());
71  tValue = (std::min)(tValue, peekVoxel0px1py0pz());
72  tValue = (std::min)(tValue, peekVoxel1px1py0pz());
73  tValue = (std::min)(tValue, peekVoxel0px0py1pz());
74  tValue = (std::min)(tValue, peekVoxel1px0py1pz());
75  tValue = (std::min)(tValue, peekVoxel0px1py1pz());
76  tValue = (std::min)(tValue, peekVoxel1px1py1pz());
77  return tValue;
78  }
79  else
80  {
81  const uint8_t uSize = 1 << uLevel;
82 
83  VoxelType tValue = (std::numeric_limits<VoxelType>::max)();
84  for(uint8_t z = 0; z < uSize; ++z)
85  {
86  for(uint8_t y = 0; y < uSize; ++y)
87  {
88  for(uint8_t x = 0; x < uSize; ++x)
89  {
90  tValue = (std::min)(tValue, this->mVolume->getVoxelAt(this->mXPosInVolume + x, this->mYPosInVolume + y, this->mZPosInVolume + z));
91  }
92  }
93  }
94  return tValue;
95  }
96  }
97 
101  template <typename VoxelType>
103  {
104  return *mCurrentVoxel;
105  }
106 
110  template <typename VoxelType>
112  {
113  setPosition(v3dNewPos.getX(), v3dNewPos.getY(), v3dNewPos.getZ());
114  }
115 
121  template <typename VoxelType>
123  {
124  this->mXPosInVolume = xPos;
125  this->mYPosInVolume = yPos;
126  this->mZPosInVolume = zPos;
127 
128  const int32_t uXBlock = this->mXPosInVolume >> this->mVolume->m_uBlockSideLengthPower;
129  const int32_t uYBlock = this->mYPosInVolume >> this->mVolume->m_uBlockSideLengthPower;
130  const int32_t uZBlock = this->mZPosInVolume >> this->mVolume->m_uBlockSideLengthPower;
131 
132  const uint16_t uXPosInBlock = static_cast<uint16_t>(this->mXPosInVolume - (uXBlock << this->mVolume->m_uBlockSideLengthPower));
133  const uint16_t uYPosInBlock = static_cast<uint16_t>(this->mYPosInVolume - (uYBlock << this->mVolume->m_uBlockSideLengthPower));
134  const uint16_t uZPosInBlock = static_cast<uint16_t>(this->mZPosInVolume - (uZBlock << this->mVolume->m_uBlockSideLengthPower));
135 
136  const uint32_t uVoxelIndexInBlock = uXPosInBlock +
137  uYPosInBlock * this->mVolume->m_uBlockSideLength +
138  uZPosInBlock * this->mVolume->m_uBlockSideLength * this->mVolume->m_uBlockSideLength;
139 
140  if(this->mVolume->m_regValidRegionInBlocks.containsPoint(Vector3DInt32(uXBlock, uYBlock, uZBlock)))
141  {
142  Block* pUncompressedCurrentBlock = this->mVolume->getUncompressedBlock(uXBlock, uYBlock, uZBlock);
143 
144  mCurrentVoxel = pUncompressedCurrentBlock->m_tUncompressedData + uVoxelIndexInBlock;
145  }
146  else
147  {
148  mCurrentVoxel = this->mVolume->m_pUncompressedBorderData + uVoxelIndexInBlock;
149  }
150  }
151 
161  template <typename VoxelType>
163  {
164  VoxelType* pBorderDataEndPlusOne = this->mVolume->m_pUncompressedBorderData + this->mVolume->m_uNoOfVoxelsPerBlock;
165 
166  //Make sure we're not trying to write to the border data
167  if((mCurrentVoxel < this->mVolume->m_pUncompressedBorderData) || (mCurrentVoxel >= pBorderDataEndPlusOne))
168  {
169  *mCurrentVoxel = tValue;
170  return true;
171  }
172  else
173  {
174  return false;
175  }
176  }
177 
178  template <typename VoxelType>
180  {
181  //Note the *pre* increament here
182  if((++this->mXPosInVolume) % this->mVolume->m_uBlockSideLength != 0)
183  {
184  //No need to compute new block.
185  ++mCurrentVoxel;
186  }
187  else
188  {
189  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
190  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
191  }
192  }
193 
194  template <typename VoxelType>
196  {
197  //Note the *pre* increament here
198  if((++this->mYPosInVolume) % this->mVolume->m_uBlockSideLength != 0)
199  {
200  //No need to compute new block.
201  mCurrentVoxel += this->mVolume->m_uBlockSideLength;
202  }
203  else
204  {
205  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
206  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
207  }
208  }
209 
210  template <typename VoxelType>
212  {
213  //Note the *pre* increament here
214  if((++this->mZPosInVolume) % this->mVolume->m_uBlockSideLength != 0)
215  {
216  //No need to compute new block.
217  mCurrentVoxel += this->mVolume->m_uBlockSideLength * this->mVolume->m_uBlockSideLength;
218  }
219  else
220  {
221  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
222  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
223  }
224  }
225 
226  template <typename VoxelType>
228  {
229  //Note the *post* decreament here
230  if((this->mXPosInVolume--) % this->mVolume->m_uBlockSideLength != 0)
231  {
232  //No need to compute new block.
233  --mCurrentVoxel;
234  }
235  else
236  {
237  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
238  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
239  }
240  }
241 
242  template <typename VoxelType>
244  {
245  //Note the *post* decreament here
246  if((this->mYPosInVolume--) % this->mVolume->m_uBlockSideLength != 0)
247  {
248  //No need to compute new block.
249  mCurrentVoxel -= this->mVolume->m_uBlockSideLength;
250  }
251  else
252  {
253  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
254  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
255  }
256  }
257 
258  template <typename VoxelType>
260  {
261  //Note the *post* decreament here
262  if((this->mZPosInVolume--) % this->mVolume->m_uBlockSideLength != 0)
263  {
264  //No need to compute new block.
265  mCurrentVoxel -= this->mVolume->m_uBlockSideLength * this->mVolume->m_uBlockSideLength;
266  }
267  else
268  {
269  //We've hit the block boundary. Just calling setPosition() is the easiest way to resolve this.
270  setPosition(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume);
271  }
272  }
273 
274  template <typename VoxelType>
276  {
277  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
278  {
279  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
280  }
281  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1);
282  }
283 
284  template <typename VoxelType>
286  {
287  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) )
288  {
289  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength);
290  }
291  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume);
292  }
293 
294  template <typename VoxelType>
296  {
297  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
298  {
299  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
300  }
301  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1);
302  }
303 
304  template <typename VoxelType>
306  {
307  if( BORDER_LOW(this->mXPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
308  {
309  return *(mCurrentVoxel - 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
310  }
311  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1);
312  }
313 
314  template <typename VoxelType>
316  {
317  if( BORDER_LOW(this->mXPosInVolume) )
318  {
319  return *(mCurrentVoxel - 1);
320  }
321  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume);
322  }
323 
324  template <typename VoxelType>
326  {
327  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
328  {
329  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
330  }
331  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1);
332  }
333 
334  template <typename VoxelType>
336  {
337  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
338  {
339  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
340  }
341  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1);
342  }
343 
344  template <typename VoxelType>
346  {
347  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) )
348  {
349  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength);
350  }
351  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume);
352  }
353 
354  template <typename VoxelType>
356  {
357  if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
358  {
359  return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
360  }
361  return this->mVolume->getVoxelAt(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1);
362  }
363 
365 
366  template <typename VoxelType>
368  {
369  if( BORDER_LOW(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
370  {
371  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
372  }
373  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1);
374  }
375 
376  template <typename VoxelType>
378  {
379  if( BORDER_LOW(this->mYPosInVolume) )
380  {
381  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength);
382  }
383  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume);
384  }
385 
386  template <typename VoxelType>
388  {
389  if( BORDER_LOW(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
390  {
391  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
392  }
393  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1);
394  }
395 
396  template <typename VoxelType>
398  {
399  if( BORDER_LOW(this->mZPosInVolume) )
400  {
401  return *(mCurrentVoxel - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
402  }
403  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1);
404  }
405 
406  template <typename VoxelType>
408  {
409  return *mCurrentVoxel;
410  }
411 
412  template <typename VoxelType>
414  {
415  if( BORDER_HIGH(this->mZPosInVolume) )
416  {
417  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
418  }
419  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1);
420  }
421 
422  template <typename VoxelType>
424  {
425  if( BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
426  {
427  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
428  }
429  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1);
430  }
431 
432  template <typename VoxelType>
434  {
435  if( BORDER_HIGH(this->mYPosInVolume) )
436  {
437  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength);
438  }
439  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume);
440  }
441 
442  template <typename VoxelType>
444  {
445  if( BORDER_HIGH(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
446  {
447  return *(mCurrentVoxel + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
448  }
449  return this->mVolume->getVoxelAt(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1);
450  }
451 
453 
454  template <typename VoxelType>
456  {
457  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
458  {
459  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
460  }
461  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1);
462  }
463 
464  template <typename VoxelType>
466  {
467  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) )
468  {
469  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength);
470  }
471  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume);
472  }
473 
474  template <typename VoxelType>
476  {
477  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
478  {
479  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
480  }
481  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1);
482  }
483 
484  template <typename VoxelType>
486  {
487  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
488  {
489  return *(mCurrentVoxel + 1 - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
490  }
491  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1);
492  }
493 
494  template <typename VoxelType>
496  {
497  if( BORDER_HIGH(this->mXPosInVolume) )
498  {
499  return *(mCurrentVoxel + 1);
500  }
501  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume);
502  }
503 
504  template <typename VoxelType>
506  {
507  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
508  {
509  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
510  }
511  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1);
512  }
513 
514  template <typename VoxelType>
516  {
517  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) )
518  {
519  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
520  }
521  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1);
522  }
523 
524  template <typename VoxelType>
526  {
527  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) )
528  {
529  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength);
530  }
531  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume);
532  }
533 
534  template <typename VoxelType>
536  {
537  if( BORDER_HIGH(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_HIGH(this->mZPosInVolume) )
538  {
539  return *(mCurrentVoxel + 1 + this->mVolume->m_uBlockSideLength + this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength);
540  }
541  return this->mVolume->getVoxelAt(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1);
542  }
543 }
544 
545 #undef BORDER_LOW
546 #undef BORDER_HIGH