diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 5534878f..a4e937a8 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -63,11 +63,13 @@ SET(IMPL_INC_FILES #Projects source files SET(UTIL_SRC_FILES + source/PolyVoxUtil/Serialization.cpp source/PolyVoxUtil/VolumeChangeTracker.cpp ) #Projects headers files SET(UTIL_INC_FILES + include/PolyVoxUtil/Serialization.h include/PolyVoxUtil/VolumeChangeTracker.h ) diff --git a/library/include/PolyVoxUtil/Serialization.h b/library/include/PolyVoxUtil/Serialization.h new file mode 100644 index 00000000..e7899cef --- /dev/null +++ b/library/include/PolyVoxUtil/Serialization.h @@ -0,0 +1,38 @@ +#pragma region License +/****************************************************************************** +This file is part of the PolyVox library +Copyright (C) 2006 David Williams + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +******************************************************************************/ +#pragma endregion + +#ifndef __PolyVox_Serialization_H__ +#define __PolyVox_Serialization_H__ + +#include "PolyVoxCore/Constants.h" +#include "PolyVoxCore/PolyVoxForwardDeclarations.h" +#include "PolyVoxCore/Region.h" +#include "PolyVoxCore/TypeDef.h" + +#include + +namespace PolyVox +{ + POLYVOX_API BlockVolume* loadVolumeRaw(std::istream& stream); + POLYVOX_API void saveVolumeRaw(std::ostream& stream, BlockVolume& volume); +} + +#endif diff --git a/library/source/PolyVoxUtil/Serialization.cpp b/library/source/PolyVoxUtil/Serialization.cpp new file mode 100644 index 00000000..34b2a9e6 --- /dev/null +++ b/library/source/PolyVoxUtil/Serialization.cpp @@ -0,0 +1,80 @@ +#include "PolyVoxUtil/Serialization.h" + +#include "PolyVoxCore/BlockVolume.h" +#include "PolyVoxCore/BlockVolumeIterator.h" +#include "PolyVoxCore/Utility.h" + +using namespace std; + +namespace PolyVox +{ + //Note: we don't do much error handling in here - exceptions will simply be propergated up to the caller. + //FIXME - think about pointer ownership issues. Or could return volume by value if the copy constructor is shallow + BlockVolume* loadVolumeRaw(istream& stream) + { + //Read volume dimensions + uint8 volumeWidthPower = 0; + uint8 volumeHeightPower = 0; + uint8 volumeDepthPower = 0; + stream.read(reinterpret_cast(&volumeWidthPower), sizeof(volumeWidthPower)); + stream.read(reinterpret_cast(&volumeHeightPower), sizeof(volumeHeightPower)); + stream.read(reinterpret_cast(&volumeDepthPower), sizeof(volumeDepthPower)); + + //FIXME - need to support non cubic volumes + BlockVolume* volume = new BlockVolume(volumeWidthPower); + + uint16 volumeWidth = 0x0001 << volumeWidthPower; + uint16 volumeHeight = 0x0001 << volumeHeightPower; + uint16 volumeDepth = 0x0001 << volumeDepthPower; + + //Read data + BlockVolumeIterator volIter(*volume); + for(uint16 z = 0; z < volumeDepth; ++z) + { + for(uint16 y = 0; y < volumeHeight; ++y) + { + for(uint16 x = 0; x < volumeWidth; ++x) + { + uint8 value = 0; + stream.read(reinterpret_cast(&value), sizeof(value)); + + volIter.setPosition(x,y,z); + volIter.setVoxel(value); + } + } + } + + return volume; + } + + void saveVolumeRaw(std::ostream& stream, BlockVolume& volume) + { + //Write volume dimensions + uint16 volumeWidth = volume.getSideLength(); + uint16 volumeHeight = volume.getSideLength(); + uint16 volumeDepth = volume.getSideLength(); + + uint8 volumeWidthPower = logBase2(volumeWidth); + uint8 volumeHeightPower = logBase2(volumeHeight); + uint8 volumeDepthPower = logBase2(volumeDepth); + + stream.write(reinterpret_cast(&volumeWidthPower), sizeof(volumeWidthPower)); + stream.write(reinterpret_cast(&volumeHeightPower), sizeof(volumeHeightPower)); + stream.write(reinterpret_cast(&volumeDepthPower), sizeof(volumeDepthPower)); + + //Write data + BlockVolumeIterator volIter(volume); + for(uint16 z = 0; z < volumeDepth; ++z) + { + for(uint16 y = 0; y < volumeHeight; ++y) + { + for(uint16 x = 0; x < volumeWidth; ++x) + { + volIter.setPosition(x,y,z); + uint8 value = volIter.getVoxel(); + stream.write(reinterpret_cast(&value), sizeof(value)); + } + } + } + } +} \ No newline at end of file