More refactoring of basic voxel types. Started replacing getDensity and getMaterial with free functions.
This commit is contained in:
		| @@ -91,79 +91,23 @@ 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; | ||||
| 	typedef Density<uint8_t> Density8; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< Density8 >	 | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static const bool HasDensity = true; | ||||
| 		static const bool HasMaterial = false; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static Density8::DensityType minDensity() { return std::numeric_limits<Density8::DensityType>::min(); } | ||||
| 		static Density8::DensityType maxDensity() { return std::numeric_limits<Density8::DensityType>::max(); } | ||||
| 	}; | ||||
|  | ||||
| 	// 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 DensityU8 Density8; | ||||
| 	typedef DensityU16 Density16; | ||||
| 	 | ||||
| 	// We have to define 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< DensityI8 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityI8::DensityType minDensity() { return -std::numeric_limits<DensityI8::DensityType>::max(); } | ||||
| 		static DensityI8::DensityType maxDensity() { return std::numeric_limits<DensityI8::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityU8 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityU8::DensityType minDensity() { return std::numeric_limits<DensityU8::DensityType>::min(); } | ||||
| 		static DensityU8::DensityType maxDensity() { return std::numeric_limits<DensityU8::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityI16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityI16::DensityType minDensity() { return -std::numeric_limits<DensityI16::DensityType>::max(); } | ||||
| 		static DensityI16::DensityType maxDensity() { return std::numeric_limits<DensityI16::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityU16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityU16::DensityType minDensity() { return std::numeric_limits<DensityU16::DensityType>::min(); } | ||||
| 		static DensityU16::DensityType maxDensity() { return std::numeric_limits<DensityU16::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityFloat > | ||||
| 	{ | ||||
| 	public: | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityFloat::DensityType minDensity() { return -std::numeric_limits<DensityFloat::DensityType>::max(); } | ||||
| 		static DensityFloat::DensityType maxDensity() { return std::numeric_limits<DensityFloat::DensityType>::max(); } | ||||
| 	}; | ||||
| 	 | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< DensityDouble > | ||||
| 	{ | ||||
| 	public: | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static DensityDouble::DensityType minDensity() { return -std::numeric_limits<DensityDouble::DensityType>::max(); } | ||||
| 		static DensityDouble::DensityType maxDensity() { return std::numeric_limits<DensityDouble::DensityType>::max(); } | ||||
| 	}; | ||||
| 	typename VoxelTypeTraits<Density8>::DensityType convertToDensity(Density8 voxel); | ||||
| } | ||||
|  | ||||
| #endif //__PolyVox_Density_H__ | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -100,20 +100,16 @@ namespace PolyVox | ||||
| 		MaterialType m_uMaterial; | ||||
| 	}; | ||||
|  | ||||
| 	typedef Material<uint8_t> MaterialU8; | ||||
| 	typedef Material<uint16_t> MaterialU16; | ||||
| 	typedef Material<uint32_t> MaterialU32; | ||||
|  | ||||
| 	// 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, 16, or 32 bit predefined types above instead. | ||||
| 	typedef MaterialU8 Material8; | ||||
| 	typedef MaterialU16 Material16; | ||||
| 	typedef MaterialU32 Material32; | ||||
| 	typedef Material<uint8_t> Material8; | ||||
| 	typedef Material<uint16_t> Material16; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialU8 > | ||||
| 	class VoxelTypeTraits< Material8 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static const bool HasDensity = false; | ||||
| 		static const bool HasMaterial = true; | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
| @@ -121,19 +117,12 @@ namespace PolyVox | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialU16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
| 		static int maxDensity() { assert(false); return 0; } | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< MaterialU32 > | ||||
| 	class VoxelTypeTraits< Material16 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static const bool HasDensity = false; | ||||
| 		static const bool HasMaterial = true; | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static int minDensity() { assert(false); return 0; } | ||||
|   | ||||
| @@ -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() | ||||
| @@ -90,6 +90,9 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits< MaterialDensityPair44 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static const bool HasDensity = true; | ||||
| 		static const bool HasMaterial = true; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static MaterialDensityPair44::DensityType minDensity() { return 0; } | ||||
| @@ -100,11 +103,20 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits< MaterialDensityPair88 > | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static const bool HasDensity = true; | ||||
| 		static const bool HasMaterial = true; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return true; } | ||||
| 		static MaterialDensityPair88::DensityType minDensity() { return 0; } | ||||
| 		static MaterialDensityPair88::DensityType maxDensity() { return 255; } | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	typename VoxelTypeTraits<MaterialDensityPair44>::DensityType convertToDensity(MaterialDensityPair44 voxel); | ||||
|  | ||||
| 	template<> | ||||
| 	typename VoxelTypeTraits<MaterialDensityPair88>::DensityType convertToDensity(MaterialDensityPair88 voxel); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -32,11 +32,24 @@ freely, subject to the following restrictions: | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	template<> | ||||
| 	class VoxelTypeTraits< uint8_t >	 | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static const bool HasDensity = true; | ||||
| 		static const bool HasMaterial = false; | ||||
| 		static bool hasDensity() { return true; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
| 		static uint8_t minDensity() { return 0; } | ||||
| 		static uint8_t maxDensity() { return 255; } | ||||
| 	}; | ||||
|  | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	class SurfaceExtractor | ||||
| 	{ | ||||
| 	public: | ||||
| 		SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result, typename VoxelType::DensityType tThreshold = (VoxelTypeTraits<VoxelType>::minDensity() + VoxelTypeTraits<VoxelType>::maxDensity()) / 2); | ||||
| 		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 +77,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 +102,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] * | ||||
| @@ -207,7 +220,7 @@ namespace PolyVox | ||||
| 		Region m_regSliceCurrent; | ||||
|  | ||||
| 		//Our threshold value | ||||
| 		typename VoxelType::DensityType m_tThreshold; | ||||
| 		typename VoxelTypeTraits<VoxelType>::DensityType m_tThreshold; | ||||
| 	}; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,7 @@ 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, typename  VoxelType::DensityType tThreshold) | ||||
| 	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) | ||||
| @@ -230,7 +230,7 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY | iPreviousCubeIndexZ; | ||||
|  | ||||
| 					if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 				else //previous X not available | ||||
| 				{ | ||||
| @@ -248,8 +248,8 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexY | iPreviousCubeIndexZ; | ||||
|  | ||||
| 					if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v011) < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 			} | ||||
| 			else //previous Y not available | ||||
| @@ -270,8 +270,8 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexZ; | ||||
|  | ||||
| 					if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v101) < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 				else //previous X not available | ||||
| 				{ | ||||
| @@ -284,10 +284,10 @@ namespace PolyVox | ||||
| 					uint8_t iPreviousCubeIndexZ = pPreviousBitmask[uXRegSpace][uYRegSpace]; | ||||
| 					iCubeIndex = iPreviousCubeIndexZ >> 4; | ||||
|  | ||||
| 					if (v001.getDensity() < m_tThreshold) iCubeIndex |= 16; | ||||
| 					if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < m_tThreshold) 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; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -312,8 +312,8 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX | iPreviousCubeIndexY; | ||||
|  | ||||
| 					if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (v111.getDensity() < m_tThreshold) iCubeIndex |= 128; | ||||
| 					if (convertToDensity(v110) < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (convertToDensity(v111) < m_tThreshold) iCubeIndex |= 128; | ||||
| 				} | ||||
| 				else //previous X not available | ||||
| 				{ | ||||
| @@ -330,10 +330,10 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexY; | ||||
|  | ||||
| 					if (v010.getDensity() < m_tThreshold) iCubeIndex |= 4; | ||||
| 					if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < m_tThreshold) 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 | ||||
| @@ -353,10 +353,10 @@ namespace PolyVox | ||||
|  | ||||
| 					iCubeIndex = iPreviousCubeIndexX; | ||||
|  | ||||
| 					if (v100.getDensity() < m_tThreshold) iCubeIndex |= 2;	 | ||||
| 					if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (v111.getDensity() < m_tThreshold) 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 | ||||
| 				{ | ||||
| @@ -370,14 +370,14 @@ namespace PolyVox | ||||
| 					v011 = m_sampVolume.peekVoxel0px1py1pz(); | ||||
| 					v111 = m_sampVolume.peekVoxel1px1py1pz(); | ||||
|  | ||||
| 					if (v000.getDensity() < m_tThreshold) iCubeIndex |= 1; | ||||
| 					if (v100.getDensity() < m_tThreshold) iCubeIndex |= 2; | ||||
| 					if (v010.getDensity() < m_tThreshold) iCubeIndex |= 4; | ||||
| 					if (v110.getDensity() < m_tThreshold) iCubeIndex |= 8; | ||||
| 					if (v001.getDensity() < m_tThreshold) iCubeIndex |= 16; | ||||
| 					if (v101.getDensity() < m_tThreshold) iCubeIndex |= 32; | ||||
| 					if (v011.getDensity() < m_tThreshold) iCubeIndex |= 64; | ||||
| 					if (v111.getDensity() < m_tThreshold) 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; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -391,6 +391,28 @@ namespace PolyVox | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	template<typename VoxelType, bool HasMaterialInType = true> | ||||
| 	struct getMaterialFromVoxel; | ||||
|  | ||||
| 	template<typename VoxelType> | ||||
| 	struct getMaterialFromVoxel<VoxelType, true> | ||||
| 	{ | ||||
| 		static uint32_t run(VoxelType voxel) | ||||
| 		{ | ||||
| 			return voxel.getMaterial(); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	template<typename VoxelType> | ||||
| 	struct getMaterialFromVoxel<VoxelType, false> | ||||
| 	{ | ||||
| 		static uint32_t run(VoxelType voxel) | ||||
| 		{ | ||||
| 			return 0; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
|  | ||||
| 	template< template<typename> class VolumeType, typename VoxelType> | ||||
| 	void SurfaceExtractor<VolumeType, VoxelType>::generateVerticesForSlice(const Array2DUint8& pCurrentBitmask, | ||||
| 		Array2DInt32& m_pCurrentVertexIndicesX, | ||||
| @@ -433,12 +455,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>(m_tThreshold - 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(); | ||||
| @@ -446,11 +465,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. | ||||
| 					uint32_t uMaterial = 0; | ||||
| 					if(VoxelTypeTraits<VoxelType>::hasMaterial()) | ||||
| 					{ | ||||
| 						uMaterial = (std::max)(v000.getMaterial(), v100.getMaterial()); | ||||
| 					} | ||||
| 					uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000); | ||||
| 					uint32_t uMaterial100 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v100); | ||||
| 					uint32_t uMaterial = (std::max)(uMaterial000, uMaterial100); | ||||
|  | ||||
| 					PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); | ||||
| 					uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); | ||||
| @@ -464,11 +481,9 @@ namespace PolyVox | ||||
| 					const VoxelType v010 = m_sampVolume.getVoxel(); | ||||
| 					const Vector3DFloat n010 = computeCentralDifferenceGradient(m_sampVolume); | ||||
|  | ||||
| 					float fInterp = static_cast<float>(m_tThreshold - 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(); | ||||
| @@ -476,11 +491,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. | ||||
| 					uint32_t uMaterial = 0; | ||||
| 					if(VoxelTypeTraits<VoxelType>::hasMaterial()) | ||||
| 					{ | ||||
| 						uMaterial = (std::max)(v000.getMaterial(), v010.getMaterial()); | ||||
| 					} | ||||
| 					uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000); | ||||
| 					uint32_t uMaterial010 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v010); | ||||
| 					uint32_t uMaterial = (std::max)(uMaterial000, uMaterial010); | ||||
|  | ||||
| 					PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); | ||||
| 					uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); | ||||
| @@ -494,11 +507,9 @@ namespace PolyVox | ||||
| 					const VoxelType v001 = m_sampVolume.getVoxel(); | ||||
| 					const Vector3DFloat n001 = computeCentralDifferenceGradient(m_sampVolume); | ||||
|  | ||||
| 					float fInterp = static_cast<float>(m_tThreshold - 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(); | ||||
| @@ -506,11 +517,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. | ||||
| 					uint32_t uMaterial = 0; | ||||
| 					if(VoxelTypeTraits<VoxelType>::hasMaterial()) | ||||
| 					{ | ||||
| 						uMaterial = (std::max)(v000.getMaterial(), v001.getMaterial()); | ||||
| 					} | ||||
| 					uint32_t uMaterial000 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v000); | ||||
| 					uint32_t uMaterial001 = getMaterialFromVoxel<VoxelType, VoxelTypeTraits<VoxelType>::HasMaterial>::run(v001); | ||||
| 					uint32_t uMaterial = (std::max)(uMaterial000, uMaterial001); | ||||
|  | ||||
| 					PositionMaterialNormal surfaceVertex(v3dPosition, v3dNormal, static_cast<float>(uMaterial)); | ||||
| 					uint32_t uLastVertexIndex = m_meshCurrent->addVertex(surfaceVertex); | ||||
|   | ||||
| @@ -112,14 +112,14 @@ namespace PolyVox | ||||
| 					VoxelType voxel110 = sampler.peekVoxel1px1py0pz(); | ||||
| 					VoxelType voxel111 = sampler.peekVoxel1px1py1pz(); | ||||
|  | ||||
| 					VoxelType::DensityType voxel000Den = voxel000.getDensity(); | ||||
| 					VoxelType::DensityType voxel001Den = voxel001.getDensity(); | ||||
| 					VoxelType::DensityType voxel010Den = voxel010.getDensity(); | ||||
| 					VoxelType::DensityType voxel011Den = voxel011.getDensity(); | ||||
| 					VoxelType::DensityType voxel100Den = voxel100.getDensity(); | ||||
| 					VoxelType::DensityType voxel101Den = voxel101.getDensity(); | ||||
| 					VoxelType::DensityType voxel110Den = voxel110.getDensity(); | ||||
| 					VoxelType::DensityType voxel111Den = voxel111.getDensity(); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel000Den = convertToDensity(voxel000); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel001Den = convertToDensity(voxel001); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel010Den = convertToDensity(voxel010); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel011Den = convertToDensity(voxel011); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel100Den = convertToDensity(voxel100); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel101Den = convertToDensity(voxel101); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel110Den = convertToDensity(voxel110); | ||||
| 					VoxelTypeTraits<VoxelType>::DensityType voxel111Den = convertToDensity(voxel111); | ||||
|  | ||||
| 					//FIXME - should accept all float parameters, but GCC complains? | ||||
| 					double dummy; | ||||
| @@ -127,10 +127,11 @@ namespace PolyVox | ||||
| 					sy = modf(sy, &dummy); | ||||
| 					sz = modf(sz, &dummy); | ||||
|  | ||||
| 					VoxelType::DensityType uInterpolatedDensity = trilinearlyInterpolate<float>(voxel000Den,voxel100Den,voxel010Den,voxel110Den,voxel001Den,voxel101Den,voxel011Den,voxel111Den,sx,sy,sz); | ||||
| 					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); | ||||
| 				} | ||||
|   | ||||
| @@ -68,17 +68,26 @@ namespace PolyVox | ||||
| 	class VoxelTypeTraits | ||||
| 	{ | ||||
| 	public: | ||||
| 		typedef uint8_t DensityType; | ||||
| 		static const bool HasDensity = false; | ||||
| 		static const bool HasMaterial = false; | ||||
|  | ||||
| 		static bool hasDensity() { return false; } | ||||
| 		static bool hasMaterial() { return false; } | ||||
|  | ||||
| 		// 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 coponents). Calls | ||||
| 		// 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__ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user