Merge branch 'master' of git@gitorious.org:polyvox/polyvox.git
This commit is contained in:
		| @@ -28,6 +28,7 @@ freely, subject to the following restrictions: | ||||
| #include "PolyVoxImpl/TypeDef.h" | ||||
|  | ||||
| #include "PolyVoxCore/Array.h" | ||||
| #include "PolyVoxCore/Voxel.h" | ||||
|  | ||||
| #include <list> | ||||
| #include <stdexcept> //For runtime_error | ||||
| @@ -43,7 +44,7 @@ namespace PolyVox | ||||
| 	extern const POLYVOX_API Vector3DInt32 arrayPathfinderCorners[8]; | ||||
|  | ||||
| 	/// This function provides the default method for checking whether a given voxel | ||||
| 	/// is vaid for the path computed by the AStarPathfinder. | ||||
| 	/// is valid for the path computed by the AStarPathfinder. | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	bool aStarDefaultVoxelValidator(const VolumeType<VoxelType>* volData, const Vector3DInt32& v3dPos); | ||||
|  | ||||
| @@ -71,7 +72,7 @@ namespace PolyVox | ||||
| 			float fHBias = 1.0, | ||||
| 			uint32_t uMaxNoOfNodes = 10000, | ||||
| 			Connectivity connectivity = TwentySixConnected, | ||||
| 			polyvox_function<bool (const VolumeType<VoxelType>*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator<VolumeType, VoxelType>, | ||||
| 			polyvox_function<bool (const VolumeType<VoxelType>*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator, | ||||
| 			polyvox_function<void (float)> funcProgressCallback = 0 | ||||
| 		) | ||||
| 			:volume(volData) | ||||
|   | ||||
| @@ -37,13 +37,6 @@ namespace PolyVox | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		//and if their density is below the threshold. | ||||
| 		VoxelType voxel = volData->getVoxelAt(v3dPos); | ||||
| 		if(voxel.getDensity() >= VoxelType::getThreshold()) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| @@ -333,4 +326,4 @@ namespace PolyVox | ||||
| 		hVal += fHash; | ||||
| 		return hVal; | ||||
| 	} | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -31,6 +31,12 @@ freely, subject to the following restrictions: | ||||
| #include "PolyVoxCore/Region.h" | ||||
| #include "PolyVoxCore/Raycast.h" | ||||
|  | ||||
| #if defined(_MSC_VER) | ||||
| 	//These two should not be here! | ||||
| 	#include "PolyVoxCore/Material.h" | ||||
| 	#include "PolyVoxCore/SimpleVolume.h" | ||||
| #endif | ||||
|  | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace PolyVox | ||||
| @@ -39,12 +45,19 @@ namespace PolyVox | ||||
| 	class AmbientOcclusionCalculator | ||||
| 	{ | ||||
| 	public: | ||||
| 		AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement); | ||||
| 		AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, polyvox_function<bool(const VoxelType& voxel)> funcIsTransparent); | ||||
| 		~AmbientOcclusionCalculator(); | ||||
|  | ||||
| 		void execute(void); | ||||
|  | ||||
| 	private: | ||||
|  | ||||
| #if defined(_MSC_VER) //FIXME: To be investigated. Linux version is more general and should be correct. | ||||
| 		bool raycastCallback(const typename SimpleVolume<VoxelType>::Sampler& sampler);		 | ||||
| #else | ||||
| 		bool raycastCallback(const typename VolumeType<VoxelType>::Sampler& sampler); | ||||
| #endif | ||||
|  | ||||
| 		Region m_region; | ||||
| 		typename VolumeType<VoxelType>::Sampler m_sampVolume; | ||||
| 		VolumeType<VoxelType>* m_volInput; | ||||
| @@ -56,6 +69,8 @@ namespace PolyVox | ||||
| 		uint16_t mRandomUnitVectorIndex; | ||||
| 		uint16_t mRandomVectorIndex; | ||||
| 		uint16_t mIndexIncreament; | ||||
|  | ||||
| 		polyvox_function<bool(const VoxelType& voxel)> m_funcIsTransparent; | ||||
| 	}; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,7 @@ freely, subject to the following restrictions: | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	AmbientOcclusionCalculator<VolumeType, VoxelType>::AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement) | ||||
| 	AmbientOcclusionCalculator<VolumeType, VoxelType>::AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, polyvox_function<bool(const VoxelType& voxel)> funcIsTransparent) | ||||
| 		:m_region(region) | ||||
| 		,m_sampVolume(volInput) | ||||
| 		,m_volInput(volInput) | ||||
| @@ -33,6 +33,7 @@ namespace PolyVox | ||||
| 		,m_uNoOfSamplesPerOutputElement(uNoOfSamplesPerOutputElement) | ||||
| 		,mRandomUnitVectorIndex(0) //Although these could be uninitialised, we  | ||||
| 		,mRandomVectorIndex(0) //initialise for consistant results in the tests. | ||||
| 		,m_funcIsTransparent(funcIsTransparent) | ||||
| 	{ | ||||
| 		//Make sure that the size of the volume is an exact multiple of the size of the array. | ||||
| 		assert(m_volInput->getWidth() % arrayResult->getDimension(0) == 0); | ||||
| @@ -74,7 +75,7 @@ namespace PolyVox | ||||
| 		const Vector3DFloat v3dOffset(0.5f,0.5f,0.5f); | ||||
|  | ||||
| 		RaycastResult raycastResult; | ||||
| 		Raycast<VolumeType, VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult); | ||||
| 		Raycast<VolumeType, VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult, polyvox_bind(&PolyVox::AmbientOcclusionCalculator<VolumeType,VoxelType>::raycastCallback, this, std::placeholders::_1)); | ||||
|  | ||||
| 		//This loop iterates over the bottom-lower-left voxel in each of the cells in the output array | ||||
| 		for(uint16_t z = m_region.getLowerCorner().getZ(); z <= m_region.getUpperCorner().getZ(); z += iRatioZ) | ||||
| @@ -131,4 +132,15 @@ namespace PolyVox | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| #if defined(_MSC_VER) | ||||
| 	bool AmbientOcclusionCalculator<VolumeType, VoxelType>::raycastCallback(const typename SimpleVolume<VoxelType>::Sampler& sampler) | ||||
| #else | ||||
| 	bool AmbientOcclusionCalculator<VolumeType, VoxelType>::raycastCallback(const typename VolumeType<VoxelType>::Sampler& sampler) | ||||
| #endif	 | ||||
| 	{ | ||||
| 		VoxelType voxel = sampler.getVoxel(); | ||||
| 		return m_funcIsTransparent(voxel); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -74,4 +74,4 @@ namespace PolyVox | ||||
| 	}; | ||||
| }//namespace PolyVox | ||||
|  | ||||
| #endif //__PolyVox_ArraySizes_H__ | ||||
| #endif //__PolyVox_ArraySizes_H__ | ||||
|   | ||||
| @@ -50,9 +50,7 @@ namespace PolyVox | ||||
| 			Sampler(DerivedVolumeType* volume); | ||||
| 			~Sampler(); | ||||
|  | ||||
| 			int32_t getPosX(void) const; | ||||
| 			int32_t getPosY(void) const; | ||||
| 			int32_t getPosZ(void) const; | ||||
| 			Vector3DInt32 getPosition(void) const; | ||||
| 			inline VoxelType getVoxel(void) const;	 | ||||
|  | ||||
| 			void setPosition(const Vector3DInt32& v3dNewPos); | ||||
|   | ||||
| @@ -41,23 +41,9 @@ namespace PolyVox | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	template <typename DerivedVolumeType> | ||||
| 	int32_t BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosX(void) const | ||||
| 	Vector3DInt32 BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosition(void) const | ||||
| 	{ | ||||
| 		return mXPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	template <typename DerivedVolumeType> | ||||
| 	int32_t BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosY(void) const | ||||
| 	{ | ||||
| 		return mYPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	template <typename DerivedVolumeType> | ||||
| 	int32_t BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::getPosZ(void) const | ||||
| 	{ | ||||
| 		return mZPosInVolume; | ||||
| 		return Vector3DInt32(mXPosInVolume, mYPosInVolume, mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
|   | ||||
| @@ -76,4 +76,4 @@ namespace PolyVox | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| #endif //__PolyVox_ConstVolumeProxy_H__ | ||||
| #endif //__PolyVox_ConstVolumeProxy_H__ | ||||
|   | ||||
| @@ -91,10 +91,10 @@ namespace PolyVox | ||||
| 					volumeSampler.setPosition(x,y,z); | ||||
|  | ||||
| 					VoxelType currentVoxel = volumeSampler.getVoxel(); | ||||
| 					bool currentVoxelIsSolid = currentVoxel.getDensity() >= VoxelType::getThreshold(); | ||||
| 					bool currentVoxelIsSolid = currentVoxel.getMaterial() != 0; | ||||
|  | ||||
| 					VoxelType negXVoxel = volumeSampler.peekVoxel1nx0py0pz(); | ||||
| 					bool negXVoxelIsSolid = negXVoxel.getDensity()  >= VoxelType::getThreshold(); | ||||
| 					bool negXVoxelIsSolid = negXVoxel.getMaterial() != 0; | ||||
|  | ||||
| 					if((currentVoxelIsSolid != negXVoxelIsSolid) && (finalY == false) && (finalZ == false)) | ||||
| 					{ | ||||
| @@ -131,7 +131,7 @@ namespace PolyVox | ||||
| 					} | ||||
|  | ||||
| 					VoxelType negYVoxel = volumeSampler.peekVoxel0px1ny0pz(); | ||||
| 					bool negYVoxelIsSolid = negYVoxel.getDensity()  >= VoxelType::getThreshold(); | ||||
| 					bool negYVoxelIsSolid = negYVoxel.getMaterial() != 0; | ||||
|  | ||||
| 					if((currentVoxelIsSolid != negYVoxelIsSolid) && (finalX == false) && (finalZ == false)) | ||||
| 					{ | ||||
| @@ -168,7 +168,7 @@ namespace PolyVox | ||||
| 					} | ||||
|  | ||||
| 					VoxelType negZVoxel = volumeSampler.peekVoxel0px0py1nz(); | ||||
| 					bool negZVoxelIsSolid = negZVoxel.getDensity()  >= VoxelType::getThreshold(); | ||||
| 					bool negZVoxelIsSolid = negZVoxel.getMaterial() != 0; | ||||
|  | ||||
| 					if((currentVoxelIsSolid != negZVoxelIsSolid) && (finalX == false) && (finalY == false)) | ||||
| 					{ | ||||
| @@ -344,4 +344,4 @@ namespace PolyVox | ||||
| 		//Quads cannot be merged. | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -48,9 +48,9 @@ namespace PolyVox | ||||
| 					float regY = static_cast<float>(y - m_regSizeInVoxels.getLowerCorner().getY()); | ||||
| 					float regZ = static_cast<float>(z - m_regSizeInVoxels.getLowerCorner().getZ()); | ||||
|  | ||||
| 					int currentVoxel = m_volData->getVoxelAt(x,y,z).getDensity() >= VoxelType::getThreshold(); | ||||
| 					int currentVoxel = m_volData->getVoxelAt(x,y,z).getMaterial() != 0; | ||||
|  | ||||
| 					int plusXVoxel = m_volData->getVoxelAt(x+1,y,z).getDensity()  >= VoxelType::getThreshold(); | ||||
| 					int plusXVoxel = m_volData->getVoxelAt(x+1,y,z).getMaterial() != 0; | ||||
| 					if(currentVoxel > plusXVoxel) | ||||
| 					{ | ||||
| 						float material = static_cast<float>(m_volData->getVoxelAt(x,y,z).getMaterial()); | ||||
| @@ -76,7 +76,7 @@ namespace PolyVox | ||||
| 						m_meshCurrent->addTriangleCubic(v1,v3,v2); | ||||
| 					} | ||||
|  | ||||
| 					int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getDensity()  >= VoxelType::getThreshold(); | ||||
| 					int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getMaterial() != 0; | ||||
| 					if(currentVoxel > plusYVoxel) | ||||
| 					{ | ||||
| 						float material = static_cast<float>(m_volData->getVoxelAt(x,y,z).getMaterial()); | ||||
| @@ -102,7 +102,7 @@ namespace PolyVox | ||||
| 						m_meshCurrent->addTriangleCubic(v1,v2,v3); | ||||
| 					} | ||||
|  | ||||
| 					int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getDensity()  >= VoxelType::getThreshold(); | ||||
| 					int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getMaterial() != 0; | ||||
| 					if(currentVoxel > plusZVoxel) | ||||
| 					{ | ||||
| 						float material = static_cast<float>(m_volData->getVoxelAt(x,y,z).getMaterial()); | ||||
| @@ -139,4 +139,4 @@ namespace PolyVox | ||||
| 		lodRecord.endIndex = m_meshCurrent->getNoOfIndices(); | ||||
| 		m_meshCurrent->m_vecLodRecords.push_back(lodRecord); | ||||
| 	} | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -31,6 +31,9 @@ freely, subject to the following restrictions: | ||||
| #include <cassert> | ||||
| #include <limits> | ||||
|  | ||||
| #undef min | ||||
| #undef max | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	///This class represents a voxel storing only a density. | ||||
| @@ -45,8 +48,11 @@ namespace PolyVox | ||||
| 	/// | ||||
| 	/// \sa Material, MaterialDensityPair | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	// int32_t template parameter is a dummy, required as the compiler expects to be able to declare an | ||||
| 	// instance of VoxelType::MaterialType without knowing that VoxelType doesn't actually have a material. | ||||
| 	template <typename Type> | ||||
| 	class Density : public Voxel<Type, uint8_t> | ||||
| 	class Density | ||||
| 	{ | ||||
| 	public: | ||||
| 		//We expose DensityType and MaterialType in this way so that, when code is | ||||
| @@ -54,7 +60,7 @@ namespace PolyVox | ||||
| 		//using code such as 'VoxelType::DensityType value = voxel.getDensity()' | ||||
| 		//or 'VoxelType::MaterialType value = voxel.getMaterial()'. | ||||
| 		typedef Type DensityType; | ||||
| 		typedef uint8_t MaterialType; //Shouldn't define this one... | ||||
| 		typedef int32_t MaterialType; //Shouldn't define this one... | ||||
|  | ||||
| 		Density() : m_uDensity(0) {} | ||||
| 		Density(DensityType uDensity) : m_uDensity(uDensity) {} | ||||
| @@ -70,13 +76,13 @@ namespace PolyVox | ||||
| 		} | ||||
|  | ||||
| 		DensityType getDensity() const throw() { return m_uDensity; } | ||||
| 		MaterialType getMaterial() const throw() { return 1; } | ||||
| 		//MaterialType getMaterial() const throw() { return 1; } | ||||
|  | ||||
| 		void setDensity(DensityType uDensity) { m_uDensity = uDensity; } | ||||
| 		void setMaterial(MaterialType /*uMaterial*/) { assert(false); } //Cannot set material on voxel of type Density | ||||
| 		//void setMaterial(MaterialType /*uMaterial*/) { assert(false); } //Cannot set material on voxel of type Density | ||||
|  | ||||
| 		//static DensityType getMaxDensity() throw() { return (std::numeric_limits<DensityType>::max)(); }  | ||||
| 		//static DensityType getMinDensity() throw() { return (std::numeric_limits<DensityType>::min)(); } | ||||
| 		//static DensityType getmaxDensity()() throw() { return (std::numeric_limits<DensityType>::max)(); }  | ||||
| 		//static DensityType getminDensity()() throw() { return (std::numeric_limits<DensityType>::min)(); } | ||||
| 		static DensityType getThreshold() throw() { return (std::numeric_limits<DensityType>::max)() / 2; } | ||||
|  | ||||
| 	private: | ||||
| @@ -85,70 +91,20 @@ namespace PolyVox | ||||
|  | ||||
| 	// These are the predefined density types. The 8-bit types are sufficient for many purposes (including | ||||
| 	// most games) but 16-bit and float types do have uses particularly in medical/scientific visualisation. | ||||
| 	typedef Density<int8_t> DensityI8; | ||||
| 	typedef Density<uint8_t> DensityU8; | ||||
| 	typedef Density<int16_t> DensityI16; | ||||
| 	typedef Density<uint16_t> DensityU16; | ||||
| 	typedef Density<float> DensityFloat; | ||||
| 	typedef Density<double> DensityDouble; | ||||
|  | ||||
| 	// These types are here for backwards compatibility but they are a little ambiguous as the name doesn't indicate | ||||
| 	// whether the values are signed. We would recommend using one of the 8 or 16 bit predefined types above instead. | ||||
| 	typedef Density<uint8_t> Density8; | ||||
| 	typedef Density<uint16_t> Density16; | ||||
| 	 | ||||
| 	// We have to define all the min and max values explicitly here rather than using std::numeric_limits because we need | ||||
| 	// compile time constants. The new 'constexpr' would help here but it's not supported by all compilers at the moment. | ||||
| 	/*template<> | ||||
| 	class VoxelTypeTraits< Density<int8_t> > | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< Density8 >	 | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static int8_t MinDensity; | ||||
| 		const static int8_t MaxDensity; | ||||
| 	};*/ | ||||
|  | ||||
| 	/*template<> | ||||
| 	class VoxelTypeTraits< Density<uint8_t> > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static uint8_t MinDensity;  | ||||
| 		const static uint8_t MaxDensity; | ||||
| 	};*/ | ||||
|  | ||||
| 	/*template<> | ||||
| 	class VoxelTypeTraits< Density<int16_t> > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static int16_t MinDensity; | ||||
| 		const static int16_t MaxDensity; | ||||
| 		typedef uint8_t DensityType; | ||||
| 		typedef uint8_t MaterialType; | ||||
| 		static Density8::DensityType minDensity() { return std::numeric_limits<Density8::DensityType>::min(); } | ||||
| 		static Density8::DensityType maxDensity() { return std::numeric_limits<Density8::DensityType>::max(); } | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< Density<uint16_t> > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static uint16_t MinDensity; | ||||
| 		const static uint16_t MaxDensity; | ||||
| 	}; | ||||
| 	 | ||||
| 	//Constants for float defined in .cpp file as they are not integers. | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< Density<float> > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static float MinDensity; | ||||
| 		const static float MaxDensity; | ||||
| 	}; | ||||
|  | ||||
| 	//Constants for double defined in .cpp file as they are not integers. | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< Density<double> > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static double MinDensity; | ||||
| 		const static double MaxDensity; | ||||
| 	};*/ | ||||
|  | ||||
| 	typename VoxelTypeTraits<Density8>::DensityType convertToDensity(Density8 voxel); | ||||
| } | ||||
|  | ||||
| #endif //__PolyVox_Density_H__ | ||||
|   | ||||
| @@ -47,9 +47,9 @@ namespace PolyVox | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	Vector3DFloat computeDecimatedCentralDifferenceGradient(const typename VolumeType<VoxelType>::Sampler& volIter) | ||||
| 	{ | ||||
| 		const int32_t x = volIter.getPosX(); | ||||
| 		const int32_t y = volIter.getPosY(); | ||||
| 		const int32_t z = volIter.getPosZ(); | ||||
| 		const int32_t x = volIter.getPosition().getX(); | ||||
| 		const int32_t y = volIter.getPosition().getY(); | ||||
| 		const int32_t z = volIter.getPosition().getZ(); | ||||
|  | ||||
| 		//FIXME - bitwise way of doing this? | ||||
| 		VoxelType voxel1nx = volIter.getVoxelAt(x-2, y  ,z  ) > 0 ? 1: 0; | ||||
| @@ -72,9 +72,9 @@ namespace PolyVox | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	Vector3DFloat computeSmoothCentralDifferenceGradient(typename VolumeType<VoxelType>::Sampler& volIter) | ||||
| 	{ | ||||
| 		int32_t initialX = volIter.getPosX(); | ||||
| 		int32_t initialY = volIter.getPosY(); | ||||
| 		int32_t initialZ = volIter.getPosZ(); | ||||
| 		int32_t initialX = volIter.getPosition().getX(); | ||||
| 		int32_t initialY = volIter.getPosition().getY(); | ||||
| 		int32_t initialZ = volIter.getPosition().getZ(); | ||||
|  | ||||
| 		//FIXME - bitwise way of doing this? | ||||
| 		volIter.setPosition(initialX-1, initialY, initialZ); | ||||
| @@ -189,9 +189,9 @@ namespace PolyVox | ||||
| 		static const int weights[3][3][3] = {  {  {2,3,2}, {3,6,3}, {2,3,2}  },  { | ||||
| 			{3,6,3},  {6,0,6},  {3,6,3} },  { {2,3,2},  {3,6,3},  {2,3,2} } }; | ||||
|  | ||||
| 			int32_t initialX = volIter.getPosX(); | ||||
| 			int32_t initialY = volIter.getPosY(); | ||||
| 			int32_t initialZ = volIter.getPosZ(); | ||||
| 			int32_t initialX = volIter.getPosition().getX(); | ||||
| 			int32_t initialY = volIter.getPosition().getY(); | ||||
| 			int32_t initialZ = volIter.getPosition().getZ(); | ||||
|  | ||||
| 			volIter.setPosition(initialX-1, initialY-1, initialZ-1);	const float pVoxel1nx1ny1nz = computeSmoothedVoxel(volIter); | ||||
| 			volIter.setPosition(initialX-1, initialY-1, initialZ );		const float pVoxel1nx1ny0pz = computeSmoothedVoxel(volIter); | ||||
|   | ||||
| @@ -32,7 +32,7 @@ namespace PolyVox | ||||
| 	template <typename IteratorType> | ||||
| 	bool IteratorController<IteratorType>::moveForward(void) | ||||
| 	{ | ||||
| 		Vector3DInt32 v3dInitialPosition(m_Iter->getPosX(), m_Iter->getPosY(), m_Iter->getPosZ()); | ||||
| 		Vector3DInt32 v3dInitialPosition(m_Iter->getPosition().getX(), m_Iter->getPosition().getY(), m_Iter->getPosition().getZ()); | ||||
|  | ||||
| 		if(v3dInitialPosition.getX() < m_regValid.getUpperCorner().getX()) | ||||
| 		{ | ||||
|   | ||||
| @@ -172,9 +172,6 @@ namespace PolyVox | ||||
|  | ||||
| 			Sampler& operator=(const Sampler& rhs) throw(); | ||||
|  | ||||
| 			int32_t getPosX(void) const; | ||||
| 			int32_t getPosY(void) const; | ||||
| 			int32_t getPosZ(void) const; | ||||
| 			VoxelType getSubSampledVoxel(uint8_t uLevel) const; | ||||
| 			inline VoxelType getVoxel(void) const;			 | ||||
|  | ||||
| @@ -299,10 +296,9 @@ namespace PolyVox | ||||
| 		/// Calculates approximatly how many bytes of memory the volume is currently using. | ||||
| 		uint32_t calculateSizeInBytes(void); | ||||
|  | ||||
| 		/// Deprecated - I don't think we should expose this function? Let us know if you disagree... | ||||
| 		void resize(const Region& regValidRegion, uint16_t uBlockSideLength); | ||||
|  | ||||
| private: | ||||
| 		void initialise(const Region& regValidRegion, uint16_t uBlockSideLength); | ||||
|  | ||||
| 		/// gets called when a new region is allocated and needs to be filled | ||||
| 		/// NOTE: accessing ANY voxels outside this region during the process of this function | ||||
| 		/// is absolutely unsafe | ||||
|   | ||||
| @@ -45,7 +45,7 @@ namespace PolyVox | ||||
| 		m_funcDataOverflowHandler = dataOverflowHandler; | ||||
| 		m_bPagingEnabled = true; | ||||
| 		//Create a volume of the right size. | ||||
| 		resize(Region::MaxRegion,uBlockSideLength); | ||||
| 		initialise(Region::MaxRegion,uBlockSideLength); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -93,7 +93,7 @@ namespace PolyVox | ||||
| 		m_bPagingEnabled = bPagingEnabled; | ||||
|  | ||||
| 		//Create a volume of the right size. | ||||
| 		resize(regValid,uBlockSideLength); | ||||
| 		initialise(regValid,uBlockSideLength); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -391,7 +391,7 @@ namespace PolyVox | ||||
| 	/// This function should probably be made internal... | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename VoxelType> | ||||
| 	void LargeVolume<VoxelType>::resize(const Region& regValidRegion, uint16_t uBlockSideLength) | ||||
| 	void LargeVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength) | ||||
| 	{ | ||||
| 		//Debug mode validation | ||||
| 		assert(uBlockSideLength > 0); | ||||
|   | ||||
| @@ -54,24 +54,6 @@ namespace PolyVox | ||||
|         return *this; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t LargeVolume<VoxelType>::Sampler::getPosX(void) const | ||||
| 	{ | ||||
| 		return this->mXPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t LargeVolume<VoxelType>::Sampler::getPosY(void) const | ||||
| 	{ | ||||
| 		return this->mYPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t LargeVolume<VoxelType>::Sampler::getPosZ(void) const | ||||
| 	{ | ||||
| 		return this->mZPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType LargeVolume<VoxelType>::Sampler::getSubSampledVoxel(uint8_t uLevel) const | ||||
| 	{		 | ||||
| @@ -321,7 +303,7 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType LargeVolume<VoxelType>::Sampler::peekVoxel1nx1py1nz(void) const | ||||
| 	{ | ||||
| 		if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mYPosInVolume) ) | ||||
| 		if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) ) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength); | ||||
| 		} | ||||
| @@ -530,4 +512,4 @@ namespace PolyVox | ||||
| } | ||||
|  | ||||
| #undef BORDER_LOW | ||||
| #undef BORDER_HIGH | ||||
| #undef BORDER_HIGH | ||||
|   | ||||
| @@ -60,4 +60,4 @@ namespace PolyVox | ||||
| #define POLYVOX_LOG_WARN(message) if(logHandler){logHandler(message, LS_WARN);} | ||||
| #define POLYVOX_LOG_ERROR(message) if(logHandler){logHandler(message, LS_ERROR);} | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
|   | ||||
| @@ -76,35 +76,35 @@ namespace PolyVox | ||||
| 					VoxelType tSrcVoxel = srcSampler.getVoxel(); | ||||
|  | ||||
| 					uint32_t uDensity = 0; | ||||
| 					uDensity += srcSampler.peekVoxel1nx1ny1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx1ny0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx1ny1pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx0py1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx0py0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx0py1pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx1py1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx1py0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1nx1py1pz().getDensity(); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx1ny1pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx0py1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx0py0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx0py1pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx1py1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx1py0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1nx1py1pz()); | ||||
|  | ||||
| 					uDensity += srcSampler.peekVoxel0px1ny1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px1ny0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px1ny1pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px0py1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px0py0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px0py1pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px1py1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px1py0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel0px1py1pz().getDensity(); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px1ny1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px1ny0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px1ny1pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px0py1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px0py0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px0py1pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px1py1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px1py0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel0px1py1pz()); | ||||
|  | ||||
| 					uDensity += srcSampler.peekVoxel1px1ny1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px1ny0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px1ny1pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px0py1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px0py0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px0py1pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px1py1nz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px1py0pz().getDensity(); | ||||
| 					uDensity += srcSampler.peekVoxel1px1py1pz().getDensity(); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px1ny1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px1ny0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px1ny1pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px0py1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px0py0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px0py1pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px1py1nz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px1py0pz()); | ||||
| 					uDensity += convertToDensity(srcSampler.peekVoxel1px1py1pz()); | ||||
|  | ||||
| 					uDensity /= 27; | ||||
|  | ||||
|   | ||||
| @@ -45,15 +45,18 @@ namespace PolyVox | ||||
| 	/// | ||||
| 	/// \sa Density, MaterialDensityPair | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	// int32_t template parameter is a dummy, required as the compiler expects to be able to declare an | ||||
| 	// instance of VoxelType::DensityType without knowing that VoxelType doesn't actually have a density. | ||||
| 	template <typename Type> | ||||
| 	class Material : public Voxel<uint8_t, Type> | ||||
| 	class Material | ||||
| 	{ | ||||
| 	public: | ||||
| 		//We expose DensityType and MaterialType in this way so that, when code is | ||||
| 		//templatised on voxel type, it can determine the underlying storage type | ||||
| 		//using code such as 'VoxelType::DensityType value = voxel.getDensity()' | ||||
| 		//or 'VoxelType::MaterialType value = voxel.getMaterial()'. | ||||
| 		typedef uint8_t DensityType; //Shouldn't define this one... | ||||
| 		typedef int32_t DensityType; | ||||
| 		typedef Type MaterialType; | ||||
|  | ||||
| 		Material() : m_uMaterial(0) {} | ||||
| @@ -74,12 +77,12 @@ namespace PolyVox | ||||
| 			//We don't actually have a density, so make one up based on the material. | ||||
| 			if(m_uMaterial == 0) | ||||
| 			{ | ||||
| 				//return getMinDensity(); | ||||
| 				//return getminDensity()(); | ||||
| 				return 0; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				//return getMaxDensity(); | ||||
| 				//return getmaxDensity()(); | ||||
| 				return 2; | ||||
| 			} | ||||
| 		} | ||||
| @@ -89,8 +92,8 @@ namespace PolyVox | ||||
| 		void setDensity(DensityType /*uDensity*/) { assert(false); } //Cannot set density on voxel of type Material | ||||
| 		void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } | ||||
|  | ||||
| 		//static DensityType getMaxDensity() throw() { return 2; } | ||||
| 		//static DensityType getMinDensity() throw() { return 0; } | ||||
| 		//static DensityType getmaxDensity()() throw() { return 2; } | ||||
| 		//static DensityType getminDensity()() throw() { return 0; } | ||||
| 		static DensityType getThreshold() throw() { return 1; } | ||||
|  | ||||
| 	private: | ||||
| @@ -99,7 +102,25 @@ namespace PolyVox | ||||
|  | ||||
| 	typedef Material<uint8_t> Material8; | ||||
| 	typedef Material<uint16_t> Material16; | ||||
| 	typedef Material<uint32_t> Material32; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< Material8 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		typedef uint8_t MaterialType; | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
| 		static int maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< Material16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
| 		static int maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| #endif //__PolyVox_Material_H__ | ||||
|   | ||||
| @@ -30,7 +30,7 @@ freely, subject to the following restrictions: | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	///This class represents a voxel storing only a density. | ||||
| 	/// This class represents a voxel storing only a density. | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	/// In order to perform a surface extraction on a LargeVolume, PolyVox needs the underlying | ||||
| 	/// voxel type to provide both getDensity() and getMaterial() functions. The getDensity() | ||||
| @@ -45,7 +45,7 @@ namespace PolyVox | ||||
| 	/// \sa Density, Material | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> | ||||
| 	class MaterialDensityPair : public Voxel<Type, Type> | ||||
| 	class MaterialDensityPair | ||||
| 	{ | ||||
| 	public: | ||||
| 		//We expose DensityType and MaterialType in this way so that, when code is | ||||
| @@ -74,8 +74,8 @@ namespace PolyVox | ||||
| 		void setDensity(DensityType uDensity) { m_uDensity = uDensity; } | ||||
| 		void setMaterial(MaterialType uMaterial) { m_uMaterial = uMaterial; } | ||||
|  | ||||
| 		//static DensityType getMaxDensity() throw() { return (0x01 << NoOfDensityBits) - 1; } | ||||
| 		//static DensityType getMinDensity() throw() { return 0; } | ||||
| 		//static DensityType getmaxDensity()() throw() { return (0x01 << NoOfDensityBits) - 1; } | ||||
| 		//static DensityType getminDensity()() throw() { return 0; } | ||||
| 		static DensityType getThreshold() throw() {return  0x01 << (NoOfDensityBits - 1);} | ||||
|  | ||||
| 	private: | ||||
| @@ -86,13 +86,42 @@ namespace PolyVox | ||||
| 	typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44; | ||||
| 	typedef MaterialDensityPair<uint16_t, 8, 8> MaterialDensityPair88; | ||||
| 	 | ||||
| 	/*template<typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> | ||||
| 	class VoxelTypeTraits< MaterialDensityPair<Type, NoOfDensityBits, NoOfMaterialBits> > | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialDensityPair44 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static Type MinDensity = 0; | ||||
| 		const static Type MaxDensity = (0x01 << NoOfDensityBits) - 1; | ||||
| 	};*/ | ||||
| 		typedef uint8_t DensityType; | ||||
| 		typedef uint8_t MaterialType; | ||||
| 		static MaterialDensityPair44::DensityType minDensity() { return 0; } | ||||
| 		static MaterialDensityPair44::DensityType maxDensity() { return 15; } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialDensityPair88 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		typedef uint8_t MaterialType; | ||||
| 		static MaterialDensityPair88::DensityType minDensity() { return 0; } | ||||
| 		static MaterialDensityPair88::DensityType maxDensity() { return 255; } | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| #endif | ||||
| #include "PolyVoxCore/SurfaceExtractor.h" | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template<> | ||||
| 	typename VoxelTypeTraits<MaterialDensityPair44>::DensityType convertToDensity(MaterialDensityPair44 voxel); | ||||
|  | ||||
| 	template<> | ||||
| 	typename VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel); | ||||
|  | ||||
| 	template<> | ||||
| 	typename VoxelTypeTraits<MaterialDensityPair44>::MaterialType convertToMaterial(MaterialDensityPair44 voxel); | ||||
|  | ||||
| 	template<> | ||||
| 	typename VoxelTypeTraits<MaterialDensityPair88>::MaterialType convertToMaterial(MaterialDensityPair88 voxel); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -28,10 +28,13 @@ freely, subject to the following restrictions: | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	//---------- Array ---------- | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// Array | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template<uint32_t dimensions, typename ElementType> class Array; | ||||
|  | ||||
| 	typedef Array<1,float> Array1DFloat; | ||||
|     typedef Array<1,double> Array1DDouble; | ||||
| 	typedef Array<1,double> Array1DDouble; | ||||
| 	typedef Array<1,int8_t> Array1DInt8; | ||||
| 	typedef Array<1,uint8_t> Array1DUint8; | ||||
| 	typedef Array<1,int16_t> Array1DInt16; | ||||
| @@ -40,7 +43,7 @@ namespace PolyVox | ||||
| 	typedef Array<1,uint32_t> Array1DUint32; | ||||
|  | ||||
| 	typedef Array<2,float> Array2DFloat; | ||||
|     typedef Array<2,double> Array2DDouble; | ||||
| 	typedef Array<2,double> Array2DDouble; | ||||
| 	typedef Array<2,int8_t> Array2DInt8; | ||||
| 	typedef Array<2,uint8_t> Array2DUint8; | ||||
| 	typedef Array<2,int16_t> Array2DInt16; | ||||
| @@ -49,51 +52,102 @@ namespace PolyVox | ||||
| 	typedef Array<2,uint32_t> Array2DUint32; | ||||
|  | ||||
| 	typedef Array<3,float> Array3DFloat; | ||||
|     typedef Array<3,double> Array3DDouble; | ||||
| 	typedef Array<3,double> Array3DDouble; | ||||
| 	typedef Array<3,int8_t> Array3DInt8; | ||||
| 	typedef Array<3,uint8_t> Array3DUint8; | ||||
| 	typedef Array<3,int16_t> Array3DInt16; | ||||
| 	typedef Array<3,uint16_t> Array3DUint16; | ||||
| 	typedef Array<3,int32_t> Array3DInt32; | ||||
| 	typedef Array<3,uint32_t> Array3DUint32; | ||||
| 	//--------------------------------- | ||||
|  | ||||
| 	template <typename VoxelType> class Block; | ||||
|  | ||||
| 	//---------- LargeVolume ---------- | ||||
| 	template <typename VoxelType> class LargeVolume; | ||||
| 	//--------------------------------- | ||||
|  | ||||
|  | ||||
| 	template <typename Type> class Density; | ||||
| 	typedef Density<uint8_t> Density8; | ||||
| 	template <typename Type> class Material; | ||||
| 	typedef Material<uint8_t> Material8; | ||||
| 	typedef Material<uint16_t> Material16; | ||||
| 	typedef Material<uint32_t> Material32; | ||||
| 	template <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> class MaterialDensityPair; | ||||
| 	typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44; | ||||
|  | ||||
| 	template <typename VertexType> class SurfaceMesh; | ||||
| 	class Region; | ||||
| 	class PositionMaterial; | ||||
| 	class PositionMaterialNormal; | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// CubicSurfaceExtractor | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> class CubicSurfaceExtractor; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// Density | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename Type> class Density; | ||||
|  | ||||
| 	typedef Density<int8_t> DensityI8; | ||||
| 	typedef Density<uint8_t> DensityU8; | ||||
| 	typedef Density<int16_t> DensityI16; | ||||
| 	typedef Density<uint16_t> DensityU16; | ||||
| 	typedef Density<float> DensityFloat; | ||||
| 	typedef Density<double> DensityDouble; | ||||
|  | ||||
| 	typedef DensityU8 Density8; //Backwards compatibility | ||||
| 	typedef DensityU16 Density16; //Backwards compatibility | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// LargeVolume | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename VoxelType> class LargeVolume; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// Material | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename Type> class Material; | ||||
|  | ||||
| 	typedef Material<uint8_t> MaterialU8; | ||||
| 	typedef Material<uint16_t> MaterialU16; | ||||
| 	typedef Material<uint32_t> MaterialU32; | ||||
|  | ||||
| 	typedef MaterialU8 Material8; | ||||
| 	typedef MaterialU16 Material16; | ||||
| 	typedef MaterialU32 Material32; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// MaterialDensityPair | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename Type, uint8_t NoOfMaterialBits, uint8_t NoOfDensityBits> class MaterialDensityPair; | ||||
|  | ||||
| 	typedef MaterialDensityPair<uint8_t, 4, 4> MaterialDensityPair44; | ||||
| 	typedef MaterialDensityPair<uint16_t, 8, 8> MaterialDensityPair88; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// PositionMaterial | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	class PositionMaterial; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// PositionMaterialNormal | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	class PositionMaterialNormal; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// RawVolume | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename VoxelType> class RawVolume; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// Region | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	class Region; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// SurfaceExtractor | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> class SurfaceExtractor; | ||||
|  | ||||
| 	//---------- Vector ---------- | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// SurfaceMesh | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename VertexType> class SurfaceMesh; | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	// Vector | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <uint32_t Size, typename Type> class Vector; | ||||
| 	typedef Vector<3,float> Vector3DFloat; | ||||
|     typedef Vector<3,double> Vector3DDouble; | ||||
| 	typedef Vector<3,double> Vector3DDouble; | ||||
| 	typedef Vector<3,int8_t> Vector3DInt8; | ||||
| 	typedef Vector<3,uint8_t> Vector3DUint8; | ||||
| 	typedef Vector<3,int16_t> Vector3DInt16; | ||||
| 	typedef Vector<3,uint16_t> Vector3DUint16; | ||||
| 	typedef Vector<3,int32_t> Vector3DInt32; | ||||
| 	typedef Vector<3,uint32_t> Vector3DUint32; | ||||
| 	//---------------------------- | ||||
|  | ||||
| 	//template <typename VoxelType> class Sampler; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,42 +1,34 @@ | ||||
| /*******************************************************************************
 | ||||
| Copyright (c) 2005-2009 David Williams | ||||
| 
 | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any damages | ||||
| arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it | ||||
| freely, subject to the following restrictions: | ||||
| 
 | ||||
|     1. The origin of this software must not be misrepresented; you must not | ||||
|     claim that you wrote the original software. If you use this software | ||||
|     in a product, an acknowledgment in the product documentation would be | ||||
|     appreciated but is not required. | ||||
| 
 | ||||
|     2. Altered source versions must be plainly marked as such, and must not be | ||||
|     misrepresented as being the original software. | ||||
| 
 | ||||
|     3. This notice may not be removed or altered from any source | ||||
|     distribution. 	 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef __PolyVox_SurfaceTypes_H__ | ||||
| #define __PolyVox_SurfaceTypes_H__ | ||||
| 
 | ||||
| #include <set> | ||||
| 
 | ||||
| namespace PolyVox | ||||
| {	 | ||||
| 	class SurfaceVertex; | ||||
| 	typedef std::set<SurfaceVertex>::iterator SurfaceVertexIterator; | ||||
| 	typedef std::set<SurfaceVertex>::const_iterator SurfaceVertexConstIterator; | ||||
| 	class SurfaceTriangle; | ||||
| 	typedef std::set<SurfaceTriangle>::iterator SurfaceTriangleIterator; | ||||
| 	typedef std::set<SurfaceTriangle>::const_iterator SurfaceTriangleConstIterator; | ||||
| 	class SurfaceEdge; | ||||
| 	typedef std::set<SurfaceEdge>::iterator SurfaceEdgeIterator; | ||||
| 	typedef std::set<SurfaceEdge>::const_iterator SurfaceEdgeConstIterator; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /*******************************************************************************
 | ||||
| Copyright (c) 2005-2009 David Williams | ||||
| 
 | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any damages | ||||
| arising from the use of this software. | ||||
| 
 | ||||
| Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it | ||||
| freely, subject to the following restrictions: | ||||
| 
 | ||||
|     1. The origin of this software must not be misrepresented; you must not | ||||
|     claim that you wrote the original software. If you use this software | ||||
|     in a product, an acknowledgment in the product documentation would be | ||||
|     appreciated but is not required. | ||||
| 
 | ||||
|     2. Altered source versions must be plainly marked as such, and must not be | ||||
|     misrepresented as being the original software. | ||||
| 
 | ||||
|     3. This notice may not be removed or altered from any source | ||||
|     distribution. 	 | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| #ifndef __PolyVox_PrimitiveVoxelTypes_H__ | ||||
| #define __PolyVox_PrimitiveVoxelTypes_H__ | ||||
| 
 | ||||
| #include "PolyVoxCore/Voxel.h" | ||||
| 
 | ||||
| namespace PolyVox | ||||
| {	 | ||||
| 	 | ||||
| } | ||||
| 
 | ||||
| #endif //__PolyVox_PrimitiveVoxelTypes_H__
 | ||||
| @@ -59,9 +59,6 @@ namespace PolyVox | ||||
| 			Sampler(RawVolume<VoxelType>* volume); | ||||
| 			~Sampler(); | ||||
|  | ||||
| 			int32_t getPosX(void) const; | ||||
| 			int32_t getPosY(void) const; | ||||
| 			int32_t getPosZ(void) const; | ||||
| 			inline VoxelType getVoxel(void) const;			 | ||||
|  | ||||
| 			void setPosition(const Vector3DInt32& v3dNewPos); | ||||
| @@ -144,10 +141,9 @@ namespace PolyVox | ||||
| 		/// Calculates approximatly how many bytes of memory the volume is currently using. | ||||
| 		uint32_t calculateSizeInBytes(void); | ||||
|  | ||||
| 		/// Deprecated - I don't think we should expose this function? Let us know if you disagree... | ||||
| 		void resize(const Region& regValidRegion); | ||||
| private: | ||||
| 		void initialise(const Region& regValidRegion); | ||||
|  | ||||
| private:	 | ||||
| 		//The block data | ||||
| 		VoxelType* m_pData; | ||||
|  | ||||
|   | ||||
| @@ -37,7 +37,7 @@ namespace PolyVox | ||||
| 		setBorderValue(VoxelType()); | ||||
|  | ||||
| 		//Create a volume of the right size. | ||||
| 		resize(regValid); | ||||
| 		initialise(regValid); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -157,7 +157,7 @@ namespace PolyVox | ||||
| 	/// This function should probably be made internal... | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename VoxelType> | ||||
| 	void RawVolume<VoxelType>::resize(const Region& regValidRegion) | ||||
| 	void RawVolume<VoxelType>::initialise(const Region& regValidRegion) | ||||
| 	{ | ||||
| 		this->m_regValidRegion = regValidRegion; | ||||
|  | ||||
|   | ||||
| @@ -45,24 +45,6 @@ namespace PolyVox | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t RawVolume<VoxelType>::Sampler::getPosX(void) const | ||||
| 	{ | ||||
| 		return this->mXPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t RawVolume<VoxelType>::Sampler::getPosY(void) const | ||||
| 	{ | ||||
| 		return this->mYPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t RawVolume<VoxelType>::Sampler::getPosZ(void) const | ||||
| 	{ | ||||
| 		return this->mZPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::getVoxel(void) const | ||||
| 	{ | ||||
| @@ -224,7 +206,7 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py1nz(void) const | ||||
| 	{ | ||||
| 		if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mYPosInVolume) ) | ||||
| 		if( BORDER_LOWX(this->mXPosInVolume) && BORDER_HIGHY(this->mYPosInVolume) && BORDER_LOWZ(this->mZPosInVolume) ) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| @@ -437,4 +419,4 @@ namespace PolyVox | ||||
| #undef BORDER_LOWY | ||||
| #undef BORDER_HIGHY | ||||
| #undef BORDER_LOWZ | ||||
| #undef BORDER_HIGHZ | ||||
| #undef BORDER_HIGHZ | ||||
|   | ||||
| @@ -59,6 +59,14 @@ namespace PolyVox | ||||
| 	/// of the RaycastResult structure and the intersectionFound flag is set to true, otherwise | ||||
| 	/// the intersectionFound flag is set to false. | ||||
| 	/// | ||||
| 	/// <b>Important Note:</b> These has been confusion in the past with people not realising | ||||
| 	/// that the length of the direction vector is important. Most graphics API can provide | ||||
| 	/// a camera position and view direction for picking purposes, but the view direction is | ||||
| 	/// usually normalised (i.e. of length one). If you use this view direction directly you | ||||
| 	/// will only iterate over a single voxel and won't find what you are looking for. Instead | ||||
| 	/// you must scale the direction vector so that it's length represents the maximum distance | ||||
| 	/// over which you want the ray to be cast. | ||||
| 	/// | ||||
| 	/// The following code snippet shows how the class is used: | ||||
| 	/// \code | ||||
| 	/// Vector3DFloat start(rayOrigin.x(), rayOrigin.y(), rayOrigin.z()); | ||||
| @@ -88,12 +96,12 @@ namespace PolyVox | ||||
| 	{ | ||||
| 	public: | ||||
| 		///Constructor | ||||
| 		Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result); | ||||
| 		Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, RaycastResult& result, polyvox_function<bool(const typename VolumeType<VoxelType>::Sampler& sampler)> funcIsPassable); | ||||
|  | ||||
| 		///Sets the start position for the ray. | ||||
| 		void setStart(const Vector3DFloat& v3dStart); | ||||
| 		///Set the direction for the ray. | ||||
| 		void setDirection(const Vector3DFloat& v3dDirection); | ||||
| 		void setDirection(const Vector3DFloat& v3dDirectionAndLength); | ||||
|  | ||||
| 		///Performs the raycast. | ||||
| 		void execute(); | ||||
| @@ -101,17 +109,19 @@ namespace PolyVox | ||||
| 	private: | ||||
| 		RaycastResult& m_result; | ||||
|  | ||||
| 		polyvox_function<bool(const typename VolumeType<VoxelType>::Sampler& position)> m_funcIsPassable; | ||||
|  | ||||
| 		void doRaycast(float x1, float y1, float z1, float x2, float y2, float z2); | ||||
|  | ||||
| 		VolumeType<VoxelType>* m_volData; | ||||
| 		typename VolumeType<VoxelType>::Sampler m_sampVolume; | ||||
|  | ||||
| 		Vector3DFloat m_v3dStart; | ||||
| 		Vector3DFloat m_v3dDirection; | ||||
| 		Vector3DFloat m_v3dDirectionAndLength; | ||||
| 		float m_fMaxDistance; | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| #include "PolyVoxCore/Raycast.inl" | ||||
|  | ||||
| #endif //__PolyVox_Raycast_H__ | ||||
| #endif //__PolyVox_Raycast_H__ | ||||
|   | ||||
| @@ -27,17 +27,18 @@ namespace PolyVox | ||||
| 	/// Builds a Raycast object. | ||||
| 	/// \param volData A pointer to the volume through which the ray will be cast. | ||||
| 	/// \param v3dStart The starting position of the ray. | ||||
| 	/// \param v3dDirection The direction of the ray. The length of this vector also | ||||
| 	/// \param v3dDirectionAndLength The direction of the ray. The length of this vector also | ||||
| 	/// represents the length of the ray. | ||||
| 	/// \param result An instance of RaycastResult in which the result will be stored. | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	Raycast<VolumeType, VoxelType>::Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, RaycastResult& result) | ||||
| 	Raycast<VolumeType, VoxelType>::Raycast(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, RaycastResult& result, polyvox_function<bool(const typename VolumeType<VoxelType>::Sampler& sampler)> funcIsPassable) | ||||
| 		:m_result(result) | ||||
| 		,m_volData(volData) | ||||
| 		,m_sampVolume(volData) | ||||
| 		,m_v3dStart(v3dStart) | ||||
| 		,m_v3dDirection(v3dDirection) | ||||
| 		,m_v3dDirectionAndLength(v3dDirectionAndLength) | ||||
| 		,m_funcIsPassable(funcIsPassable) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| @@ -51,13 +52,14 @@ namespace PolyVox | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	/// \param v3dDirection The direction of the ray. The length of this vector also | ||||
| 	/// \param v3dDirectionAndLength The direction of the ray. The length of this vector also | ||||
| 	/// represents the length of the ray. | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	void Raycast<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirection) | ||||
| 	void Raycast<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirectionAndLength) | ||||
| 	{ | ||||
| 		m_v3dDirection = v3dDirection; | ||||
| 		//FIXME: We should add a warning when the ray direction is of length one, as this seems to be a common mistake.  | ||||
| 		m_v3dDirectionAndLength = v3dDirectionAndLength; | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -72,7 +74,7 @@ namespace PolyVox | ||||
| 		Vector3DFloat v3dStart = m_v3dStart + Vector3DFloat(0.5f, 0.5f, 0.5f); | ||||
|  | ||||
| 		//Compute the end point | ||||
| 		Vector3DFloat v3dEnd = v3dStart + m_v3dDirection; | ||||
| 		Vector3DFloat v3dEnd = v3dStart + m_v3dDirectionAndLength; | ||||
|  | ||||
| 		//Do the raycast | ||||
| 		doRaycast(v3dStart.getX(), v3dStart.getY(), v3dStart.getZ(), v3dEnd.getX(), v3dEnd.getY(), v3dEnd.getZ()); | ||||
| @@ -138,7 +140,7 @@ namespace PolyVox | ||||
|  | ||||
| 		for(;;) | ||||
| 		{ | ||||
| 			if(m_sampVolume.getVoxel().getDensity() > VoxelType::getThreshold()) | ||||
| 			if(!m_funcIsPassable(m_sampVolume)) | ||||
| 			{ | ||||
| 				m_result.foundIntersection = true; | ||||
| 				m_result.intersectionVoxel = Vector3DInt32(i,j,k); | ||||
| @@ -178,4 +180,4 @@ namespace PolyVox | ||||
| 		m_result.intersectionVoxel = Vector3DInt32(0,0,0); | ||||
| 		m_result.previousVoxel = Vector3DInt32(0,0,0); | ||||
| 	} | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -33,12 +33,12 @@ namespace PolyVox | ||||
| 	{ | ||||
| 	public: | ||||
| 		///Constructor | ||||
| 		RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback); | ||||
| 		RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, polyvox_function<bool(const Vector3DInt32& position)> funcCallback); | ||||
|  | ||||
| 		///Sets the start position for the ray. | ||||
| 		void setStart(const Vector3DFloat& v3dStart); | ||||
| 		///Set the direction for the ray. | ||||
| 		void setDirection(const Vector3DFloat& v3dDirection); | ||||
| 		void setDirection(const Vector3DFloat& v3dDirectionAndLength); | ||||
|  | ||||
| 		///Performs the raycast. | ||||
| 		void execute(); | ||||
| @@ -52,7 +52,7 @@ namespace PolyVox | ||||
| 		typename VolumeType<VoxelType>::Sampler m_sampVolume; | ||||
|  | ||||
| 		Vector3DFloat m_v3dStart; | ||||
| 		Vector3DFloat m_v3dDirection; | ||||
| 		Vector3DFloat m_v3dDirectionAndLength; | ||||
| 		float m_fMaxDistance; | ||||
| 	}; | ||||
| } | ||||
|   | ||||
| @@ -24,11 +24,11 @@ freely, subject to the following restrictions: | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	RaycastWithCallback<VolumeType, VoxelType>::RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirection, polyvox_function<bool(const Vector3DInt32& position)> funcCallback) | ||||
| 	RaycastWithCallback<VolumeType, VoxelType>::RaycastWithCallback(VolumeType<VoxelType>* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, polyvox_function<bool(const Vector3DInt32& position)> funcCallback) | ||||
| 		:m_volData(volData) | ||||
| 		,m_sampVolume(volData) | ||||
| 		,m_v3dStart(v3dStart) | ||||
| 		,m_v3dDirection(v3dDirection) | ||||
| 		,m_v3dDirectionAndLength(v3dDirectionAndLength) | ||||
| 		,m_funcCallback(funcCallback) | ||||
| 	{ | ||||
| 		//Check the user provided a callback, because it | ||||
| @@ -43,9 +43,9 @@ namespace PolyVox | ||||
| 	} | ||||
|  | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	void RaycastWithCallback<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirection) | ||||
| 	void RaycastWithCallback<VolumeType, VoxelType>::setDirection(const Vector3DFloat& v3dDirectionAndLength) | ||||
| 	{ | ||||
| 		m_v3dDirection = v3dDirection; | ||||
| 		m_v3dDirectionAndLength = v3dDirectionAndLength; | ||||
| 	} | ||||
|  | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| @@ -57,7 +57,7 @@ namespace PolyVox | ||||
| 		Vector3DFloat v3dStart = m_v3dStart + Vector3DFloat(0.5f, 0.5f, 0.5f); | ||||
|  | ||||
| 		//Compute the end point | ||||
| 		Vector3DFloat v3dEnd = v3dStart + m_v3dDirection; | ||||
| 		Vector3DFloat v3dEnd = v3dStart + m_v3dDirectionAndLength; | ||||
|  | ||||
| 		//Do the raycast | ||||
| 		doRaycast(v3dStart.getX(), v3dStart.getY(), v3dStart.getZ(), v3dEnd.getX(), v3dEnd.getY(), v3dEnd.getZ()); | ||||
|   | ||||
| @@ -72,6 +72,7 @@ namespace PolyVox | ||||
| 		void shift(const Vector3DInt32& amount); | ||||
| 		void shiftLowerCorner(const Vector3DInt32& amount); | ||||
| 		void shiftUpperCorner(const Vector3DInt32& amount); | ||||
| 		//FIXME - Add dilate and erode functions? | ||||
| 		/// Deprecated and misleading | ||||
| 		Vector3DInt32 dimensions(void); | ||||
| 		/// Deprecated and misleading | ||||
|   | ||||
| @@ -87,9 +87,6 @@ namespace PolyVox | ||||
|  | ||||
| 			Sampler& operator=(const Sampler& rhs) throw(); | ||||
|  | ||||
| 			int32_t getPosX(void) const; | ||||
| 			int32_t getPosY(void) const; | ||||
| 			int32_t getPosZ(void) const; | ||||
| 			VoxelType getSubSampledVoxel(uint8_t uLevel) const; | ||||
| 			inline VoxelType getVoxel(void) const;			 | ||||
|  | ||||
| @@ -173,10 +170,9 @@ namespace PolyVox | ||||
| 		/// Calculates approximatly how many bytes of memory the volume is currently using. | ||||
| 		uint32_t calculateSizeInBytes(void); | ||||
|  | ||||
| 		/// Deprecated - I don't think we should expose this function? Let us know if you disagree... | ||||
| 		void resize(const Region& regValidRegion, uint16_t uBlockSideLength); | ||||
|  | ||||
| private:	 | ||||
| 		void initialise(const Region& regValidRegion, uint16_t uBlockSideLength); | ||||
|  | ||||
| 		Block* getUncompressedBlock(int32_t uBlockX, int32_t uBlockY, int32_t uBlockZ) const; | ||||
|  | ||||
| 		//The block data | ||||
|   | ||||
| @@ -57,7 +57,7 @@ namespace PolyVox | ||||
| 	:BaseVolume<VoxelType>(regValid) | ||||
| 	{ | ||||
| 		//Create a volume of the right size. | ||||
| 		resize(regValid,uBlockSideLength); | ||||
| 		initialise(regValid,uBlockSideLength); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -174,7 +174,7 @@ namespace PolyVox | ||||
| 	/// This function should probably be made internal... | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename VoxelType> | ||||
| 	void SimpleVolume<VoxelType>::resize(const Region& regValidRegion, uint16_t uBlockSideLength) | ||||
| 	void SimpleVolume<VoxelType>::initialise(const Region& regValidRegion, uint16_t uBlockSideLength) | ||||
| 	{ | ||||
| 		//Debug mode validation | ||||
| 		assert(uBlockSideLength >= 8); | ||||
|   | ||||
| @@ -54,24 +54,6 @@ namespace PolyVox | ||||
|         return *this; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t SimpleVolume<VoxelType>::Sampler::getPosX(void) const | ||||
| 	{ | ||||
| 		return this->mXPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t SimpleVolume<VoxelType>::Sampler::getPosY(void) const | ||||
| 	{ | ||||
| 		return this->mYPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	int32_t SimpleVolume<VoxelType>::Sampler::getPosZ(void) const | ||||
| 	{ | ||||
| 		return this->mZPosInVolume; | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType SimpleVolume<VoxelType>::Sampler::getSubSampledVoxel(uint8_t uLevel) const | ||||
| 	{		 | ||||
| @@ -329,7 +311,7 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType SimpleVolume<VoxelType>::Sampler::peekVoxel1nx1py1nz(void) const | ||||
| 	{ | ||||
| 		if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mYPosInVolume) ) | ||||
| 		if( BORDER_LOW(this->mXPosInVolume) && BORDER_HIGH(this->mYPosInVolume) && BORDER_LOW(this->mZPosInVolume) ) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 + this->mVolume->m_uBlockSideLength - this->mVolume->m_uBlockSideLength*this->mVolume->m_uBlockSideLength); | ||||
| 		} | ||||
|   | ||||
| @@ -1,69 +0,0 @@ | ||||
| /******************************************************************************* | ||||
| Copyright (c) 2005-2009 David Williams | ||||
|  | ||||
| This software is provided 'as-is', without any express or implied | ||||
| warranty. In no event will the authors be held liable for any damages | ||||
| arising from the use of this software. | ||||
|  | ||||
| Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it | ||||
| freely, subject to the following restrictions: | ||||
|  | ||||
|     1. The origin of this software must not be misrepresented; you must not | ||||
|     claim that you wrote the original software. If you use this software | ||||
|     in a product, an acknowledgment in the product documentation would be | ||||
|     appreciated but is not required. | ||||
|  | ||||
|     2. Altered source versions must be plainly marked as such, and must not be | ||||
|     misrepresented as being the original software. | ||||
|  | ||||
|     3. This notice may not be removed or altered from any source | ||||
|     distribution. 	 | ||||
| *******************************************************************************/ | ||||
|  | ||||
| #ifndef __PolyVox_SurfaceEdge_H__ | ||||
| #define __PolyVox_SurfaceEdge_H__ | ||||
|  | ||||
| #include "SurfaceTypes.h" | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	class SurfaceEdge | ||||
| 	{ | ||||
| 	public: | ||||
| 		SurfaceEdge(const SurfaceVertexIterator& targetToSet,const SurfaceVertexIterator& sourceToSet); | ||||
|  | ||||
| 		friend bool operator == (const SurfaceEdge& lhs, const SurfaceEdge& rhs); | ||||
| 		friend bool operator < (const SurfaceEdge& lhs, const SurfaceEdge& rhs); | ||||
|  | ||||
|  | ||||
| 		std::string tostring(void); | ||||
|  | ||||
| 		bool isDegenerate(void); | ||||
|  | ||||
| 		const SurfaceVertexIterator& getTarget(void) const; | ||||
| 		const SurfaceVertexIterator& getSource(void) const; | ||||
| 		const SurfaceEdgeIterator& getOtherHalfEdge(void) const; | ||||
| 		const SurfaceEdgeIterator& getPreviousHalfEdge(void) const; | ||||
| 		const SurfaceEdgeIterator& getNextHalfEdge(void) const; | ||||
| 		const SurfaceTriangleIterator& getTriangle(void) const; | ||||
|  | ||||
| 		void setPreviousHalfEdge(const SurfaceEdgeIterator& previousHalfEdgeToSet); | ||||
| 		void setNextHalfEdge(const SurfaceEdgeIterator& nextHalfEdgeToSet); | ||||
| 		void setTriangle(const SurfaceTriangleIterator& triangleToSet); | ||||
|  | ||||
| 		void pairWithOtherHalfEdge(const SurfaceEdgeIterator& otherHalfEdgeToPair); | ||||
|  | ||||
| 	private: | ||||
| 		SurfaceVertexIterator target; | ||||
| 		SurfaceVertexIterator source; | ||||
|  | ||||
| 		SurfaceEdgeIterator previousHalfEdge; | ||||
| 		SurfaceEdgeIterator nextHalfEdge; | ||||
| 		SurfaceEdgeIterator otherHalfEdge; | ||||
|  | ||||
| 		SurfaceTriangleIterator triangle; | ||||
| 	};	 | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -32,11 +32,27 @@ freely, subject to the following restrictions: | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< uint8_t >	 | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		typedef uint8_t MaterialType; | ||||
| 		static uint8_t minDensity() { return 0; } | ||||
| 		static uint8_t maxDensity() { return 255; } | ||||
| 	}; | ||||
|  | ||||
| 	template<typename VoxelType> | ||||
| 	typename VoxelTypeTraits<VoxelType>::MaterialType convertToMaterial(VoxelType voxel) | ||||
| 	{ | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	class SurfaceExtractor | ||||
| 	{ | ||||
| 	public: | ||||
| 		SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result); | ||||
| 		SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelTypeTraits<VoxelType>::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::minDensity() + VoxelTypeTraits<VoxelType>::maxDensity()) / 2); | ||||
|  | ||||
| 		void execute(); | ||||
|  | ||||
| @@ -64,14 +80,14 @@ namespace PolyVox | ||||
| 			//FIXME - Should actually use DensityType here, both in principle and because the maths may be | ||||
| 			//faster (and to reduce casts). So it would be good to add a way to get DensityType from a voxel. | ||||
| 			//But watch out for when the DensityType is unsigned and the difference could be negative. | ||||
| 			float voxel1nx = static_cast<float>(volIter.peekVoxel1nx0py0pz().getDensity()); | ||||
| 			float voxel1px = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity()); | ||||
| 			float voxel1nx = static_cast<float>(convertToDensity(volIter.peekVoxel1nx0py0pz())); | ||||
| 			float voxel1px = static_cast<float>(convertToDensity(volIter.peekVoxel1px0py0pz())); | ||||
|  | ||||
| 			float voxel1ny = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity()); | ||||
| 			float voxel1py = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity()); | ||||
| 			float voxel1ny = static_cast<float>(convertToDensity(volIter.peekVoxel0px1ny0pz())); | ||||
| 			float voxel1py = static_cast<float>(convertToDensity(volIter.peekVoxel0px1py0pz())); | ||||
|  | ||||
| 			float voxel1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity()); | ||||
| 			float voxel1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity()); | ||||
| 			float voxel1nz = static_cast<float>(convertToDensity(volIter.peekVoxel0px0py1nz())); | ||||
| 			float voxel1pz = static_cast<float>(convertToDensity(volIter.peekVoxel0px0py1pz())); | ||||
|  | ||||
| 			return Vector3DFloat | ||||
| 			( | ||||
| @@ -89,35 +105,35 @@ namespace PolyVox | ||||
| 				//FIXME - Should actually use DensityType here, both in principle and because the maths may be | ||||
| 				//faster (and to reduce casts). So it would be good to add a way to get DensityType from a voxel. | ||||
| 				//But watch out for when the DensityType is unsigned and the difference could be negative. | ||||
| 				const float pVoxel1nx1ny1nz = static_cast<float>(volIter.peekVoxel1nx1ny1nz().getDensity()); | ||||
| 				const float pVoxel1nx1ny0pz = static_cast<float>(volIter.peekVoxel1nx1ny0pz().getDensity()); | ||||
| 				const float pVoxel1nx1ny1pz = static_cast<float>(volIter.peekVoxel1nx1ny1pz().getDensity()); | ||||
| 				const float pVoxel1nx0py1nz = static_cast<float>(volIter.peekVoxel1nx0py1nz().getDensity()); | ||||
| 				const float pVoxel1nx0py0pz = static_cast<float>(volIter.peekVoxel1nx0py0pz().getDensity()); | ||||
| 				const float pVoxel1nx0py1pz = static_cast<float>(volIter.peekVoxel1nx0py1pz().getDensity()); | ||||
| 				const float pVoxel1nx1py1nz = static_cast<float>(volIter.peekVoxel1nx1py1nz().getDensity()); | ||||
| 				const float pVoxel1nx1py0pz = static_cast<float>(volIter.peekVoxel1nx1py0pz().getDensity()); | ||||
| 				const float pVoxel1nx1py1pz = static_cast<float>(volIter.peekVoxel1nx1py1pz().getDensity()); | ||||
| 				const float pVoxel1nx1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny1nz())); | ||||
| 				const float pVoxel1nx1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny0pz())); | ||||
| 				const float pVoxel1nx1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1ny1pz())); | ||||
| 				const float pVoxel1nx0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py1nz())); | ||||
| 				const float pVoxel1nx0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py0pz())); | ||||
| 				const float pVoxel1nx0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx0py1pz())); | ||||
| 				const float pVoxel1nx1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py1nz())); | ||||
| 				const float pVoxel1nx1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py0pz())); | ||||
| 				const float pVoxel1nx1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1nx1py1pz())); | ||||
|  | ||||
| 				const float pVoxel0px1ny1nz = static_cast<float>(volIter.peekVoxel0px1ny1nz().getDensity()); | ||||
| 				const float pVoxel0px1ny0pz = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity()); | ||||
| 				const float pVoxel0px1ny1pz = static_cast<float>(volIter.peekVoxel0px1ny1pz().getDensity()); | ||||
| 				const float pVoxel0px0py1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity()); | ||||
| 				//const float pVoxel0px0py0pz = static_cast<float>(volIter.peekVoxel0px0py0pz().getDensity()); | ||||
| 				const float pVoxel0px0py1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity()); | ||||
| 				const float pVoxel0px1py1nz = static_cast<float>(volIter.peekVoxel0px1py1nz().getDensity()); | ||||
| 				const float pVoxel0px1py0pz = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity()); | ||||
| 				const float pVoxel0px1py1pz = static_cast<float>(volIter.peekVoxel0px1py1pz().getDensity()); | ||||
| 				const float pVoxel0px1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny1nz())); | ||||
| 				const float pVoxel0px1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny0pz())); | ||||
| 				const float pVoxel0px1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1ny1pz())); | ||||
| 				const float pVoxel0px0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py1nz())); | ||||
| 				//const float pVoxel0px0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py0pz())); | ||||
| 				const float pVoxel0px0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px0py1pz())); | ||||
| 				const float pVoxel0px1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py1nz())); | ||||
| 				const float pVoxel0px1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py0pz())); | ||||
| 				const float pVoxel0px1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel0px1py1pz())); | ||||
|  | ||||
| 				const float pVoxel1px1ny1nz = static_cast<float>(volIter.peekVoxel1px1ny1nz().getDensity()); | ||||
| 				const float pVoxel1px1ny0pz = static_cast<float>(volIter.peekVoxel1px1ny0pz().getDensity()); | ||||
| 				const float pVoxel1px1ny1pz = static_cast<float>(volIter.peekVoxel1px1ny1pz().getDensity()); | ||||
| 				const float pVoxel1px0py1nz = static_cast<float>(volIter.peekVoxel1px0py1nz().getDensity()); | ||||
| 				const float pVoxel1px0py0pz = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity()); | ||||
| 				const float pVoxel1px0py1pz = static_cast<float>(volIter.peekVoxel1px0py1pz().getDensity()); | ||||
| 				const float pVoxel1px1py1nz = static_cast<float>(volIter.peekVoxel1px1py1nz().getDensity()); | ||||
| 				const float pVoxel1px1py0pz = static_cast<float>(volIter.peekVoxel1px1py0pz().getDensity()); | ||||
| 				const float pVoxel1px1py1pz = static_cast<float>(volIter.peekVoxel1px1py1pz().getDensity()); | ||||
| 				const float pVoxel1px1ny1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny1nz())); | ||||
| 				const float pVoxel1px1ny0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny0pz())); | ||||
| 				const float pVoxel1px1ny1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1ny1pz())); | ||||
| 				const float pVoxel1px0py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py1nz())); | ||||
| 				const float pVoxel1px0py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py0pz())); | ||||
| 				const float pVoxel1px0py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px0py1pz())); | ||||
| 				const float pVoxel1px1py1nz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py1nz())); | ||||
| 				const float pVoxel1px1py0pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py0pz())); | ||||
| 				const float pVoxel1px1py1pz = static_cast<float>(convertToDnsity(volIter.peekVoxel1px1py1pz())); | ||||
|  | ||||
| 				const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz - | ||||
| 					weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] * | ||||
| @@ -205,6 +221,9 @@ namespace PolyVox | ||||
| 		Region m_regVolumeCropped;*/ | ||||
| 		Region m_regSlicePrevious; | ||||
| 		Region m_regSliceCurrent; | ||||
|  | ||||
| 		//Our threshold value | ||||
| 		typename VoxelTypeTraits<VoxelType>::DensityType m_tThreshold; | ||||
| 	}; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -24,11 +24,12 @@ freely, subject to the following restrictions: | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	SurfaceExtractor<VolumeType, VoxelType>::SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result) | ||||
| 	SurfaceExtractor<VolumeType, VoxelType>::SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelTypeTraits<VoxelType>::DensityType tThreshold) | ||||
| 		:m_volData(volData) | ||||
| 		,m_sampVolume(volData) | ||||
| 		,m_meshCurrent(result) | ||||
| 		,m_regSizeInVoxels(region) | ||||
| 		,m_tThreshold(tThreshold) | ||||
| 	{ | ||||
| 		//m_regSizeInVoxels.cropTo(m_volData->getEnclosingRegion()); | ||||
| 		m_regSizeInCells = m_regSizeInVoxels; | ||||
| @@ -229,7 +230,7 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; | ||||
|  | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 				else //previous X not available | ||||
| 				{ | ||||
| @@ -247,8 +248,8 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; | ||||
|  | ||||
| 					if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 			} | ||||
| 			else //previous Y not available | ||||
| @@ -269,8 +270,8 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; | ||||
|  | ||||
| 					if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 				else //previous X not available | ||||
| 				{ | ||||
| @@ -283,10 +284,10 @@ namespace PolyVox | ||||
| 					uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; | ||||
| 					iCubeIndex = iPreviousCubeIndexZ >> 4; | ||||
|  | ||||
| 					if (v001.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 16; | ||||
| 					if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; | ||||
| 					if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; | ||||
| 					if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -311,8 +312,8 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; | ||||
|  | ||||
| 					if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 				else //previous X not available | ||||
| 				{ | ||||
| @@ -329,10 +330,10 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexY; | ||||
|  | ||||
| 					if (v010.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 4; | ||||
| 					if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; | ||||
| 					if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; | ||||
| 					if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 			} | ||||
| 			else //previous Y not available | ||||
| @@ -352,10 +353,10 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX; | ||||
|  | ||||
| 					if (v100.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 2;	 | ||||
| 					if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; | ||||
| 					if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2;	 | ||||
| 					if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 				else //previous X not available | ||||
| 				{ | ||||
| @@ -369,14 +370,14 @@ namespace PolyVox | ||||
| 					v011 = m_sampVolume.peekVoxel0px1py1pz(); | ||||
| 					v111 = m_sampVolume.peekVoxel1px1py1pz(); | ||||
|  | ||||
| 					if (v000.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 1; | ||||
| 					if (v100.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 2; | ||||
| 					if (v010.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 4; | ||||
| 					if (v110.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 8; | ||||
| 					if (v001.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 16; | ||||
| 					if (v101.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 32; | ||||
| 					if (v011.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < VoxelType::getThreshold()) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v000) < m_tThreshold) iCubeIndex |= 1; | ||||
| 					if (convertToDensity(v100) < m_tThreshold) iCubeIndex |= 2; | ||||
| 					if (convertToDensity(v010) < m_tThreshold) iCubeIndex |= 4; | ||||
| 					if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (convertToDensity(v001) < m_tThreshold) iCubeIndex |= 16; | ||||
| 					if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -432,12 +433,9 @@ namespace PolyVox | ||||
| 					const VoxelType v100 = m_sampVolume.getVoxel(); | ||||
| 					const Vector3DFloat n100 = computeCentralDifferenceGradient(m_sampVolume); | ||||
|  | ||||
| 					//float fInterp = static_cast<float>(v100.getDensity() - VoxelType::getMinDensity()) / static_cast<float>(VoxelType::getMaxDensity() - VoxelType::getMinDensity()); | ||||
| 					float fInterp = static_cast<float>(VoxelType::getThreshold() - v000.getDensity()) / static_cast<float>(v100.getDensity() - v000.getDensity()); | ||||
| 					//fInterp = 0.5f; | ||||
| 					float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v100) - convertToDensity(v000)); | ||||
|  | ||||
| 					const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()) + fInterp, static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast<float>(iZVolSpace - m_regSizeInCells.getLowerCorner().getZ())); | ||||
| 					//const Vector3DFloat v3dNormal(v000.getDensity() > v100.getDensity() ? 1.0f : -1.0f,0.0,0.0); | ||||
|  | ||||
| 					Vector3DFloat v3dNormal = (n100*fInterp) + (n000*(1-fInterp)); | ||||
| 					v3dNormal.normalise(); | ||||
| @@ -445,7 +443,9 @@ namespace PolyVox | ||||
| 					//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of | ||||
| 					//material IDs does not make sense). We take the largest, so that if we are working on a material-only | ||||
| 					//volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. | ||||
| 					const uint32_t uMaterial = (std::max)(v000.getMaterial(), v100.getMaterial()); | ||||
| 					uint32_t uMaterial000 = convertToMaterial(v000); | ||||
| 					uint32_t uMaterial100 = convertToMaterial(v100); | ||||
| 					uint32_t uMaterial = (std::max)(uMaterial000, uMaterial100); | ||||
|  | ||||
| 					PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); | ||||
| 					uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); | ||||
| @@ -459,11 +459,9 @@ namespace PolyVox | ||||
| 					const VoxelType v010 = m_sampVolume.getVoxel(); | ||||
| 					const Vector3DFloat n010 = computeCentralDifferenceGradient(m_sampVolume); | ||||
|  | ||||
| 					float fInterp = static_cast<float>(VoxelType::getThreshold() - v000.getDensity()) / static_cast<float>(v010.getDensity() - v000.getDensity()); | ||||
| 					//fInterp = 0.5f; | ||||
| 					float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v010) - convertToDensity(v000)); | ||||
|  | ||||
| 					const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()) + fInterp, static_cast<float>(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ())); | ||||
| 					//const Vector3DFloat v3dNormal(0.0,v000.getDensity() > v010.getDensity() ? 1.0f : -1.0f,0.0); | ||||
|  | ||||
| 					Vector3DFloat v3dNormal = (n010*fInterp) + (n000*(1-fInterp)); | ||||
| 					v3dNormal.normalise(); | ||||
| @@ -471,7 +469,9 @@ namespace PolyVox | ||||
| 					//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of | ||||
| 					//material IDs does not make sense). We take the largest, so that if we are working on a material-only | ||||
| 					//volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. | ||||
| 					const uint32_t uMaterial = (std::max)(v000.getMaterial(), v010.getMaterial()); | ||||
| 					uint32_t uMaterial000 = convertToMaterial(v000); | ||||
| 					uint32_t uMaterial010 = convertToMaterial(v010); | ||||
| 					uint32_t uMaterial = (std::max)(uMaterial000, uMaterial010); | ||||
|  | ||||
| 					PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); | ||||
| 					uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); | ||||
| @@ -485,11 +485,9 @@ namespace PolyVox | ||||
| 					const VoxelType v001 = m_sampVolume.getVoxel(); | ||||
| 					const Vector3DFloat n001 = computeCentralDifferenceGradient(m_sampVolume); | ||||
|  | ||||
| 					float fInterp = static_cast<float>(VoxelType::getThreshold() - v000.getDensity()) / static_cast<float>(v001.getDensity() - v000.getDensity()); | ||||
| 					//fInterp = 0.5f; | ||||
| 					float fInterp = static_cast<float>(m_tThreshold - convertToDensity(v000)) / static_cast<float>(convertToDensity(v001) - convertToDensity(v000)); | ||||
|  | ||||
| 					const Vector3DFloat v3dPosition(static_cast<float>(iXVolSpace - m_regSizeInVoxels.getLowerCorner().getX()), static_cast<float>(iYVolSpace - m_regSizeInVoxels.getLowerCorner().getY()), static_cast<float>(iZVolSpace - m_regSizeInVoxels.getLowerCorner().getZ()) + fInterp); | ||||
| 					//const Vector3DFloat v3dNormal(0.0,0.0,v000.getDensity() > v001.getDensity() ? 1.0f : -1.0f); | ||||
|  | ||||
| 					Vector3DFloat v3dNormal = (n001*fInterp) + (n000*(1-fInterp)); | ||||
| 					v3dNormal.normalise(); | ||||
| @@ -497,7 +495,9 @@ namespace PolyVox | ||||
| 					//Choose one of the two materials to use for the vertex (we don't interpolate as interpolation of | ||||
| 					//material IDs does not make sense). We take the largest, so that if we are working on a material-only | ||||
| 					//volume we get the one which is non-zero. Both materials can be non-zero if our volume has a density component. | ||||
| 					const uint32_t uMaterial = (std::max)(v000.getMaterial(), v001.getMaterial()); | ||||
| 					uint32_t uMaterial000 = convertToMaterial(v000); | ||||
| 					uint32_t uMaterial001 = convertToMaterial(v001); | ||||
| 					uint32_t uMaterial = (std::max)(uMaterial000, uMaterial001); | ||||
|  | ||||
| 					PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); | ||||
| 					uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); | ||||
| @@ -531,8 +531,8 @@ namespace PolyVox | ||||
| 				m_sampVolume.setPosition(iXVolSpace,iYVolSpace,iZVolSpace);	 | ||||
|  | ||||
| 				//Current position | ||||
| 				const uint32_t uXRegSpace = m_sampVolume.getPosX() - m_regSizeInVoxels.getLowerCorner().getX(); | ||||
| 				const uint32_t uYRegSpace = m_sampVolume.getPosY() - m_regSizeInVoxels.getLowerCorner().getY(); | ||||
| 				const uint32_t uXRegSpace = m_sampVolume.getPosition().getX() - m_regSizeInVoxels.getLowerCorner().getX(); | ||||
| 				const uint32_t uYRegSpace = m_sampVolume.getPosition().getY() - m_regSizeInVoxels.getLowerCorner().getY(); | ||||
|  | ||||
| 				//Determine the index into the edge table which tells us which vertices are inside of the surface | ||||
| 				uint8_t iCubeIndex = pPreviousBitmask[uXRegSpace][uYRegSpace]; | ||||
| @@ -613,13 +613,6 @@ namespace PolyVox | ||||
|  | ||||
| 					if((ind0 != -1) && (ind1 != -1) && (ind2 != -1)) | ||||
| 					{ | ||||
| 						assert(ind0 >= 0); | ||||
| 						assert(ind1 >= 0); | ||||
| 						assert(ind2 >= 0); | ||||
|  | ||||
| 						assert(ind0 < 1000000); | ||||
| 						assert(ind1 < 1000000); | ||||
| 						assert(ind2 < 1000000); | ||||
| 						m_meshCurrent->addTriangle(ind0, ind1, ind2); | ||||
| 					} | ||||
| 				}//For each triangle | ||||
|   | ||||
| @@ -100,6 +100,11 @@ namespace PolyVox | ||||
| 	template <typename VertexType> | ||||
| 	void SurfaceMesh<VertexType>::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2) | ||||
| 	{ | ||||
| 		//Make sure the specified indices correspond to valid vertices. | ||||
| 		assert(index0 < m_vecVertices.size()); | ||||
| 		assert(index1 < m_vecVertices.size()); | ||||
| 		assert(index2 < m_vecVertices.size()); | ||||
|  | ||||
| 		m_vecTriangleIndices.push_back(index0); | ||||
| 		m_vecTriangleIndices.push_back(index1); | ||||
| 		m_vecTriangleIndices.push_back(index2); | ||||
| @@ -108,6 +113,11 @@ namespace PolyVox | ||||
| 	template <typename VertexType> | ||||
| 	void SurfaceMesh<VertexType>::addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2) | ||||
| 	{ | ||||
| 		//Make sure the specified indices correspond to valid vertices. | ||||
| 		assert(index0 < m_vecVertices.size()); | ||||
| 		assert(index1 < m_vecVertices.size()); | ||||
| 		assert(index2 < m_vecVertices.size()); | ||||
|  | ||||
| 		m_vecTriangleIndices.push_back(index0); | ||||
| 		m_vecTriangleIndices.push_back(index1); | ||||
| 		m_vecTriangleIndices.push_back(index2); | ||||
| @@ -475,4 +485,4 @@ namespace PolyVox | ||||
| 			m_vecVertices[ct].setPosition(position); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -21,6 +21,8 @@ freely, subject to the following restrictions: | ||||
|     distribution. 	 | ||||
| *******************************************************************************/ | ||||
|  | ||||
| #include "PolyVoxImpl/Utility.h" | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template< template<typename> class SrcVolumeType, template<typename> class DestVolumeType, typename VoxelType> | ||||
| @@ -110,14 +112,14 @@ namespace PolyVox | ||||
| 					VoxelType voxel110 = sampler.peekVoxel1px1py0pz(); | ||||
| 					VoxelType voxel111 = sampler.peekVoxel1px1py1pz(); | ||||
|  | ||||
| 					uint8_t voxel000Den = voxel000.getDensity(); | ||||
| 					uint8_t voxel001Den = voxel001.getDensity(); | ||||
| 					uint8_t voxel010Den = voxel010.getDensity(); | ||||
| 					uint8_t voxel011Den = voxel011.getDensity(); | ||||
| 					uint8_t voxel100Den = voxel100.getDensity(); | ||||
| 					uint8_t voxel101Den = voxel101.getDensity(); | ||||
| 					uint8_t voxel110Den = voxel110.getDensity(); | ||||
| 					uint8_t voxel111Den = voxel111.getDensity(); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel000Den = convertToDensity(voxel000); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel001Den = convertToDensity(voxel001); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel010Den = convertToDensity(voxel010); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel011Den = convertToDensity(voxel011); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel100Den = convertToDensity(voxel100); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel101Den = convertToDensity(voxel101); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel110Den = convertToDensity(voxel110); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType voxel111Den = convertToDensity(voxel111); | ||||
|  | ||||
| 					//FIXME - should accept all float parameters, but GCC complains? | ||||
| 					double dummy; | ||||
| @@ -125,10 +127,11 @@ namespace PolyVox | ||||
| 					sy = modf(sy, &dummy); | ||||
| 					sz = modf(sz, &dummy); | ||||
|  | ||||
| 					uint8_t uInterpolatedDensity = trilinearlyInterpolate<float>(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz); | ||||
| 					typename VoxelTypeTraits<VoxelType>::DensityType uInterpolatedDensity = trilinearlyInterpolate<float>(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz); | ||||
|  | ||||
| 					VoxelType result; | ||||
| 					result.setDensity(uInterpolatedDensity); | ||||
| 					//result.setDensity(uInterpolatedDensity); | ||||
| 					result = uInterpolatedDensity; | ||||
|  | ||||
| 					m_pVolDst->setVoxelAt(dx,dy,dz,result); | ||||
| 				} | ||||
|   | ||||
| @@ -30,37 +30,15 @@ freely, subject to the following restrictions: | ||||
| #include <limits> | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	/// This class represents a voxel | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	/// Detailed description... | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename DenType, typename MatType> | ||||
| 	class Voxel | ||||
| 	{ | ||||
| 	public: | ||||
| 		// We expose DensityType and MaterialType in this way so that, when code is | ||||
| 		// templatised on voxel type, it can determine the underlying storage type | ||||
| 		// using code such as 'VoxelType::DensityType value = voxel.getDensity()' | ||||
| 		// or 'VoxelType::MaterialType value = voxel.getMaterial()'. | ||||
| 		typedef DenType DensityType; | ||||
| 		typedef MatType MaterialType; | ||||
| 		 | ||||
| 		DensityType getDensity() const throw() { assert(false); return 0; } | ||||
| 		MaterialType getMaterial() const throw() { assert(false); return 0; } | ||||
|  | ||||
| 		void setDensity(DensityType uDensity) { assert(false); } | ||||
| 		void setMaterial(MaterialType /*uMaterial*/) { assert(false); }  | ||||
| 	}; | ||||
| 	 | ||||
| {	 | ||||
| 	// Various properties of the voxel types can be expressed via types traits, similar to the way std::numeric_limits is implemented. | ||||
| 	// This has some advantages compared to storing the properties directly in the voxel class. For example, by using traits it is possible | ||||
| 	// to also apply these properties to primative types which might be desirable (the Volume classes do accept primative types as template | ||||
| 	// parameters). Also, properties such as MinDensity and MaxDensity would be difficult to represent though class members because they | ||||
| 	// parameters). Also, properties such as minDensity() and maxDensity() would be difficult to represent though class members because they | ||||
| 	// depend ont the type (float has a very different range from int8_t for example). | ||||
| 	// | ||||
| 	// The properties are currently exposed as constants because we need access to them at compile time. Ideally we would like to make them | ||||
| 	// functions flagged with 'constexpr' as we could then make use of the max() and min() functions in std::numric_limits, but this is not | ||||
| 	// functions flagged with 'constexpr' as we could then make use of the max() and min() functions in std::numeric_limits, but this is not | ||||
| 	// widely supported by compilers yet. We may change this in the future. | ||||
| 	// | ||||
| 	// Syntax for templatised traits classes: http://stackoverflow.com/q/8606302/849083 | ||||
| @@ -68,10 +46,22 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits | ||||
| 	{ | ||||
| 	public: | ||||
| 		const static typename Type::DensityType MinDensity; | ||||
| 		const static typename Type::DensityType MaxDensity; | ||||
| 		typedef uint8_t DensityType; | ||||
| 		typedef uint8_t MaterialType; | ||||
|  | ||||
| 		// These default implementations return an int32_t rather than void so that the result can be | ||||
| 		// assigned to a variable for all voxel types (even those without density components). Calls | ||||
| 		// to these functions should be protected by calls to hasDensity(), but the compiler still | ||||
| 		// needs to ensure the assignment is compilable even if hasDensity() returns false. | ||||
| 		static int32_t minDensity() { assert(false); return 0; }  | ||||
| 		static int32_t maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
|  | ||||
| 	template<typename VoxelType> | ||||
| 	typename VoxelTypeTraits<VoxelType>::DensityType convertToDensity(VoxelType voxel) | ||||
| 	{ | ||||
| 		return voxel; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #endif //__PolyVox_Voxel_H__ | ||||
|   | ||||
| @@ -32,4 +32,4 @@ namespace PolyVox | ||||
| 	float computeSmoothedVoxel(typename VolumeType<uint8_t>::Sampler& volIter); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user