From c887d1444ffb40e7ac46e1b9f0a5a3d5acade3a1 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 5 Apr 2015 10:14:25 +0200 Subject: [PATCH] Added utility function for people who already have data in linear order, to convert it to Morton order. --- include/PolyVox/PagedVolume.h | 2 ++ include/PolyVox/PagedVolumeChunk.inl | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/PolyVox/PagedVolume.h b/include/PolyVox/PagedVolume.h index ad33dcb2..35443154 100644 --- a/include/PolyVox/PagedVolume.h +++ b/include/PolyVox/PagedVolume.h @@ -133,6 +133,8 @@ namespace PolyVox void setVoxel(uint32_t uXPos, uint32_t uYPos, uint32_t uZPos, VoxelType tValue); void setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue); + void changeLinearOrderingToMorton(void); + private: /// Private copy constructor to prevent accisdental copying Chunk(const Chunk& /*rhs*/) {}; diff --git a/include/PolyVox/PagedVolumeChunk.inl b/include/PolyVox/PagedVolumeChunk.inl index 32f33662..d06a21cc 100644 --- a/include/PolyVox/PagedVolumeChunk.inl +++ b/include/PolyVox/PagedVolumeChunk.inl @@ -152,4 +152,30 @@ namespace PolyVox uint32_t uSizeInBytes = uSideLength * uSideLength * uSideLength * sizeof(VoxelType); return uSizeInBytes; } + + // This convienience function exists for historical reasons. Chunks used to store their data in 'linear' order but now we + // use Morton encoding. Users who still have data in linear order (on disk, in databases, etc) will need to call this function + // if they load the data in by memcpy()ing it via the raw pointer. On the other hand, if they set the data using setVoxel() + // then the ordering is automatically handled correctly. + template + void PagedVolume::Chunk::changeLinearOrderingToMorton(void) + { + VoxelType* pTempBuffer = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; + for (uint16_t z = 0; z < m_uSideLength; z++) + { + for (uint16_t y = 0; y < m_uSideLength; y++) + { + for (uint16_t x = 0; x < m_uSideLength; x++) + { + uint32_t uLinearIndex = x + y * m_uSideLength + z * m_uSideLength * m_uSideLength; + uint32_t uMortonIndex = morton256_x[x] | morton256_y[y] | morton256_z[z]; + pTempBuffer[uMortonIndex] = m_tData[uLinearIndex]; + } + } + } + + std::memcpy(m_tData, pTempBuffer, getDataSizeInBytes()); + + delete[] pTempBuffer; + } }