Implemented morton encoding using standard bit-twidling approach.
This commit is contained in:
parent
1c17a7147b
commit
d99ed5e624
@ -127,10 +127,10 @@ namespace PolyVox
|
|||||||
VoxelType* getData(void) const;
|
VoxelType* getData(void) const;
|
||||||
uint32_t getDataSizeInBytes(void) const;
|
uint32_t getDataSizeInBytes(void) const;
|
||||||
|
|
||||||
VoxelType getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const;
|
VoxelType getVoxel(uint32_t uXPos, uint32_t uYPos, uint32_t uZPos) const;
|
||||||
VoxelType getVoxel(const Vector3DUint16& v3dPos) const;
|
VoxelType getVoxel(const Vector3DUint16& v3dPos) const;
|
||||||
|
|
||||||
void setVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue);
|
void setVoxel(uint32_t uXPos, uint32_t uYPos, uint32_t uZPos, VoxelType tValue);
|
||||||
void setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue);
|
void setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -91,8 +91,19 @@ namespace PolyVox
|
|||||||
return m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
return m_uSideLength * m_uSideLength * m_uSideLength * sizeof(VoxelType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Based on https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
|
||||||
|
inline uint32_t Part1By2(uint32_t x)
|
||||||
|
{
|
||||||
|
x &= 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210
|
||||||
|
x = (x ^ (x << 16)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210
|
||||||
|
x = (x ^ (x << 8)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210
|
||||||
|
x = (x ^ (x << 4)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10
|
||||||
|
x = (x ^ (x << 2)) & 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
VoxelType PagedVolume<VoxelType>::Chunk::getVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) const
|
VoxelType PagedVolume<VoxelType>::Chunk::getVoxel(uint32_t uXPos, uint32_t uYPos, uint32_t uZPos) const
|
||||||
{
|
{
|
||||||
// This code is not usually expected to be called by the user, with the exception of when implementing paging
|
// This code is not usually expected to be called by the user, with the exception of when implementing paging
|
||||||
// of uncompressed data. It's a performance critical code path so we use asserts rather than exceptions.
|
// of uncompressed data. It's a performance critical code path so we use asserts rather than exceptions.
|
||||||
@ -101,12 +112,10 @@ namespace PolyVox
|
|||||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the chunk");
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the chunk");
|
||||||
POLYVOX_ASSERT(m_tData, "No uncompressed data - chunk must be decompressed before accessing voxels.");
|
POLYVOX_ASSERT(m_tData, "No uncompressed data - chunk must be decompressed before accessing voxels.");
|
||||||
|
|
||||||
return m_tData
|
uint32_t index = 0;
|
||||||
[
|
index |= Part1By2(uXPos) | Part1By2(uYPos) << 1 | Part1By2(uZPos) << 2;
|
||||||
uXPos +
|
|
||||||
uYPos * m_uSideLength +
|
return m_tData[index];
|
||||||
uZPos * m_uSideLength * m_uSideLength
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
@ -116,7 +125,7 @@ namespace PolyVox
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename VoxelType>
|
template <typename VoxelType>
|
||||||
void PagedVolume<VoxelType>::Chunk::setVoxel(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos, VoxelType tValue)
|
void PagedVolume<VoxelType>::Chunk::setVoxel(uint32_t uXPos, uint32_t uYPos, uint32_t uZPos, VoxelType tValue)
|
||||||
{
|
{
|
||||||
// This code is not usually expected to be called by the user, with the exception of when implementing paging
|
// This code is not usually expected to be called by the user, with the exception of when implementing paging
|
||||||
// of uncompressed data. It's a performance critical code path so we use asserts rather than exceptions.
|
// of uncompressed data. It's a performance critical code path so we use asserts rather than exceptions.
|
||||||
@ -125,12 +134,10 @@ namespace PolyVox
|
|||||||
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the chunk");
|
POLYVOX_ASSERT(uZPos < m_uSideLength, "Supplied position is outside of the chunk");
|
||||||
POLYVOX_ASSERT(m_tData, "No uncompressed data - chunk must be decompressed before accessing voxels.");
|
POLYVOX_ASSERT(m_tData, "No uncompressed data - chunk must be decompressed before accessing voxels.");
|
||||||
|
|
||||||
m_tData
|
uint32_t index = 0;
|
||||||
[
|
index |= Part1By2(uXPos) | Part1By2(uYPos) << 1 | Part1By2(uZPos) << 2;
|
||||||
uXPos +
|
|
||||||
uYPos * m_uSideLength +
|
m_tData[index] = tValue;
|
||||||
uZPos * m_uSideLength * m_uSideLength
|
|
||||||
] = tValue;
|
|
||||||
|
|
||||||
this->m_bDataModified = true;
|
this->m_bDataModified = true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user