Applied default Visual Studio formatting to most files. This is a quick fix for the tabs vs spaces issue that messes up the formatting in any editor (esp. Linux) which handles tabs/spaces differently to Visual Studio. Some parts of the formatting look a bit worse but overall it should be better (or at least more consistent).
I didn't apply the changes to a few macro-heavy files as Visual Studio removes all indentation from macros, whereas the indentation can be handy to see nesting.
This commit is contained in:
		| @@ -97,7 +97,7 @@ namespace PolyVox | ||||
| 	{ | ||||
| 	public: | ||||
| 		AStarPathfinderParams | ||||
| 		( | ||||
| 			( | ||||
| 			VolumeType* volData, | ||||
| 			const Vector3DInt32& v3dStart, | ||||
| 			const Vector3DInt32& v3dEnd, | ||||
| @@ -105,18 +105,18 @@ namespace PolyVox | ||||
| 			float fHBias = 1.0, | ||||
| 			uint32_t uMaxNoOfNodes = 10000, | ||||
| 			Connectivity requiredConnectivity = TwentySixConnected, | ||||
| 			std::function<bool (const VolumeType*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator, | ||||
| 			std::function<void (float)> funcProgressCallback = nullptr | ||||
| 		) | ||||
| 			std::function<bool(const VolumeType*, const Vector3DInt32&)> funcIsVoxelValidForPath = &aStarDefaultVoxelValidator, | ||||
| 			std::function<void(float)> funcProgressCallback = nullptr | ||||
| 			) | ||||
| 			:volume(volData) | ||||
| 			,start(v3dStart) | ||||
| 			,end(v3dEnd) | ||||
| 			,result(listResult) | ||||
| 			,connectivity(requiredConnectivity) | ||||
| 			,hBias(fHBias) | ||||
| 			,maxNumberOfNodes(uMaxNoOfNodes) | ||||
| 			,isVoxelValidForPath(funcIsVoxelValidForPath) | ||||
| 			,progressCallback(funcProgressCallback) | ||||
| 			, start(v3dStart) | ||||
| 			, end(v3dEnd) | ||||
| 			, result(listResult) | ||||
| 			, connectivity(requiredConnectivity) | ||||
| 			, hBias(fHBias) | ||||
| 			, maxNumberOfNodes(uMaxNoOfNodes) | ||||
| 			, isVoxelValidForPath(funcIsVoxelValidForPath) | ||||
| 			, progressCallback(funcProgressCallback) | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| @@ -125,7 +125,7 @@ namespace PolyVox | ||||
|  | ||||
| 		/// The start point for the pathfinding algorithm. | ||||
| 		Vector3DInt32 start; | ||||
| 		 | ||||
|  | ||||
| 		/// The end point for the pathfinding algorithm. | ||||
| 		Vector3DInt32 end; | ||||
|  | ||||
| @@ -160,14 +160,14 @@ namespace PolyVox | ||||
| 		/// you could check to ensure that the voxel above is empty and the voxel below is solid. | ||||
| 		/// | ||||
| 		/// \sa aStarDefaultVoxelValidator | ||||
| 		std::function<bool (const VolumeType*, const Vector3DInt32&)> isVoxelValidForPath; | ||||
| 		std::function<bool(const VolumeType*, const Vector3DInt32&)> isVoxelValidForPath; | ||||
|  | ||||
| 		/// This function is called by the AStarPathfinder to report on its progress in getting to | ||||
| 		/// the goal. The progress is reported by computing the distance from the closest node found | ||||
| 		/// so far to the end node, and comparing this with the distance from the start node to the | ||||
| 		/// end node. This progress value is guarenteed to never decrease, but it may stop increasing | ||||
| 		///for short periods of time. It may even stop increasing altogether if a path cannot be found. | ||||
| 		std::function<void (float)> progressCallback; | ||||
| 		std::function<void(float)> progressCallback; | ||||
| 	}; | ||||
|  | ||||
| 	/// The AStarPathfinder compute a path from one point in the volume to another. | ||||
| @@ -218,7 +218,7 @@ namespace PolyVox | ||||
|  | ||||
| 		//The current node | ||||
| 		AllNodesContainer::iterator current; | ||||
| 		 | ||||
|  | ||||
| 		float m_fProgress; | ||||
|  | ||||
| 		AStarPathfinderParams<VolumeType> m_params; | ||||
|   | ||||
| @@ -35,7 +35,7 @@ namespace PolyVox | ||||
| 	bool aStarDefaultVoxelValidator(const VolumeType* volData, const Vector3DInt32& v3dPos) | ||||
| 	{ | ||||
| 		//Voxels are considered valid candidates for the path if they are inside the volume... | ||||
| 		if(volData->getEnclosingRegion().containsPoint(v3dPos) == false) | ||||
| 		if (volData->getEnclosingRegion().containsPoint(v3dPos) == false) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
| @@ -83,12 +83,12 @@ namespace PolyVox | ||||
|  | ||||
| 		float fDistStartToEnd = (endNode->position - startNode->position).length(); | ||||
| 		m_fProgress = 0.0f; | ||||
| 		if(m_params.progressCallback) | ||||
| 		if (m_params.progressCallback) | ||||
| 		{ | ||||
| 			m_params.progressCallback(m_fProgress); | ||||
| 		} | ||||
|  | ||||
| 		while((openNodes.empty() == false) && (openNodes.getFirst() != endNode)) | ||||
| 		while ((openNodes.empty() == false) && (openNodes.getFirst() != endNode)) | ||||
| 		{ | ||||
| 			//Move the first node from open to closed. | ||||
| 			current = openNodes.getFirst(); | ||||
| @@ -96,13 +96,13 @@ namespace PolyVox | ||||
| 			closedNodes.insert(current); | ||||
|  | ||||
| 			//Update the user on our progress | ||||
| 			if(m_params.progressCallback) | ||||
| 			if (m_params.progressCallback) | ||||
| 			{ | ||||
| 				const float fMinProgresIncreament = 0.001f; | ||||
| 				float fDistCurrentToEnd = (endNode->position - current->position).length(); | ||||
| 				float fDistNormalised = fDistCurrentToEnd / fDistStartToEnd; | ||||
| 				float fProgress = 1.0f - fDistNormalised; | ||||
| 				if(fProgress >= m_fProgress + fMinProgresIncreament) | ||||
| 				if (fProgress >= m_fProgress + fMinProgresIncreament) | ||||
| 				{ | ||||
| 					m_fProgress = fProgress; | ||||
| 					m_params.progressCallback(m_fProgress); | ||||
| @@ -116,7 +116,7 @@ namespace PolyVox | ||||
|  | ||||
| 			//Process the neighbours. Note the deliberate lack of 'break'  | ||||
| 			//statements, larger connectivities include smaller ones. | ||||
| 			switch(m_params.connectivity) | ||||
| 			switch (m_params.connectivity) | ||||
| 			{ | ||||
| 			case TwentySixConnected: | ||||
| 				processNeighbour(current->position + arrayPathfinderCorners[0], current->gVal + fCornerCost); | ||||
| @@ -129,16 +129,16 @@ namespace PolyVox | ||||
| 				processNeighbour(current->position + arrayPathfinderCorners[7], current->gVal + fCornerCost); | ||||
|  | ||||
| 			case EighteenConnected: | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 0], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 1], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 2], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 3], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 4], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 5], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 6], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 7], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 8], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[ 9], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[0], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[1], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[2], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[3], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[4], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[5], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[6], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[7], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[8], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[9], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[10], current->gVal + fEdgeCost); | ||||
| 				processNeighbour(current->position + arrayPathfinderEdges[11], current->gVal + fEdgeCost); | ||||
|  | ||||
| @@ -151,7 +151,7 @@ namespace PolyVox | ||||
| 				processNeighbour(current->position + arrayPathfinderFaces[5], current->gVal + fFaceCost); | ||||
| 			} | ||||
|  | ||||
| 			if(allNodes.size() > m_params.maxNumberOfNodes) | ||||
| 			if (allNodes.size() > m_params.maxNumberOfNodes) | ||||
| 			{ | ||||
| 				//We've reached the specified maximum number | ||||
| 				//of nodes. Just give up on the search. | ||||
| @@ -159,7 +159,7 @@ namespace PolyVox | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if((openNodes.empty()) || (openNodes.getFirst() != endNode)) | ||||
| 		if ((openNodes.empty()) || (openNodes.getFirst() != endNode)) | ||||
| 		{ | ||||
| 			//In this case we failed to find a valid path. | ||||
| 			POLYVOX_THROW(std::runtime_error, "No path found"); | ||||
| @@ -172,14 +172,14 @@ namespace PolyVox | ||||
| 			//custom sort operator for the set which we know only uses the position to sort. Hence we can safely | ||||
| 			//modify other properties of the object while it is in the set. | ||||
| 			Node* n = const_cast<Node*>(&(*endNode)); | ||||
| 			while(n != 0) | ||||
| 			while (n != 0) | ||||
| 			{ | ||||
| 				m_params.result->push_front(n->position); | ||||
| 				n = n->parent; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if(m_params.progressCallback) | ||||
| 		if (m_params.progressCallback) | ||||
| 		{ | ||||
| 			m_params.progressCallback(1.0f); | ||||
| 		} | ||||
| @@ -189,7 +189,7 @@ namespace PolyVox | ||||
| 	void AStarPathfinder<VolumeType>::processNeighbour(const Vector3DInt32& neighbourPos, float neighbourGVal) | ||||
| 	{ | ||||
| 		bool bIsVoxelValidForPath = m_params.isVoxelValidForPath(m_params.volume, neighbourPos); | ||||
| 		if(!bIsVoxelValidForPath) | ||||
| 		if (!bIsVoxelValidForPath) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| @@ -199,16 +199,16 @@ namespace PolyVox | ||||
| 		std::pair<AllNodesContainer::iterator, bool> insertResult = allNodes.insert(Node(neighbourPos.getX(), neighbourPos.getY(), neighbourPos.getZ())); | ||||
| 		AllNodesContainer::iterator neighbour = insertResult.first; | ||||
|  | ||||
| 		if(insertResult.second == true) //New node, compute h. | ||||
| 		if (insertResult.second == true) //New node, compute h. | ||||
| 		{ | ||||
| 			Node* tempNeighbour = const_cast<Node*>(&(*neighbour)); | ||||
| 			tempNeighbour -> hVal = computeH(neighbour->position, m_params.end); | ||||
| 			tempNeighbour->hVal = computeH(neighbour->position, m_params.end); | ||||
| 		} | ||||
|  | ||||
| 		OpenNodesContainer::iterator openIter = openNodes.find(neighbour); | ||||
| 		if(openIter != openNodes.end()) | ||||
| 		if (openIter != openNodes.end()) | ||||
| 		{ | ||||
| 			if(cost < neighbour->gVal) | ||||
| 			if (cost < neighbour->gVal) | ||||
| 			{ | ||||
| 				openNodes.remove(openIter); | ||||
| 				openIter = openNodes.end(); | ||||
| @@ -217,9 +217,9 @@ namespace PolyVox | ||||
|  | ||||
| 		//TODO - Nodes could keep track of if they are in open or closed? And a pointer to where they are? | ||||
| 		ClosedNodesContainer::iterator closedIter = closedNodes.find(neighbour); | ||||
| 		if(closedIter != closedNodes.end()) | ||||
| 		if (closedIter != closedNodes.end()) | ||||
| 		{ | ||||
| 			if(cost < neighbour->gVal) | ||||
| 			if (cost < neighbour->gVal) | ||||
| 			{ | ||||
| 				//Probably shouldn't happen? | ||||
| 				closedNodes.remove(closedIter); | ||||
| @@ -227,7 +227,7 @@ namespace PolyVox | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if((openIter == openNodes.end()) && (closedIter == closedNodes.end())) | ||||
| 		if ((openIter == openNodes.end()) && (closedIter == closedNodes.end())) | ||||
| 		{ | ||||
| 			//Regarding the const_cast - normally you should not modify an object which is in an sdt::set. | ||||
| 			//The reason is that objects in a set are stored sorted in a tree so they can be accessed quickly, | ||||
| @@ -245,7 +245,7 @@ namespace PolyVox | ||||
| 	float AStarPathfinder<VolumeType>::SixConnectedCost(const Vector3DInt32& a, const Vector3DInt32& b) | ||||
| 	{ | ||||
| 		//This is the only heuristic I'm sure of - just use the manhatten distance for the 6-connected case. | ||||
| 		uint32_t faceSteps = std::abs(a.getX()-b.getX()) + std::abs(a.getY()-b.getY()) + std::abs(a.getZ()-b.getZ()); | ||||
| 		uint32_t faceSteps = std::abs(a.getX() - b.getX()) + std::abs(a.getY() - b.getY()) + std::abs(a.getZ() - b.getZ()); | ||||
|  | ||||
| 		return faceSteps * 1.0f; | ||||
| 	} | ||||
| @@ -257,7 +257,7 @@ namespace PolyVox | ||||
| 		//6-connected case. This means 'h' will be bigger than it should be, resulting in a faster path which may not  | ||||
| 		//actually be the shortest one. If you have a correct heuristic for the 18-connected case then please let me know. | ||||
|  | ||||
| 		return SixConnectedCost(a,b); | ||||
| 		return SixConnectedCost(a, b); | ||||
| 	} | ||||
|  | ||||
| 	template<typename VolumeType> | ||||
| @@ -269,7 +269,7 @@ namespace PolyVox | ||||
| 		array[0] = std::abs(a.getX() - b.getX()); | ||||
| 		array[1] = std::abs(a.getY() - b.getY()); | ||||
| 		array[2] = std::abs(a.getZ() - b.getZ()); | ||||
| 		 | ||||
|  | ||||
| 		//Maybe this is better implemented directly | ||||
| 		//using three compares and two swaps... but not | ||||
| 		//until the profiler says so. | ||||
| @@ -286,8 +286,8 @@ namespace PolyVox | ||||
| 	float AStarPathfinder<VolumeType>::computeH(const Vector3DInt32& a, const Vector3DInt32& b) | ||||
| 	{ | ||||
| 		float hVal; | ||||
| 			 | ||||
| 		switch(m_params.connectivity) | ||||
|  | ||||
| 		switch (m_params.connectivity) | ||||
| 		{ | ||||
| 		case TwentySixConnected: | ||||
| 			hVal = TwentySixConnectedCost(a, b); | ||||
| @@ -295,7 +295,7 @@ namespace PolyVox | ||||
| 		case EighteenConnected: | ||||
| 			hVal = EighteenConnectedCost(a, b); | ||||
| 			break; | ||||
| 		case SixConnected:				 | ||||
| 		case SixConnected: | ||||
| 			hVal = SixConnectedCost(a, b); | ||||
| 			break; | ||||
| 		default: | ||||
| @@ -304,9 +304,9 @@ namespace PolyVox | ||||
|  | ||||
| 		//Sanity checks in debug mode. These can come out eventually, but I | ||||
| 		//want to make sure that the heuristics I've come up with make sense. | ||||
| 		POLYVOX_ASSERT((a-b).length() <= TwentySixConnectedCost(a,b), "A* heuristic error."); | ||||
| 		POLYVOX_ASSERT(TwentySixConnectedCost(a,b) <= EighteenConnectedCost(a,b), "A* heuristic error."); | ||||
| 		POLYVOX_ASSERT(EighteenConnectedCost(a,b) <= SixConnectedCost(a,b), "A* heuristic error."); | ||||
| 		POLYVOX_ASSERT((a - b).length() <= TwentySixConnectedCost(a, b), "A* heuristic error."); | ||||
| 		POLYVOX_ASSERT(TwentySixConnectedCost(a, b) <= EighteenConnectedCost(a, b), "A* heuristic error."); | ||||
| 		POLYVOX_ASSERT(EighteenConnectedCost(a, b) <= SixConnectedCost(a, b), "A* heuristic error."); | ||||
|  | ||||
| 		//Apply the bias to the computed h value; | ||||
| 		hVal *= m_params.hBias; | ||||
| @@ -323,8 +323,8 @@ namespace PolyVox | ||||
| 		//while the other one doesn't - both approaches are valid). For the same reason we want | ||||
| 		//to make sure that position (x,y,z) has a differnt hash from e.g. position (x,z,y). | ||||
| 		uint32_t aX = (a.getX() << 16) & 0x00FF0000; | ||||
| 		uint32_t aY = (a.getY() <<  8) & 0x0000FF00; | ||||
| 		uint32_t aZ = (a.getZ()      ) & 0x000000FF; | ||||
| 		uint32_t aY = (a.getY() << 8) & 0x0000FF00; | ||||
| 		uint32_t aZ = (a.getZ()) & 0x000000FF; | ||||
| 		uint32_t hashVal = hash(aX | aY | aZ); | ||||
|  | ||||
| 		//Stop hashVal going over 65535, and divide by 1000000 to make sure it is small. | ||||
| @@ -339,14 +339,14 @@ namespace PolyVox | ||||
| 	// Robert Jenkins' 32 bit integer hash function | ||||
| 	// http://www.burtleburtle.net/bob/hash/integer.html | ||||
| 	template<typename VolumeType> | ||||
| 	uint32_t AStarPathfinder<VolumeType>::hash( uint32_t a) | ||||
| 	uint32_t AStarPathfinder<VolumeType>::hash(uint32_t a) | ||||
| 	{ | ||||
| 		a = (a+0x7ed55d16) + (a<<12); | ||||
| 		a = (a^0xc761c23c) ^ (a>>19); | ||||
| 		a = (a+0x165667b1) + (a<<5); | ||||
| 		a = (a+0xd3a2646c) ^ (a<<9); | ||||
| 		a = (a+0xfd7046c5) + (a<<3); | ||||
| 		a = (a^0xb55a4f09) ^ (a>>16); | ||||
| 		a = (a + 0x7ed55d16) + (a << 12); | ||||
| 		a = (a ^ 0xc761c23c) ^ (a >> 19); | ||||
| 		a = (a + 0x165667b1) + (a << 5); | ||||
| 		a = (a + 0xd3a2646c) ^ (a << 9); | ||||
| 		a = (a + 0xfd7046c5) + (a << 3); | ||||
| 		a = (a ^ 0xb55a4f09) ^ (a >> 16); | ||||
| 		return a; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -42,10 +42,10 @@ namespace PolyVox | ||||
| { | ||||
| 	/** | ||||
| 	 * \file | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * Ambient occlusion | ||||
| 	 */ | ||||
| 	 | ||||
|  | ||||
| 	template<typename VolumeType, typename IsVoxelTransparentCallback> | ||||
| 	class AmbientOcclusionCalculatorRaycastCallback | ||||
| 	{ | ||||
| @@ -72,7 +72,7 @@ namespace PolyVox | ||||
| 	// This will be 'perfect forwarding' using 'universal references' | ||||
| 	// This will require C++11 rvalue references which is why I haven't made the | ||||
| 	// change yet. | ||||
| 	 | ||||
|  | ||||
| 	/// Calculate the ambient occlusion for the volume | ||||
| 	template<typename VolumeType, typename IsVoxelTransparentCallback> | ||||
| 	void calculateAmbientOcclusion(VolumeType* volInput, Array<3, uint8_t>* arrayResult, const Region& region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement, IsVoxelTransparentCallback isVoxelTransparentCallback); | ||||
|   | ||||
| @@ -76,14 +76,14 @@ namespace PolyVox | ||||
| 		const float fHalfRatioZ = fRatioZ * 0.5f; | ||||
| 		const Vector3DFloat v3dHalfRatio(fHalfRatioX, fHalfRatioY, fHalfRatioZ); | ||||
|  | ||||
| 		const Vector3DFloat v3dOffset(0.5f,0.5f,0.5f); | ||||
| 		const Vector3DFloat v3dOffset(0.5f, 0.5f, 0.5f); | ||||
|  | ||||
| 		//This loop iterates over the bottom-lower-left voxel in each of the cells in the output array | ||||
| 		for(uint16_t z = region.getLowerZ(); z <= region.getUpperZ(); z += iRatioZ) | ||||
| 		for (uint16_t z = region.getLowerZ(); z <= region.getUpperZ(); z += iRatioZ) | ||||
| 		{ | ||||
| 			for(uint16_t y = region.getLowerY(); y <= region.getUpperY(); y += iRatioY) | ||||
| 			for (uint16_t y = region.getLowerY(); y <= region.getUpperY(); y += iRatioY) | ||||
| 			{ | ||||
| 				for(uint16_t x = region.getLowerX(); x <= region.getUpperX(); x += iRatioX) | ||||
| 				for (uint16_t x = region.getLowerX(); x <= region.getUpperX(); x += iRatioX) | ||||
| 				{ | ||||
| 					//Compute a start position corresponding to  | ||||
| 					//the centre of the cell in the output array. | ||||
| @@ -94,8 +94,8 @@ namespace PolyVox | ||||
| 					//Keep track of how many rays did not hit anything | ||||
| 					uint8_t uVisibleDirections = 0; | ||||
|  | ||||
| 					for(int ct = 0; ct < uNoOfSamplesPerOutputElement; ct++) | ||||
| 					{						 | ||||
| 					for (int ct = 0; ct < uNoOfSamplesPerOutputElement; ct++) | ||||
| 					{ | ||||
| 						//We take a random vector with components going from -1 to 1 and scale it to go from -halfRatio to +halfRatio. | ||||
| 						//This jitter value moves our sample point from the centre of the array cell to somewhere else in the array cell | ||||
| 						Vector3DFloat v3dJitter = randomVectors[(uRandomVectorIndex += (++uIndexIncreament)) % 1019]; //Prime number helps avoid repetition on successive loops. | ||||
| @@ -104,20 +104,20 @@ namespace PolyVox | ||||
|  | ||||
| 						Vector3DFloat v3dRayDirection = randomUnitVectors[(uRandomUnitVectorIndex += (++uIndexIncreament)) % 1021]; //Different prime number. | ||||
| 						v3dRayDirection *= fRayLength; | ||||
| 						 | ||||
|  | ||||
| 						AmbientOcclusionCalculatorRaycastCallback<VolumeType, IsVoxelTransparentCallback> ambientOcclusionCalculatorRaycastCallback(isVoxelTransparentCallback); | ||||
| 						RaycastResult result = raycastWithDirection(volInput, v3dRayStart, v3dRayDirection, ambientOcclusionCalculatorRaycastCallback); | ||||
|  | ||||
| 						// Note - The performance of this could actually be improved it we exited as soon | ||||
| 						// as the ray left the volume. The raycast test has an example of how to do this. | ||||
| 						if(result == RaycastResults::Completed) | ||||
| 						if (result == RaycastResults::Completed) | ||||
| 						{ | ||||
| 							++uVisibleDirections; | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					float fVisibility; | ||||
| 					if(uNoOfSamplesPerOutputElement == 0) | ||||
| 					if (uNoOfSamplesPerOutputElement == 0) | ||||
| 					{ | ||||
| 						//The user might request zero samples (I've done this in the past while debugging - I don't want to | ||||
| 						//wait for ambient occlusion but I do want as valid result for rendering). Avoid the divide by zero. | ||||
|   | ||||
| @@ -43,7 +43,7 @@ namespace PolyVox | ||||
| 	public: | ||||
| 		typedef _VoxelType VoxelType; | ||||
|  | ||||
| 		#ifndef SWIG | ||||
| #ifndef SWIG | ||||
| 		template <typename DerivedVolumeType> | ||||
| 		class Sampler | ||||
| 		{ | ||||
| @@ -52,7 +52,7 @@ namespace PolyVox | ||||
| 			~Sampler(); | ||||
|  | ||||
| 			Vector3DInt32 getPosition(void) const; | ||||
| 			inline VoxelType getVoxel(void) const;	 | ||||
| 			inline VoxelType getVoxel(void) const; | ||||
|  | ||||
| 			void setPosition(const Vector3DInt32& v3dNewPos); | ||||
| 			void setPosition(int32_t xPos, int32_t yPos, int32_t zPos); | ||||
| @@ -105,7 +105,7 @@ namespace PolyVox | ||||
| 			int32_t mYPosInVolume; | ||||
| 			int32_t mZPosInVolume; | ||||
| 		}; | ||||
| 		#endif // SWIG | ||||
| #endif // SWIG | ||||
|  | ||||
| 	public: | ||||
| 		/// Gets a voxel at the position given by <tt>x,y,z</tt> coordinates | ||||
| @@ -121,7 +121,7 @@ namespace PolyVox | ||||
| 		/// Calculates approximatly how many bytes of memory the volume is currently using. | ||||
| 		uint32_t calculateSizeInBytes(void); | ||||
|  | ||||
| 	protected:	 | ||||
| 	protected: | ||||
| 		/// Constructor for creating a volume. | ||||
| 		BaseVolume(); | ||||
|  | ||||
|   | ||||
| @@ -125,6 +125,6 @@ namespace PolyVox | ||||
| 	uint32_t BaseVolume<VoxelType>::calculateSizeInBytes(void) | ||||
| 	{ | ||||
| 		return this->getWidth() * this->getHeight() * this->getDepth() * sizeof(VoxelType); | ||||
| 	}	 | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -30,9 +30,9 @@ namespace PolyVox | ||||
| 	template <typename DerivedVolumeType> | ||||
| 	BaseVolume<VoxelType>::Sampler<DerivedVolumeType>::Sampler(DerivedVolumeType* volume) | ||||
| 		:mVolume(volume) | ||||
| 		,mXPosInVolume(0) | ||||
| 		,mYPosInVolume(0) | ||||
| 		,mZPosInVolume(0) | ||||
| 		, mXPosInVolume(0) | ||||
| 		, mYPosInVolume(0) | ||||
| 		, mZPosInVolume(0) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -215,17 +215,17 @@ namespace PolyVox | ||||
| 		POLYVOX_THROW(std::runtime_error, "All slots full but no matches during cubic surface extraction. This is probably a bug in PolyVox"); | ||||
| 		return -1; //Should never happen. | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	/// Do not use this class directly. Use the 'extractCubicSurface' function instead (see examples). | ||||
| 	template<typename VolumeType, typename MeshType, typename IsQuadNeeded> | ||||
| 	class CubicSurfaceExtractor | ||||
| 	{		 | ||||
| 	{ | ||||
|  | ||||
| 	public: | ||||
| 		CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), bool bMergeQuads = true); | ||||
|  | ||||
| 	private: | ||||
| 		 | ||||
|  | ||||
| 	}; | ||||
|  | ||||
| 	// This version of the function performs the extraction into a user-provided mesh rather than allocating a mesh automatically. | ||||
|   | ||||
| @@ -37,7 +37,7 @@ namespace PolyVox | ||||
| 	public: | ||||
| 		bool operator()(VoxelType back, VoxelType front, VoxelType& materialToUse) | ||||
| 		{ | ||||
| 			if((back > 0) && (front == 0)) | ||||
| 			if ((back > 0) && (front == 0)) | ||||
| 			{ | ||||
| 				materialToUse = static_cast<VoxelType>(back); | ||||
| 				return true; | ||||
|   | ||||
| @@ -39,25 +39,25 @@ namespace PolyVox | ||||
| 	 * type to be used. However, the Marching Cubes algorithm does have some requirents about the underlying data in that conceptually it operates | ||||
| 	 * on a <i>density field</i>. In addition, the PolyVox implementation of the Marching Cubes algorithm also understands the idea of each voxel | ||||
| 	 * having a material which is copied into the vertex data. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * Because we want the MarchingCubesSurfaceExtractor to work on <i>any</i> voxel type, we use a <i>Marching Cubes controller</i> (passed as | ||||
| 	 * a parameter of the MarchingCubesSurfaceExtractor) to expose the required properties. This parameter defaults to the DefaultMarchingCubesController. | ||||
| 	 * The main implementation of this class is designed to work with primitives data types, and the class is also specialised for the Material, | ||||
| 	 * Density and MaterialdensityPair classes. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * If you create a custom class for your voxel data then you probably want to include a specialisation of DefaultMarchingCubesController, | ||||
| 	 * though you don't have to if you don't want to use the Marching Cubes algorithm or if you prefer to define a seperate Marching Cubes controller | ||||
| 	 * and pass it as an explicit parameter (rather than relying on the default). | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * For primitive types, the DefaultMarchingCubesController considers the value of the voxel to represent it's density and just returns a constant | ||||
| 	 * for the material. So you can, for example, run the MarchingCubesSurfaceExtractor on a volume of floats or ints. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * It is possible to customise the behaviour of the controller by providing a threshold value through the constructor. The extracted surface | ||||
| 	 * will pass through the density value specified by the threshold, and so you should make sure that the threshold value you choose is between | ||||
| 	 * the minimum and maximum values found in your volume data. By default it is in the middle of the representable range of the underlying type. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \sa MarchingCubesSurfaceExtractor | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 */ | ||||
| 	template<typename VoxelType> | ||||
| 	class DefaultMarchingCubesController | ||||
| @@ -76,7 +76,7 @@ namespace PolyVox | ||||
| 		 * if the voxel type is 'float' then the representable range is -FLT_MAX to FLT_MAX and the threshold will be set to zero. | ||||
| 		 */ | ||||
| 		DefaultMarchingCubesController(void) | ||||
| 		{	 | ||||
| 		{ | ||||
| 			if (std::is_signed<DensityType>()) | ||||
| 			{ | ||||
| 				m_tThreshold = DensityType(0); | ||||
| @@ -119,7 +119,7 @@ namespace PolyVox | ||||
| 		 */ | ||||
| 		MaterialType blendMaterials(VoxelType a, VoxelType b, float /*weight*/) | ||||
| 		{ | ||||
| 			if(convertToDensity(a) > convertToDensity(b)) | ||||
| 			if (convertToDensity(a) > convertToDensity(b)) | ||||
| 			{ | ||||
| 				return convertToMaterial(a); | ||||
| 			} | ||||
|   | ||||
| @@ -93,13 +93,13 @@ namespace PolyVox | ||||
| 		Type getDensity() const { return m_uDensity; } | ||||
| 		/** | ||||
| 		 * Set the density of the voxel | ||||
| 		 *  | ||||
| 		 * | ||||
| 		 * \param uDensity The density to set to | ||||
| 		 */ | ||||
| 		void setDensity(Type uDensity) { m_uDensity = uDensity; } | ||||
|  | ||||
| 		/// \return The maximum allowed density of the voxel | ||||
| 		static Type getMaxDensity() { return (std::numeric_limits<Type>::max)(); }  | ||||
| 		static Type getMaxDensity() { return (std::numeric_limits<Type>::max)(); } | ||||
| 		/// \return The minimum allowed density of the voxel | ||||
| 		static Type getMinDensity() { return (std::numeric_limits<Type>::min)(); } | ||||
|  | ||||
| @@ -175,7 +175,7 @@ namespace PolyVox | ||||
| 		} | ||||
|  | ||||
| 		DensityType getThreshold(void) | ||||
| 		{			 | ||||
| 		{ | ||||
| 			return m_tThreshold; | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -49,26 +49,26 @@ namespace PolyVox | ||||
| 		/// Constructor | ||||
| 		FilePager(const std::string& strFolderName = ".") | ||||
| 			:PagedVolume<VoxelType>::Pager() | ||||
| 			,m_strFolderName(strFolderName) | ||||
| 			, m_strFolderName(strFolderName) | ||||
| 		{ | ||||
| 			// Add the trailing slash, assuming the user dind't already do it. | ||||
| 				// Add the trailing slash, assuming the user dind't already do it. | ||||
| 				if ((m_strFolderName.back() != '/') && (m_strFolderName.back() != '\\')) | ||||
| 			{ | ||||
| 				{ | ||||
| 					m_strFolderName.append("/"); | ||||
| 			} | ||||
| 				} | ||||
|  | ||||
| 			// Build a unique postfix to avoid filename conflicts between multiple pagers/runs. | ||||
| 			// Not a very robust solution but this class is meant as an example for testing really. | ||||
| 			std::stringstream ss; | ||||
| 			ss << time(0) << "--"; // Avoid multiple runs using the same filenames. | ||||
| 			ss << this; // Avoid multiple FilePagers using the same filenames. | ||||
| 			m_strPostfix = ss.str(); | ||||
| 				// Build a unique postfix to avoid filename conflicts between multiple pagers/runs. | ||||
| 				// Not a very robust solution but this class is meant as an example for testing really. | ||||
| 				std::stringstream ss; | ||||
| 				ss << time(0) << "--"; // Avoid multiple runs using the same filenames. | ||||
| 				ss << this; // Avoid multiple FilePagers using the same filenames. | ||||
| 				m_strPostfix = ss.str(); | ||||
| 		} | ||||
|  | ||||
| 		/// Destructor | ||||
| 		virtual ~FilePager() | ||||
| 		{ | ||||
| 			for(std::vector<std::string>::iterator iter = m_vecCreatedFiles.begin(); iter < m_vecCreatedFiles.end(); iter++) | ||||
| 			for (std::vector<std::string>::iterator iter = m_vecCreatedFiles.begin(); iter < m_vecCreatedFiles.end(); iter++) | ||||
| 			{ | ||||
| 				POLYVOX_LOG_WARNING_IF(std::remove(iter->c_str()) != 0, "Failed to delete '", *iter, "' when destroying FilePager"); | ||||
| 			} | ||||
| @@ -84,8 +84,8 @@ namespace PolyVox | ||||
| 			std::stringstream ssFilename; | ||||
| 			ssFilename << m_strFolderName << "/" | ||||
| 				<< region.getLowerX() << "_" << region.getLowerY() << "_" << region.getLowerZ() << "_" | ||||
| 				 << region.getUpperX() << "_" << region.getUpperY() << "_" << region.getUpperZ() | ||||
| 				 << "--" << m_strPostfix; | ||||
| 				<< region.getUpperX() << "_" << region.getUpperY() << "_" << region.getUpperZ() | ||||
| 				<< "--" << m_strPostfix; | ||||
|  | ||||
| 			std::string filename = ssFilename.str(); | ||||
|  | ||||
| @@ -93,14 +93,14 @@ namespace PolyVox | ||||
| 			// the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919 | ||||
|  | ||||
| 			FILE* pFile = fopen(filename.c_str(), "rb"); | ||||
| 			if(pFile) | ||||
| 			if (pFile) | ||||
| 			{ | ||||
| 				POLYVOX_LOG_TRACE("Paging in data for ", region); | ||||
|  | ||||
| 				/*fseek(pFile, 0L, SEEK_END); | ||||
| 				size_t fileSizeInBytes = ftell(pFile); | ||||
| 				fseek(pFile, 0L, SEEK_SET); | ||||
| 				 | ||||
|  | ||||
| 				uint8_t* buffer = new uint8_t[fileSizeInBytes]; | ||||
| 				fread(buffer, sizeof(uint8_t), fileSizeInBytes, pFile); | ||||
| 				pChunk->setData(buffer, fileSizeInBytes); | ||||
| @@ -108,7 +108,7 @@ namespace PolyVox | ||||
|  | ||||
| 				fread(pChunk->getData(), sizeof(uint8_t), pChunk->getDataSizeInBytes(), pFile); | ||||
|  | ||||
| 				if(ferror(pFile)) | ||||
| 				if (ferror(pFile)) | ||||
| 				{ | ||||
| 					POLYVOX_THROW(std::runtime_error, "Error reading in chunk data, even though a file exists."); | ||||
| 				} | ||||
| @@ -145,7 +145,7 @@ namespace PolyVox | ||||
| 			// the gameplay-cubiquity integration. See: https://github.com/blackberry/GamePlay/issues/919 | ||||
|  | ||||
| 			FILE* pFile = fopen(filename.c_str(), "wb"); | ||||
| 			if(!pFile) | ||||
| 			if (!pFile) | ||||
| 			{ | ||||
| 				POLYVOX_THROW(std::runtime_error, "Unable to open file to write out chunk data."); | ||||
| 			} | ||||
| @@ -155,7 +155,7 @@ namespace PolyVox | ||||
|  | ||||
| 			fwrite(pChunk->getData(), sizeof(uint8_t), pChunk->getDataSizeInBytes(), pFile); | ||||
|  | ||||
| 			if(ferror(pFile)) | ||||
| 			if (ferror(pFile)) | ||||
| 			{ | ||||
| 				POLYVOX_THROW(std::runtime_error, "Error writing out chunk data."); | ||||
| 			} | ||||
|   | ||||
| @@ -53,8 +53,8 @@ namespace PolyVox | ||||
| 	{ | ||||
| 		Node(int x, int y, int z) | ||||
| 			:gVal(std::numeric_limits<float>::quiet_NaN()) //Initilise with NaNs so that we will | ||||
| 			,hVal(std::numeric_limits<float>::quiet_NaN()) //know if we forget to set these properly. | ||||
| 			,parent(0) | ||||
| 			, hVal(std::numeric_limits<float>::quiet_NaN()) //know if we forget to set these properly. | ||||
| 			, parent(0) | ||||
| 		{ | ||||
| 			position.setX(x); | ||||
| 			position.setY(y); | ||||
|   | ||||
| @@ -141,19 +141,19 @@ namespace PolyVox | ||||
|  | ||||
| 	/*inline uint32_t convertCoordinates(uint16_t uXPos, uint16_t uYPos, uint16_t uZPos) | ||||
| 	{ | ||||
| 		uint64_t answer = 0; | ||||
| 		answer = morton256_z[(uZPos >> 16) & 0xFF] | // we start by shifting the third byte, since we only look at the first 21 bits | ||||
| 			morton256_y[(uYPos >> 16) & 0xFF] | | ||||
| 			morton256_x[(uXPos >> 16) & 0xFF]; | ||||
| 		answer = answer << 48 | | ||||
| 			morton256_z[(uZPos >> 8) & 0xFF] | // shifting second byte | ||||
| 			morton256_y[(uYPos >> 8) & 0xFF] | | ||||
| 			morton256_x[(uXPos >> 8) & 0xFF]; | ||||
| 		answer = answer << 24 | | ||||
| 			morton256_z[(uZPos)& 0xFF] | // first byte | ||||
| 			morton256_y[(uYPos)& 0xFF] | | ||||
| 			morton256_x[(uXPos)& 0xFF]; | ||||
| 		return answer; | ||||
| 	uint64_t answer = 0; | ||||
| 	answer = morton256_z[(uZPos >> 16) & 0xFF] | // we start by shifting the third byte, since we only look at the first 21 bits | ||||
| 	morton256_y[(uYPos >> 16) & 0xFF] | | ||||
| 	morton256_x[(uXPos >> 16) & 0xFF]; | ||||
| 	answer = answer << 48 | | ||||
| 	morton256_z[(uZPos >> 8) & 0xFF] | // shifting second byte | ||||
| 	morton256_y[(uYPos >> 8) & 0xFF] | | ||||
| 	morton256_x[(uXPos >> 8) & 0xFF]; | ||||
| 	answer = answer << 24 | | ||||
| 	morton256_z[(uZPos)& 0xFF] | // first byte | ||||
| 	morton256_y[(uYPos)& 0xFF] | | ||||
| 	morton256_x[(uXPos)& 0xFF]; | ||||
| 	return answer; | ||||
| 	}*/ | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
| #include "PolyVox/Vector.h" | ||||
|  | ||||
| namespace PolyVox | ||||
| {	 | ||||
| { | ||||
| 	const Vector3DFloat randomUnitVectors[1024] = | ||||
| 	{ | ||||
| 		Vector3DFloat(+0.339922f, +0.827727f, -0.446454f), | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
| #include "PolyVox/Vector.h" | ||||
|  | ||||
| namespace PolyVox | ||||
| {	 | ||||
| { | ||||
| 	const Vector3DFloat randomVectors[1024] = | ||||
| 	{ | ||||
| 		Vector3DFloat(+0.348918f, -0.385662f, +0.650197f), | ||||
|   | ||||
| @@ -41,12 +41,12 @@ namespace PolyVox | ||||
| 				start(); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 		void start(void) | ||||
| 		{ | ||||
| 			m_start = clock::now(); | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 		float elapsedTimeInSeconds(void) | ||||
| 		{ | ||||
| 			std::chrono::duration<float> elapsed_seconds = clock::now() - m_start; | ||||
| @@ -64,7 +64,7 @@ namespace PolyVox | ||||
| 			std::chrono::duration<float, std::micro> elapsed_microseconds = clock::now() - m_start; | ||||
| 			return elapsed_microseconds.count(); | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 	private: | ||||
| 		typedef std::chrono::system_clock clock; | ||||
| 		std::chrono::time_point<clock> m_start; | ||||
|   | ||||
| @@ -29,20 +29,20 @@ namespace PolyVox | ||||
| { | ||||
| 	template <typename Type> | ||||
| 	Type lerp( | ||||
|         const Type& v0,const Type& v1, | ||||
|         const float x) | ||||
|     { | ||||
| 		const Type& v0, const Type& v1, | ||||
| 		const float x) | ||||
| 	{ | ||||
| 		//Interpolate along X | ||||
| 		Type v0_1 = (v1 - v0) * x + v0; | ||||
|  | ||||
| 		return v0_1; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	template <typename Type> | ||||
| 	Type bilerp( | ||||
|         const Type& v00,const Type& v10,const Type& v01,const Type& v11, | ||||
|         const float x, const float y) | ||||
|     { | ||||
| 		const Type& v00, const Type& v10, const Type& v01, const Type& v11, | ||||
| 		const float x, const float y) | ||||
| 	{ | ||||
| 		// Linearly interpolate along x | ||||
| 		Type v00_10 = lerp(v00, v10, x); | ||||
| 		Type v01_11 = lerp(v01, v11, x); | ||||
| @@ -51,23 +51,23 @@ namespace PolyVox | ||||
| 		Type v00_10__v01_11 = lerp(v00_10, v01_11, y); | ||||
|  | ||||
| 		return v00_10__v01_11; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	template <typename Type> | ||||
| 	Type trilerp( | ||||
|         const Type& v000,const Type& v100,const Type& v010,const Type& v110, | ||||
|         const Type& v001,const Type& v101,const Type& v011,const Type& v111, | ||||
|         const float x, const float y, const float z) | ||||
|     { | ||||
| 		const Type& v000, const Type& v100, const Type& v010, const Type& v110, | ||||
| 		const Type& v001, const Type& v101, const Type& v011, const Type& v111, | ||||
| 		const float x, const float y, const float z) | ||||
| 	{ | ||||
| 		// Bilinearly interpolate along Y | ||||
| 		Type v000_v100__v010_v110 = bilerp(v000, v100, v010, v110, x, y); | ||||
| 		Type v001_v101__v011_v111 = bilerp(v001, v101, v011, v111, x, y); | ||||
|  | ||||
| 		// And linearly interpolate the results along z | ||||
| 		Type v000_v100__v010_v110____v001_v101__v011_v111 = lerp(v000_v100__v010_v110, v001_v101__v011_v111, z); | ||||
| 			 | ||||
|  | ||||
| 		return v000_v100__v010_v110____v001_v101__v011_v111; | ||||
|     } | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #endif //__PolyVox_Interpolation_H__ | ||||
|   | ||||
| @@ -35,7 +35,7 @@ namespace PolyVox | ||||
| 	{ | ||||
| 		Vector3DInt32 v3dInitialPosition(m_Iter->getPosition().getX(), m_Iter->getPosition().getY(), m_Iter->getPosition().getZ()); | ||||
|  | ||||
| 		if(v3dInitialPosition.getX() < m_regValid.getUpperX()) | ||||
| 		if (v3dInitialPosition.getX() < m_regValid.getUpperX()) | ||||
| 		{ | ||||
| 			m_Iter->movePositiveX(); | ||||
| 			return true; | ||||
| @@ -43,7 +43,7 @@ namespace PolyVox | ||||
|  | ||||
| 		v3dInitialPosition.setX(m_regValid.getLowerX()); | ||||
|  | ||||
| 		if(v3dInitialPosition.getY() < m_regValid.getUpperY()) | ||||
| 		if (v3dInitialPosition.getY() < m_regValid.getUpperY()) | ||||
| 		{ | ||||
| 			v3dInitialPosition.setY(v3dInitialPosition.getY() + 1); | ||||
| 			m_Iter->setPosition(v3dInitialPosition); | ||||
| @@ -52,7 +52,7 @@ namespace PolyVox | ||||
|  | ||||
| 		v3dInitialPosition.setY(m_regValid.getLowerY()); | ||||
|  | ||||
| 		if(v3dInitialPosition.getZ() < m_regValid.getUpperZ()) | ||||
| 		if (v3dInitialPosition.getZ() < m_regValid.getUpperZ()) | ||||
| 		{ | ||||
| 			v3dInitialPosition.setZ(v3dInitialPosition.getZ() + 1); | ||||
| 			m_Iter->setPosition(v3dInitialPosition); | ||||
|   | ||||
| @@ -34,19 +34,19 @@ namespace PolyVox | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType, typename AccumulationType> | ||||
| 	LowPassFilter<SrcVolumeType, DstVolumeType, AccumulationType>::LowPassFilter(SrcVolumeType* pVolSrc, Region regSrc, DstVolumeType* pVolDst, Region regDst, uint32_t uKernelSize) | ||||
| 		:m_pVolSrc(pVolSrc) | ||||
| 		,m_regSrc(regSrc) | ||||
| 		,m_pVolDst(pVolDst) | ||||
| 		,m_regDst(regDst) | ||||
| 		,m_uKernelSize(uKernelSize) | ||||
| 		, m_regSrc(regSrc) | ||||
| 		, m_pVolDst(pVolDst) | ||||
| 		, m_regDst(regDst) | ||||
| 		, m_uKernelSize(uKernelSize) | ||||
| 	{ | ||||
| 		//Kernel size must be at least three | ||||
| 		if(m_uKernelSize < 3) | ||||
| 		if (m_uKernelSize < 3) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(std::invalid_argument, "Kernel size must be at least three"); | ||||
| 		} | ||||
|  | ||||
| 		//Kernel size must be odd | ||||
| 		if(m_uKernelSize % 2 == 0) | ||||
| 		if (m_uKernelSize % 2 == 0) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(std::invalid_argument, "Kernel size must be odd"); | ||||
| 		} | ||||
| @@ -73,11 +73,11 @@ namespace PolyVox | ||||
|  | ||||
| 		typename SrcVolumeType::Sampler srcSampler(m_pVolSrc); | ||||
|  | ||||
| 		for(int32_t iSrcZ = iSrcMinZ, iDstZ = iDstMinZ; iSrcZ <= iSrcMaxZ; iSrcZ++, iDstZ++) | ||||
| 		for (int32_t iSrcZ = iSrcMinZ, iDstZ = iDstMinZ; iSrcZ <= iSrcMaxZ; iSrcZ++, iDstZ++) | ||||
| 		{ | ||||
| 			for(int32_t iSrcY = iSrcMinY, iDstY = iDstMinY; iSrcY <= iSrcMaxY; iSrcY++, iDstY++) | ||||
| 			for (int32_t iSrcY = iSrcMinY, iDstY = iDstMinY; iSrcY <= iSrcMaxY; iSrcY++, iDstY++) | ||||
| 			{ | ||||
| 				for(int32_t iSrcX = iSrcMinX, iDstX = iDstMinX; iSrcX <= iSrcMaxX; iSrcX++, iDstX++) | ||||
| 				for (int32_t iSrcX = iSrcMinX, iDstX = iDstMinX; iSrcX <= iSrcMaxX; iSrcX++, iDstX++) | ||||
| 				{ | ||||
| 					AccumulationType tSrcVoxel(0); | ||||
| 					srcSampler.setPosition(iSrcX, iSrcY, iSrcZ); | ||||
| @@ -136,13 +136,13 @@ namespace PolyVox | ||||
| 		//Clear to zeros (necessary?) | ||||
| 		//FIXME - use Volume::fill() method. Implemented in base class as below | ||||
| 		//but with optimised implementations in subclasses? | ||||
| 		for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) | ||||
| 		for (int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) | ||||
| 		{ | ||||
| 			for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 			for (int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 			{ | ||||
| 				for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				for (int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				{ | ||||
| 					satVolume.setVoxel(x,y,z,0); | ||||
| 					satVolume.setVoxel(x, y, z, 0); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -170,47 +170,47 @@ namespace PolyVox | ||||
|  | ||||
| 			srcIterCont.moveForward(); | ||||
|  | ||||
| 		}while(satIterCont.moveForward()); | ||||
| 		} while (satIterCont.moveForward()); | ||||
|  | ||||
| 		//Build SAT in three passes | ||||
| 		/*for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) | ||||
| 		{ | ||||
| 			for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 			{ | ||||
| 				for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				{ | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x-1,y,z)); | ||||
| 					AccumulationType currentVal = static_cast<AccumulationType>(m_pVolSrc->getVoxel(x,y,z)); | ||||
| 		for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 		{ | ||||
| 		for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 		{ | ||||
| 		AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x-1,y,z)); | ||||
| 		AccumulationType currentVal = static_cast<AccumulationType>(m_pVolSrc->getVoxel(x,y,z)); | ||||
|  | ||||
| 					satVolume.setVoxel(x,y,z,previousSum + currentVal); | ||||
| 				} | ||||
| 			} | ||||
| 		satVolume.setVoxel(x,y,z,previousSum + currentVal); | ||||
| 		} | ||||
| 		} | ||||
| 		}*/ | ||||
|  | ||||
| 		for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) | ||||
| 		for (int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) | ||||
| 		{ | ||||
| 			for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 			for (int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 			{ | ||||
| 				for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				for (int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				{ | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y-1,z)); | ||||
| 					AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z)); | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y - 1, z)); | ||||
| 					AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y, z)); | ||||
|  | ||||
| 					satVolume.setVoxel(x,y,z,previousSum + currentSum); | ||||
| 					satVolume.setVoxel(x, y, z, previousSum + currentSum); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) | ||||
| 		for (int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++) | ||||
| 		{ | ||||
| 			for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 			for (int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++) | ||||
| 			{ | ||||
| 				for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				for (int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++) | ||||
| 				{ | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z-1)); | ||||
| 					AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x,y,z)); | ||||
| 					AccumulationType previousSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y, z - 1)); | ||||
| 					AccumulationType currentSum = static_cast<AccumulationType>(satVolume.getVoxel(x, y, z)); | ||||
|  | ||||
| 					satVolume.setVoxel(x,y,z,previousSum + currentSum); | ||||
| 					satVolume.setVoxel(x, y, z, previousSum + currentSum); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -221,11 +221,11 @@ namespace PolyVox | ||||
|  | ||||
| 		const Vector3DInt32& v3dSrcLowerCorner = m_regSrc.getLowerCorner(); | ||||
|  | ||||
| 		for(int32_t iDstZ = v3dDstLowerCorner.getZ(), iSrcZ = v3dSrcLowerCorner.getZ(); iDstZ <= v3dDstUpperCorner.getZ(); iDstZ++, iSrcZ++) | ||||
| 		for (int32_t iDstZ = v3dDstLowerCorner.getZ(), iSrcZ = v3dSrcLowerCorner.getZ(); iDstZ <= v3dDstUpperCorner.getZ(); iDstZ++, iSrcZ++) | ||||
| 		{ | ||||
| 			for(int32_t iDstY = v3dDstLowerCorner.getY(), iSrcY = v3dSrcLowerCorner.getY(); iDstY <= v3dDstUpperCorner.getY(); iDstY++, iSrcY++) | ||||
| 			for (int32_t iDstY = v3dDstLowerCorner.getY(), iSrcY = v3dSrcLowerCorner.getY(); iDstY <= v3dDstUpperCorner.getY(); iDstY++, iSrcY++) | ||||
| 			{ | ||||
| 				for(int32_t iDstX = v3dDstLowerCorner.getX(), iSrcX = v3dSrcLowerCorner.getX(); iDstX <= v3dDstUpperCorner.getX(); iDstX++, iSrcX++) | ||||
| 				for (int32_t iDstX = v3dDstLowerCorner.getX(), iSrcX = v3dSrcLowerCorner.getX(); iDstX <= v3dDstUpperCorner.getX(); iDstX++, iSrcX++) | ||||
| 				{ | ||||
| 					int32_t satLowerX = iSrcX - border - 1; | ||||
| 					int32_t satLowerY = iSrcY - border - 1; | ||||
| @@ -235,16 +235,16 @@ namespace PolyVox | ||||
| 					int32_t satUpperY = iSrcY + border; | ||||
| 					int32_t satUpperZ = iSrcZ + border; | ||||
|  | ||||
| 					AccumulationType a = satVolume.getVoxel(satLowerX,satLowerY,satLowerZ); | ||||
| 					AccumulationType b = satVolume.getVoxel(satUpperX,satLowerY,satLowerZ); | ||||
| 					AccumulationType c = satVolume.getVoxel(satLowerX,satUpperY,satLowerZ); | ||||
| 					AccumulationType d = satVolume.getVoxel(satUpperX,satUpperY,satLowerZ); | ||||
| 					AccumulationType e = satVolume.getVoxel(satLowerX,satLowerY,satUpperZ); | ||||
| 					AccumulationType f = satVolume.getVoxel(satUpperX,satLowerY,satUpperZ); | ||||
| 					AccumulationType g = satVolume.getVoxel(satLowerX,satUpperY,satUpperZ); | ||||
| 					AccumulationType h = satVolume.getVoxel(satUpperX,satUpperY,satUpperZ); | ||||
| 					AccumulationType a = satVolume.getVoxel(satLowerX, satLowerY, satLowerZ); | ||||
| 					AccumulationType b = satVolume.getVoxel(satUpperX, satLowerY, satLowerZ); | ||||
| 					AccumulationType c = satVolume.getVoxel(satLowerX, satUpperY, satLowerZ); | ||||
| 					AccumulationType d = satVolume.getVoxel(satUpperX, satUpperY, satLowerZ); | ||||
| 					AccumulationType e = satVolume.getVoxel(satLowerX, satLowerY, satUpperZ); | ||||
| 					AccumulationType f = satVolume.getVoxel(satUpperX, satLowerY, satUpperZ); | ||||
| 					AccumulationType g = satVolume.getVoxel(satLowerX, satUpperY, satUpperZ); | ||||
| 					AccumulationType h = satVolume.getVoxel(satUpperX, satUpperY, satUpperZ); | ||||
|  | ||||
| 					AccumulationType sum = h+c-d-g-f-a+b+e; | ||||
| 					AccumulationType sum = h + c - d - g - f - a + b + e; | ||||
| 					uint32_t sideLength = border * 2 + 1; | ||||
| 					AccumulationType average = sum / (sideLength*sideLength*sideLength); | ||||
|  | ||||
|   | ||||
| @@ -112,7 +112,7 @@ namespace PolyVox | ||||
| 	{ | ||||
| 		// Extract the two bytes from the uint16_t. | ||||
| 		uint16_t ux = (encodedNormal >> 8) & 0xFF; | ||||
| 		uint16_t uy = (encodedNormal     ) & 0xFF; | ||||
| 		uint16_t uy = (encodedNormal)& 0xFF; | ||||
|  | ||||
| 		// Convert to floats in the range [-1.0f, +1.0f]. | ||||
| 		float ex = ux / 127.5f - 1.0f; | ||||
|   | ||||
| @@ -142,7 +142,7 @@ namespace PolyVox | ||||
|  | ||||
| 	template< typename VolumeType, typename MeshType, typename ControllerType > | ||||
| 	void extractMarchingCubesMeshCustom(VolumeType* volData, Region region, MeshType* result, ControllerType controller) | ||||
| 	{		 | ||||
| 	{ | ||||
| 		// Validate parameters | ||||
| 		POLYVOX_THROW_IF(volData == nullptr, std::invalid_argument, "Provided volume cannot be null"); | ||||
| 		POLYVOX_THROW_IF(result == nullptr, std::invalid_argument, "Provided mesh cannot be null"); | ||||
| @@ -161,7 +161,7 @@ namespace PolyVox | ||||
| 		const uint32_t uRegionHeightInVoxels = region.getHeightInVoxels(); | ||||
| 		const uint32_t uRegionDepthInVoxels = region.getDepthInVoxels(); | ||||
|  | ||||
| 		typename ControllerType::DensityType tThreshold = controller.getThreshold();		 | ||||
| 		typename ControllerType::DensityType tThreshold = controller.getThreshold(); | ||||
|  | ||||
| 		// A naive implemetation of Marching Cubes might sample the eight corner voxels of every cell to determine the cell index.  | ||||
| 		// However, when processing the cells sequentially we cn observe that many of the voxels are shared with previous adjacent  | ||||
| @@ -456,5 +456,5 @@ namespace PolyVox | ||||
| 		POLYVOX_LOG_TRACE("Marching cubes surface extraction took ", timer.elapsedTimeInMilliSeconds(), | ||||
| 			"ms (Region size = ", region.getWidthInVoxels(), "x", region.getHeightInVoxels(), | ||||
| 			"x", region.getDepthInVoxels(), ")"); | ||||
| 	}		 | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -58,7 +58,7 @@ namespace PolyVox | ||||
| 		Type getMaterial() const { return m_uMaterial; } | ||||
| 		/** | ||||
| 		 * Set the material value of the voxel | ||||
| 		 *  | ||||
| 		 * | ||||
| 		 * \param uMaterial The material to set to | ||||
| 		 */ | ||||
| 		void setMaterial(Type uMaterial) { m_uMaterial = uMaterial; } | ||||
| @@ -76,7 +76,7 @@ namespace PolyVox | ||||
| 	public: | ||||
| 		bool operator()(Material<Type> back, Material<Type> front, Material<Type>& materialToUse) | ||||
| 		{ | ||||
| 			if((back.getMaterial() > 0) && (front.getMaterial() == 0)) | ||||
| 			if ((back.getMaterial() > 0) && (front.getMaterial() == 0)) | ||||
| 			{ | ||||
| 				materialToUse = back; | ||||
| 				return true; | ||||
|   | ||||
| @@ -93,7 +93,7 @@ namespace PolyVox | ||||
| 	public: | ||||
| 		bool operator()(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> back, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> front, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits>& materialToUse) | ||||
| 		{ | ||||
| 			if((back.getMaterial() > 0) && (front.getMaterial() == 0)) | ||||
| 			if ((back.getMaterial() > 0) && (front.getMaterial() == 0)) | ||||
| 			{ | ||||
| 				materialToUse = back; | ||||
| 				return true; | ||||
| @@ -135,7 +135,7 @@ namespace PolyVox | ||||
|  | ||||
| 		MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> blendMaterials(MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> a, MaterialDensityPair<Type, NoOfMaterialBits, NoOfDensityBits> b, float /*weight*/) | ||||
| 		{ | ||||
| 			if(convertToDensity(a) > convertToDensity(b)) | ||||
| 			if (convertToDensity(a) > convertToDensity(b)) | ||||
| 			{ | ||||
| 				return a; | ||||
| 			} | ||||
| @@ -146,7 +146,7 @@ namespace PolyVox | ||||
| 		} | ||||
|  | ||||
| 		DensityType getThreshold(void) | ||||
| 		{			 | ||||
| 		{ | ||||
| 			return m_tThreshold; | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,7 @@ namespace PolyVox | ||||
| 		typedef _IndexType IndexType; | ||||
|  | ||||
| 		Mesh(); | ||||
| 		~Mesh();	    | ||||
| 		~Mesh(); | ||||
|  | ||||
| 		IndexType getNoOfVertices(void) const; | ||||
| 		const VertexType& getVertex(IndexType index) const; | ||||
| @@ -69,9 +69,9 @@ namespace PolyVox | ||||
|  | ||||
| 		void clear(void); | ||||
| 		bool isEmpty(void) const; | ||||
| 		void removeUnusedVertices(void);		 | ||||
| 	 | ||||
| 	private:		 | ||||
| 		void removeUnusedVertices(void); | ||||
|  | ||||
| 	private: | ||||
| 		std::vector<IndexType> m_vecIndices; | ||||
| 		std::vector<VertexType> m_vecVertices; | ||||
| 		Vector3DInt32 m_offset; | ||||
|   | ||||
| @@ -30,7 +30,7 @@ namespace PolyVox | ||||
| 	} | ||||
|  | ||||
| 	template <typename VertexType, typename IndexType> | ||||
| 	Mesh<VertexType, IndexType>::~Mesh()	   | ||||
| 	Mesh<VertexType, IndexType>::~Mesh() | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| @@ -136,7 +136,7 @@ namespace PolyVox | ||||
| 		std::vector<bool> isVertexUsed(m_vecVertices.size()); | ||||
| 		std::fill(isVertexUsed.begin(), isVertexUsed.end(), false); | ||||
|  | ||||
| 		for(uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++) | ||||
| 		for (uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++) | ||||
| 		{ | ||||
| 			int v = m_vecIndices[triCt]; | ||||
| 			isVertexUsed[v] = true; | ||||
| @@ -144,9 +144,9 @@ namespace PolyVox | ||||
|  | ||||
| 		int noOfUsedVertices = 0; | ||||
| 		std::vector<uint32_t> newPos(m_vecVertices.size()); | ||||
| 		for(IndexType vertCt = 0; vertCt < m_vecVertices.size(); vertCt++) | ||||
| 		for (IndexType vertCt = 0; vertCt < m_vecVertices.size(); vertCt++) | ||||
| 		{ | ||||
| 			if(isVertexUsed[vertCt]) | ||||
| 			if (isVertexUsed[vertCt]) | ||||
| 			{ | ||||
| 				m_vecVertices[noOfUsedVertices] = m_vecVertices[vertCt]; | ||||
| 				newPos[vertCt] = noOfUsedVertices; | ||||
| @@ -156,7 +156,7 @@ namespace PolyVox | ||||
|  | ||||
| 		m_vecVertices.resize(noOfUsedVertices); | ||||
|  | ||||
| 		for(uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++) | ||||
| 		for (uint32_t triCt = 0; triCt < m_vecIndices.size(); triCt++) | ||||
| 		{ | ||||
| 			m_vecIndices[triCt] = newPos[m_vecIndices[triCt]]; | ||||
| 		} | ||||
|   | ||||
| @@ -187,7 +187,7 @@ namespace PolyVox | ||||
| 		//in the future | ||||
| 		//typedef Volume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences. | ||||
| 		//class Sampler : public VolumeOfVoxelType::template Sampler< PagedVolume<VoxelType> > | ||||
| 		#ifndef SWIG | ||||
| #ifndef SWIG | ||||
| #if defined(_MSC_VER) | ||||
| 		class Sampler : public BaseVolume<VoxelType>::Sampler< PagedVolume<VoxelType> > //This line works on VS2010 | ||||
| #else | ||||
| @@ -198,7 +198,7 @@ namespace PolyVox | ||||
| 			Sampler(PagedVolume<VoxelType>* volume); | ||||
| 			~Sampler(); | ||||
|  | ||||
| 			inline VoxelType getVoxel(void) const;			 | ||||
| 			inline VoxelType getVoxel(void) const; | ||||
|  | ||||
| 			void setPosition(const Vector3DInt32& v3dNewPos); | ||||
| 			void setPosition(int32_t xPos, int32_t yPos, int32_t zPos); | ||||
| @@ -256,7 +256,7 @@ namespace PolyVox | ||||
| 			uint16_t m_uChunkSideLengthMinusOne; | ||||
| 		}; | ||||
|  | ||||
| 		#endif // SWIG | ||||
| #endif // SWIG | ||||
|  | ||||
| 	public: | ||||
| 		/// Constructor for creating a fixed size volume. | ||||
|   | ||||
| @@ -36,38 +36,38 @@ namespace PolyVox | ||||
| 	/// \param uChunkSideLength The size of the chunks making up the volume. Small chunks will compress/decompress faster, but there will also be more of them meaning voxel access could be slower. | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| 	template <typename VoxelType> | ||||
| 	PagedVolume<VoxelType>::PagedVolume(Pager* pPager,	uint32_t uTargetMemoryUsageInBytes,	uint16_t uChunkSideLength) | ||||
| 	PagedVolume<VoxelType>::PagedVolume(Pager* pPager, uint32_t uTargetMemoryUsageInBytes, uint16_t uChunkSideLength) | ||||
| 		:BaseVolume<VoxelType>() | ||||
| 		, m_uChunkSideLength(uChunkSideLength) | ||||
| 		, m_pPager(pPager) | ||||
| 	{ | ||||
| 		// Validation of parameters | ||||
| 		POLYVOX_THROW_IF(!pPager, std::invalid_argument, "You must provide a valid pager when constructing a PagedVolume"); | ||||
| 		POLYVOX_THROW_IF(uTargetMemoryUsageInBytes < 1 * 1024 * 1024, std::invalid_argument, "Target memory usage is too small to be practical"); | ||||
| 		POLYVOX_THROW_IF(m_uChunkSideLength == 0, std::invalid_argument, "Chunk side length cannot be zero."); | ||||
| 		POLYVOX_THROW_IF(m_uChunkSideLength > 256, std::invalid_argument, "Chunk size is too large to be practical."); | ||||
| 		POLYVOX_THROW_IF(!isPowerOf2(m_uChunkSideLength), std::invalid_argument, "Chunk side length must be a power of two."); | ||||
| 			// Validation of parameters | ||||
| 			POLYVOX_THROW_IF(!pPager, std::invalid_argument, "You must provide a valid pager when constructing a PagedVolume"); | ||||
| 			POLYVOX_THROW_IF(uTargetMemoryUsageInBytes < 1 * 1024 * 1024, std::invalid_argument, "Target memory usage is too small to be practical"); | ||||
| 			POLYVOX_THROW_IF(m_uChunkSideLength == 0, std::invalid_argument, "Chunk side length cannot be zero."); | ||||
| 			POLYVOX_THROW_IF(m_uChunkSideLength > 256, std::invalid_argument, "Chunk size is too large to be practical."); | ||||
| 			POLYVOX_THROW_IF(!isPowerOf2(m_uChunkSideLength), std::invalid_argument, "Chunk side length must be a power of two."); | ||||
|  | ||||
| 		// Used to perform multiplications and divisions by bit shifting. | ||||
| 		m_uChunkSideLengthPower = logBase2(m_uChunkSideLength); | ||||
| 		// Use to perform modulo by bit operations | ||||
| 		m_iChunkMask = m_uChunkSideLength - 1; | ||||
| 			// Used to perform multiplications and divisions by bit shifting. | ||||
| 			m_uChunkSideLengthPower = logBase2(m_uChunkSideLength); | ||||
| 			// Use to perform modulo by bit operations | ||||
| 			m_iChunkMask = m_uChunkSideLength - 1; | ||||
|  | ||||
| 		// Calculate the number of chunks based on the memory limit and the size of each chunk. | ||||
| 		uint32_t uChunkSizeInBytes = PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(m_uChunkSideLength); | ||||
| 		m_uChunkCountLimit = uTargetMemoryUsageInBytes / uChunkSizeInBytes; | ||||
| 			// Calculate the number of chunks based on the memory limit and the size of each chunk. | ||||
| 			uint32_t uChunkSizeInBytes = PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(m_uChunkSideLength); | ||||
| 			m_uChunkCountLimit = uTargetMemoryUsageInBytes / uChunkSizeInBytes; | ||||
|  | ||||
| 		// Enforce sensible limits on the number of chunks. | ||||
| 		const uint32_t uMinPracticalNoOfChunks = 32; // Enough to make sure a chunks and it's neighbours can be loaded, with a few to spare. | ||||
| 		const uint32_t uMaxPracticalNoOfChunks = uChunkArraySize / 2; // A hash table should only become half-full to avoid too many clashes. | ||||
| 		POLYVOX_LOG_WARNING_IF(m_uChunkCountLimit < uMinPracticalNoOfChunks, "Requested memory usage limit of ", | ||||
| 			uTargetMemoryUsageInBytes / (1024 * 1024), "Mb is too low and cannot be adhered to."); | ||||
| 		m_uChunkCountLimit = (std::max)(m_uChunkCountLimit, uMinPracticalNoOfChunks); | ||||
| 		m_uChunkCountLimit = (std::min)(m_uChunkCountLimit, uMaxPracticalNoOfChunks); | ||||
| 			// Enforce sensible limits on the number of chunks. | ||||
| 			const uint32_t uMinPracticalNoOfChunks = 32; // Enough to make sure a chunks and it's neighbours can be loaded, with a few to spare. | ||||
| 			const uint32_t uMaxPracticalNoOfChunks = uChunkArraySize / 2; // A hash table should only become half-full to avoid too many clashes. | ||||
| 			POLYVOX_LOG_WARNING_IF(m_uChunkCountLimit < uMinPracticalNoOfChunks, "Requested memory usage limit of ", | ||||
| 				uTargetMemoryUsageInBytes / (1024 * 1024), "Mb is too low and cannot be adhered to."); | ||||
| 			m_uChunkCountLimit = (std::max)(m_uChunkCountLimit, uMinPracticalNoOfChunks); | ||||
| 			m_uChunkCountLimit = (std::min)(m_uChunkCountLimit, uMaxPracticalNoOfChunks); | ||||
|  | ||||
| 		// Inform the user about the chosen memory configuration. | ||||
| 		POLYVOX_LOG_DEBUG("Memory usage limit for volume now set to ", (m_uChunkCountLimit * uChunkSizeInBytes) / (1024 * 1024), | ||||
| 			"Mb (", m_uChunkCountLimit, " chunks of ", uChunkSizeInBytes / 1024, "Kb each)."); | ||||
| 			// Inform the user about the chosen memory configuration. | ||||
| 			POLYVOX_LOG_DEBUG("Memory usage limit for volume now set to ", (m_uChunkCountLimit * uChunkSizeInBytes) / (1024 * 1024), | ||||
| 				"Mb (", m_uChunkCountLimit, " chunks of ", uChunkSizeInBytes / 1024, "Kb each)."); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -181,13 +181,13 @@ namespace PolyVox | ||||
| 	{ | ||||
| 		// Convert the start and end positions into chunk space coordinates | ||||
| 		Vector3DInt32 v3dStart; | ||||
| 		for(int i = 0; i < 3; i++) | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			v3dStart.setElement(i, regPrefetch.getLowerCorner().getElement(i) >> m_uChunkSideLengthPower); | ||||
| 		} | ||||
|  | ||||
| 		Vector3DInt32 v3dEnd; | ||||
| 		for(int i = 0; i < 3; i++) | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			v3dEnd.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uChunkSideLengthPower); | ||||
| 		} | ||||
| @@ -199,13 +199,13 @@ namespace PolyVox | ||||
| 		uNoOfChunks = (std::min)(uNoOfChunks, m_uChunkCountLimit); | ||||
|  | ||||
| 		// Loops over the specified positions and touch the corresponding chunks. | ||||
| 		for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) | ||||
| 		for (int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) | ||||
| 		{ | ||||
| 			for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) | ||||
| 			for (int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) | ||||
| 			{ | ||||
| 				for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++) | ||||
| 				{					 | ||||
| 					getChunk(x,y,z); | ||||
| 				for (int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++) | ||||
| 				{ | ||||
| 					getChunk(x, y, z); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -233,33 +233,33 @@ namespace PolyVox | ||||
| 	/*template <typename VoxelType> | ||||
| 	void PagedVolume<VoxelType>::flush(Region regFlush) | ||||
| 	{ | ||||
| 		// Clear this pointer in case the chunk it points at is flushed. | ||||
| 		m_pLastAccessedChunk = nullptr; | ||||
| 	// Clear this pointer in case the chunk it points at is flushed. | ||||
| 	m_pLastAccessedChunk = nullptr; | ||||
|  | ||||
| 		// Convert the start and end positions into chunk space coordinates | ||||
| 		Vector3DInt32 v3dStart; | ||||
| 		for(int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			v3dStart.setElement(i, regFlush.getLowerCorner().getElement(i) >> m_uChunkSideLengthPower); | ||||
| 		} | ||||
| 	// Convert the start and end positions into chunk space coordinates | ||||
| 	Vector3DInt32 v3dStart; | ||||
| 	for(int i = 0; i < 3; i++) | ||||
| 	{ | ||||
| 	v3dStart.setElement(i, regFlush.getLowerCorner().getElement(i) >> m_uChunkSideLengthPower); | ||||
| 	} | ||||
|  | ||||
| 		Vector3DInt32 v3dEnd; | ||||
| 		for(int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			v3dEnd.setElement(i, regFlush.getUpperCorner().getElement(i) >> m_uChunkSideLengthPower); | ||||
| 		} | ||||
| 	Vector3DInt32 v3dEnd; | ||||
| 	for(int i = 0; i < 3; i++) | ||||
| 	{ | ||||
| 	v3dEnd.setElement(i, regFlush.getUpperCorner().getElement(i) >> m_uChunkSideLengthPower); | ||||
| 	} | ||||
|  | ||||
| 		// Loops over the specified positions and delete the corresponding chunks. | ||||
| 		for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) | ||||
| 		{ | ||||
| 			for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) | ||||
| 			{ | ||||
| 				for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++) | ||||
| 				{ | ||||
| 					m_mapChunks.erase(Vector3DInt32(x, y, z)); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	// Loops over the specified positions and delete the corresponding chunks. | ||||
| 	for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) | ||||
| 	{ | ||||
| 	for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) | ||||
| 	{ | ||||
| 	for(int32_t z = v3dStart.getZ(); z <= v3dEnd.getZ(); z++) | ||||
| 	{ | ||||
| 	m_mapChunks.erase(Vector3DInt32(x, y, z)); | ||||
| 	} | ||||
| 	} | ||||
| 	} | ||||
| 	}*/ | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -365,13 +365,13 @@ namespace PolyVox | ||||
| 				m_arrayChunks[uOldestChunkIndex] = nullptr; | ||||
| 			} | ||||
| 		} | ||||
| 				 | ||||
|  | ||||
| 		m_pLastAccessedChunk = pChunk; | ||||
| 		m_v3dLastAccessedChunkX = uChunkX; | ||||
| 		m_v3dLastAccessedChunkY = uChunkY; | ||||
| 		m_v3dLastAccessedChunkZ = uChunkZ; | ||||
|  | ||||
| 		return pChunk;	 | ||||
| 		return pChunk; | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
|   | ||||
| @@ -30,12 +30,12 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	PagedVolume<VoxelType>::Chunk::Chunk(Vector3DInt32 v3dPosition, uint16_t uSideLength, Pager* pPager) | ||||
| 		:m_uChunkLastAccessed(0) | ||||
| 		,m_bDataModified(true) | ||||
| 		,m_tData(0) | ||||
| 		,m_uSideLength(0) | ||||
| 		,m_uSideLengthPower(0) | ||||
| 		,m_pPager(pPager) | ||||
| 		,m_v3dChunkSpacePosition(v3dPosition) | ||||
| 		, m_bDataModified(true) | ||||
| 		, m_tData(0) | ||||
| 		, m_uSideLength(0) | ||||
| 		, m_uSideLengthPower(0) | ||||
| 		, m_pPager(pPager) | ||||
| 		, m_v3dChunkSpacePosition(v3dPosition) | ||||
| 	{ | ||||
| 		POLYVOX_ASSERT(m_pPager, "No valid pager supplied to chunk constructor."); | ||||
| 		POLYVOX_ASSERT(uSideLength <= 256, "Chunk side length cannot be greater than 256."); | ||||
| @@ -46,7 +46,7 @@ namespace PolyVox | ||||
|  | ||||
| 		// Allocate the data | ||||
| 		const uint32_t uNoOfVoxels = m_uSideLength * m_uSideLength * m_uSideLength; | ||||
| 		m_tData = new VoxelType[uNoOfVoxels];   | ||||
| 		m_tData = new VoxelType[uNoOfVoxels]; | ||||
|  | ||||
| 		// Pass the chunk to the Pager to give it a chance to initialise it with any data | ||||
| 		// From the coordinates of the chunk we deduce the coordinates of the contained voxels. | ||||
| @@ -134,9 +134,9 @@ namespace PolyVox | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	void PagedVolume<VoxelType>::Chunk::setVoxel(const Vector3DUint16& v3dPos, VoxelType tValue) | ||||
|     { | ||||
| 	{ | ||||
| 		setVoxel(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue); | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	uint32_t PagedVolume<VoxelType>::Chunk::calculateSizeInBytes(void) | ||||
| @@ -160,7 +160,7 @@ namespace PolyVox | ||||
| 	// then the ordering is automatically handled correctly.  | ||||
| 	template <typename VoxelType> | ||||
| 	void PagedVolume<VoxelType>::Chunk::changeLinearOrderingToMorton(void) | ||||
| 	{		 | ||||
| 	{ | ||||
| 		VoxelType* pTempBuffer = new VoxelType[m_uSideLength * m_uSideLength * m_uSideLength]; | ||||
|  | ||||
| 		// We should prehaps restructure this loop. From: https://fgiesen.wordpress.com/2011/01/17/texture-tiling-and-swizzling/ | ||||
|   | ||||
| @@ -107,7 +107,7 @@ namespace PolyVox | ||||
| 		BaseVolume<VoxelType>::template Sampler< PagedVolume<VoxelType> >::movePositiveX(); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(CAN_GO_POS_X(this->m_uXPosInChunk)) | ||||
| 		if (CAN_GO_POS_X(this->m_uXPosInChunk)) | ||||
| 		{ | ||||
| 			//No need to compute new chunk. | ||||
| 			mCurrentVoxel += POS_X_DELTA; | ||||
| @@ -227,7 +227,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -237,7 +237,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -247,7 +247,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + NEG_Y_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -257,7 +257,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -267,7 +267,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -277,7 +277,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -287,7 +287,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -297,7 +297,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -307,7 +307,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_X_DELTA + POS_Y_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| @@ -319,7 +319,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_Y_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -329,7 +329,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_Y_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -339,7 +339,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_Y_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -349,7 +349,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -365,7 +365,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -375,7 +375,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_Y_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -385,7 +385,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_Y_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -395,7 +395,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_Y_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| @@ -407,7 +407,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -417,7 +417,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -427,7 +427,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + NEG_Y_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -437,7 +437,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -447,7 +447,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -457,7 +457,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -467,7 +467,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA + NEG_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -477,7 +477,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| @@ -487,7 +487,7 @@ namespace PolyVox | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + POS_X_DELTA + POS_Y_DELTA + POS_Z_DELTA); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -39,7 +39,7 @@ namespace PolyVox | ||||
| 		Vector3DInt32 hitVoxel; ///< The location of the solid voxel it hit | ||||
| 		Vector3DInt32 previousVoxel; ///< The location of the voxel before the one it hit | ||||
| 	}; | ||||
| 	 | ||||
|  | ||||
| 	/// Pick the first solid voxel along a vector | ||||
| 	template<typename VolumeType> | ||||
| 	PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample); | ||||
|   | ||||
| @@ -26,13 +26,13 @@ | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
| 	namespace  | ||||
| 	namespace | ||||
| 	{ | ||||
| 		/** | ||||
| 		 * This is just an implementation class for the pickVoxel function | ||||
| 		 *  | ||||
| 		 * | ||||
| 		 * It makes note of the sort of empty voxel you're looking for in the constructor. | ||||
| 		 *  | ||||
| 		 * | ||||
| 		 * Each time the operator() is called: | ||||
| 		 *  * if it's hit a voxel it sets up the result and returns false | ||||
| 		 *  * otherwise it preps the result for the next iteration and returns true | ||||
| @@ -43,43 +43,43 @@ namespace PolyVox | ||||
| 		public: | ||||
| 			RaycastPickingFunctor(const typename VolumeType::VoxelType& emptyVoxelExample) | ||||
| 				:m_emptyVoxelExample(emptyVoxelExample) | ||||
| 				,m_result() | ||||
| 				, m_result() | ||||
| 			{ | ||||
| 			} | ||||
| 		 | ||||
|  | ||||
| 			bool operator()(const typename VolumeType::Sampler& sampler) | ||||
| 			{ | ||||
| 				if(sampler.getVoxel() != m_emptyVoxelExample) //If we've hit something | ||||
| 				if (sampler.getVoxel() != m_emptyVoxelExample) //If we've hit something | ||||
| 				{ | ||||
| 					m_result.didHit = true; | ||||
| 					m_result.hitVoxel = sampler.getPosition(); | ||||
| 					return false; | ||||
| 				} | ||||
| 				 | ||||
|  | ||||
| 				m_result.previousVoxel = sampler.getPosition(); | ||||
| 				 | ||||
|  | ||||
| 				return true; | ||||
| 			} | ||||
| 			const typename VolumeType::VoxelType& m_emptyVoxelExample; | ||||
| 			PickResult m_result; | ||||
| 		}; | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 * \param volData The volume to pass the ray though | ||||
| 	 * \param v3dStart The start position in the volume | ||||
| 	 * \param v3dDirectionAndLength The direction and length of the ray | ||||
| 	 * \param emptyVoxelExample The value used to represent empty voxels in your volume | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \return A PickResult containing the hit information | ||||
| 	 */ | ||||
| 	template<typename VolumeType> | ||||
| 	PickResult pickVoxel(VolumeType* volData, const Vector3DFloat& v3dStart, const Vector3DFloat& v3dDirectionAndLength, const typename VolumeType::VoxelType& emptyVoxelExample) | ||||
| 	{ | ||||
| 		RaycastPickingFunctor<VolumeType> functor(emptyVoxelExample); | ||||
| 		 | ||||
|  | ||||
| 		raycastWithDirection(volData, v3dStart, v3dDirectionAndLength, functor); | ||||
| 		 | ||||
|  | ||||
| 		return functor.m_result; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -40,7 +40,7 @@ namespace PolyVox | ||||
| 	class RawVolume : public BaseVolume<VoxelType> | ||||
| 	{ | ||||
| 	public: | ||||
| 		#ifndef SWIG | ||||
| #ifndef SWIG | ||||
| 		//There seems to be some descrepency between Visual Studio and GCC about how the following class should be declared. | ||||
| 		//There is a work around (see also See http://goo.gl/qu1wn) given below which appears to work on VS2010 and GCC, but | ||||
| 		//which seems to cause internal compiler errors on VS2008 when building with the /Gm 'Enable Minimal Rebuild' compiler | ||||
| @@ -51,7 +51,7 @@ namespace PolyVox | ||||
| #if defined(_MSC_VER) | ||||
| 		class Sampler : public BaseVolume<VoxelType>::Sampler< RawVolume<VoxelType> > //This line works on VS2010 | ||||
| #else | ||||
|                 class Sampler : public BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> > //This line works on GCC | ||||
| 		class Sampler : public BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> > //This line works on GCC | ||||
| #endif | ||||
| 		{ | ||||
| 		public: | ||||
| @@ -115,7 +115,7 @@ namespace PolyVox | ||||
| 			bool m_bIsCurrentPositionValidInY; | ||||
| 			bool m_bIsCurrentPositionValidInZ; | ||||
| 		}; | ||||
| 		#endif // SWIG | ||||
| #endif // SWIG | ||||
|  | ||||
| 	public: | ||||
| 		/// Constructor for creating a fixed size volume. | ||||
|   | ||||
| @@ -34,10 +34,10 @@ namespace PolyVox | ||||
| 		, m_regValidRegion(regValid) | ||||
| 		, m_tBorderValue() | ||||
| 	{ | ||||
| 		this->setBorderValue(VoxelType()); | ||||
| 			this->setBorderValue(VoxelType()); | ||||
|  | ||||
| 		//Create a volume of the right size. | ||||
| 		initialise(regValid); | ||||
| 			//Create a volume of the right size. | ||||
| 			initialise(regValid); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -145,11 +145,11 @@ namespace PolyVox | ||||
| 			int32_t iLocalZPos = uZPos - regValidRegion.getLowerZ(); | ||||
|  | ||||
| 			return m_pData | ||||
| 			[ | ||||
| 				iLocalXPos + | ||||
| 				iLocalYPos * this->getWidth() + | ||||
| 				iLocalZPos * this->getWidth() * this->getHeight() | ||||
| 			]; | ||||
| 				[ | ||||
| 					iLocalXPos + | ||||
| 					iLocalYPos * this->getWidth() + | ||||
| 					iLocalZPos * this->getWidth() * this->getHeight() | ||||
| 				]; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @@ -198,11 +198,11 @@ namespace PolyVox | ||||
| 		int32_t iLocalZPos = uZPos - v3dLowerCorner.getZ(); | ||||
|  | ||||
| 		m_pData | ||||
| 		[ | ||||
| 			iLocalXPos +  | ||||
| 			iLocalYPos * this->getWidth() +  | ||||
| 			iLocalZPos * this->getWidth() * this->getHeight() | ||||
| 		] = tValue; | ||||
| 			[ | ||||
| 				iLocalXPos + | ||||
| 				iLocalYPos * this->getWidth() + | ||||
| 				iLocalZPos * this->getWidth() * this->getHeight() | ||||
| 			] = tValue; | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -223,15 +223,15 @@ namespace PolyVox | ||||
| 	{ | ||||
| 		this->m_regValidRegion = regValidRegion; | ||||
|  | ||||
| 		if(this->getWidth() <= 0) | ||||
| 		if (this->getWidth() <= 0) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(std::invalid_argument, "Volume width must be greater than zero."); | ||||
| 		} | ||||
| 		if(this->getHeight() <= 0) | ||||
| 		if (this->getHeight() <= 0) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(std::invalid_argument, "Volume height must be greater than zero."); | ||||
| 		} | ||||
| 		if(this->getDepth() <= 0) | ||||
| 		if (this->getDepth() <= 0) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(std::invalid_argument, "Volume depth must be greater than zero."); | ||||
| 		} | ||||
|   | ||||
| @@ -34,7 +34,7 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	RawVolume<VoxelType>::Sampler::Sampler(RawVolume<VoxelType>* volume) | ||||
| 		:BaseVolume<VoxelType>::template Sampler< RawVolume<VoxelType> >(volume) | ||||
| 		,mCurrentVoxel(0) | ||||
| 		, mCurrentVoxel(0) | ||||
| 		, m_bIsCurrentPositionValidInX(false) | ||||
| 		, m_bIsCurrentPositionValidInY(false) | ||||
| 		, m_bIsCurrentPositionValidInZ(false) | ||||
| @@ -49,7 +49,7 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::getVoxel(void) const | ||||
| 	{ | ||||
| 		if(this->isCurrentPositionValid()) | ||||
| 		if (this->isCurrentPositionValid()) | ||||
| 		{ | ||||
| 			return *mCurrentVoxel; | ||||
| 		} | ||||
| @@ -82,16 +82,16 @@ namespace PolyVox | ||||
| 		m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(zPos); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(this->isCurrentPositionValid()) | ||||
| 		if (this->isCurrentPositionValid()) | ||||
| 		{ | ||||
| 			const Vector3DInt32& v3dLowerCorner = this->mVolume->m_regValidRegion.getLowerCorner(); | ||||
| 			int32_t iLocalXPos = xPos - v3dLowerCorner.getX(); | ||||
| 			int32_t iLocalYPos = yPos - v3dLowerCorner.getY(); | ||||
| 			int32_t iLocalZPos = zPos - v3dLowerCorner.getZ(); | ||||
|  | ||||
| 			const int32_t uVoxelIndex = iLocalXPos +  | ||||
| 					iLocalYPos * this->mVolume->getWidth() +  | ||||
| 					iLocalZPos * this->mVolume->getWidth() * this->mVolume->getHeight(); | ||||
| 			const int32_t uVoxelIndex = iLocalXPos + | ||||
| 				iLocalYPos * this->mVolume->getWidth() + | ||||
| 				iLocalZPos * this->mVolume->getWidth() * this->mVolume->getHeight(); | ||||
|  | ||||
| 			mCurrentVoxel = this->mVolume->m_pData + uVoxelIndex; | ||||
| 		} | ||||
| @@ -105,7 +105,7 @@ namespace PolyVox | ||||
| 	bool RawVolume<VoxelType>::Sampler::setVoxel(VoxelType tValue) | ||||
| 	{ | ||||
| 		//return m_bIsCurrentPositionValid ? *mCurrentVoxel : this->mVolume->getBorderValue(); | ||||
| 		if(this->m_bIsCurrentPositionValidInX && this->m_bIsCurrentPositionValidInY && this->m_bIsCurrentPositionValidInZ) | ||||
| 		if (this->m_bIsCurrentPositionValidInX && this->m_bIsCurrentPositionValidInY && this->m_bIsCurrentPositionValidInZ) | ||||
| 		{ | ||||
| 			*mCurrentVoxel = tValue; | ||||
| 			return true; | ||||
| @@ -128,7 +128,7 @@ namespace PolyVox | ||||
| 		m_bIsCurrentPositionValidInX = this->mVolume->getEnclosingRegion().containsPointInX(this->mXPosInVolume); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(this->isCurrentPositionValid() && bIsOldPositionValid ) | ||||
| 		if (this->isCurrentPositionValid() && bIsOldPositionValid) | ||||
| 		{ | ||||
| 			++mCurrentVoxel; | ||||
| 		} | ||||
| @@ -150,7 +150,7 @@ namespace PolyVox | ||||
| 		m_bIsCurrentPositionValidInY = this->mVolume->getEnclosingRegion().containsPointInY(this->mYPosInVolume); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(this->isCurrentPositionValid() && bIsOldPositionValid ) | ||||
| 		if (this->isCurrentPositionValid() && bIsOldPositionValid) | ||||
| 		{ | ||||
| 			mCurrentVoxel += this->mVolume->getWidth(); | ||||
| 		} | ||||
| @@ -172,7 +172,7 @@ namespace PolyVox | ||||
| 		m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(this->mZPosInVolume); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(this->isCurrentPositionValid() && bIsOldPositionValid ) | ||||
| 		if (this->isCurrentPositionValid() && bIsOldPositionValid) | ||||
| 		{ | ||||
| 			mCurrentVoxel += this->mVolume->getWidth() * this->mVolume->getHeight(); | ||||
| 		} | ||||
| @@ -194,7 +194,7 @@ namespace PolyVox | ||||
| 		m_bIsCurrentPositionValidInX = this->mVolume->getEnclosingRegion().containsPointInX(this->mXPosInVolume); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(this->isCurrentPositionValid() && bIsOldPositionValid ) | ||||
| 		if (this->isCurrentPositionValid() && bIsOldPositionValid) | ||||
| 		{ | ||||
| 			--mCurrentVoxel; | ||||
| 		} | ||||
| @@ -216,7 +216,7 @@ namespace PolyVox | ||||
| 		m_bIsCurrentPositionValidInY = this->mVolume->getEnclosingRegion().containsPointInY(this->mYPosInVolume); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(this->isCurrentPositionValid() && bIsOldPositionValid ) | ||||
| 		if (this->isCurrentPositionValid() && bIsOldPositionValid) | ||||
| 		{ | ||||
| 			mCurrentVoxel -= this->mVolume->getWidth(); | ||||
| 		} | ||||
| @@ -238,7 +238,7 @@ namespace PolyVox | ||||
| 		m_bIsCurrentPositionValidInZ = this->mVolume->getEnclosingRegion().containsPointInZ(this->mZPosInVolume); | ||||
|  | ||||
| 		// Then we update the voxel pointer | ||||
| 		if(this->isCurrentPositionValid() && bIsOldPositionValid ) | ||||
| 		if (this->isCurrentPositionValid() && bIsOldPositionValid) | ||||
| 		{ | ||||
| 			mCurrentVoxel -= this->mVolume->getWidth() * this->mVolume->getHeight(); | ||||
| 		} | ||||
| @@ -251,91 +251,91 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 - this->mVolume->getWidth()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1ny1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume-1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx0py1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 + this->mVolume->getWidth()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1nx1py1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume-1,this->mYPosInVolume+1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume - 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| @@ -343,47 +343,47 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - this->mVolume->getWidth()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1ny1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume-1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume - 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid())) | ||||
| 		if ((this->isCurrentPositionValid())) | ||||
| 		{ | ||||
| 			return *mCurrentVoxel; | ||||
| 		} | ||||
| @@ -393,41 +393,41 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px0py1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + this->mVolume->getWidth()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel0px1py1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume,this->mYPosInVolume+1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume, this->mYPosInVolume + 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| @@ -435,91 +435,91 @@ namespace PolyVox | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 - this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 - this->mVolume->getWidth()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1ny1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 - this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume-1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume - 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px0py1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume, this->mZPosInVolume + 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py1nz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_NEG_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 + this->mVolume->getWidth() - this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume-1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume - 1); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py0pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 + this->mVolume->getWidth()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume); | ||||
| 	} | ||||
|  | ||||
| 	template <typename VoxelType> | ||||
| 	VoxelType RawVolume<VoxelType>::Sampler::peekVoxel1px1py1pz(void) const | ||||
| 	{ | ||||
| 		if((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume) ) | ||||
| 		if ((this->isCurrentPositionValid()) && CAN_GO_POS_X(this->mXPosInVolume) && CAN_GO_POS_Y(this->mYPosInVolume) && CAN_GO_POS_Z(this->mZPosInVolume)) | ||||
| 		{ | ||||
| 			return *(mCurrentVoxel + 1 + this->mVolume->getWidth() + this->mVolume->getWidth() * this->mVolume->getHeight()); | ||||
| 		} | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume+1,this->mYPosInVolume+1,this->mZPosInVolume+1); | ||||
| 		return this->mVolume->getVoxel(this->mXPosInVolume + 1, this->mYPosInVolume + 1, this->mZPosInVolume + 1); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -53,20 +53,20 @@ namespace PolyVox | ||||
| 	//  It should simply read "if (ty <= tz)". | ||||
| 	// | ||||
| 	//	This error was reported by Joey Hammer (PixelActive). | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 * Cast a ray through a volume by specifying the start and end positions | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * The ray will move from \a v3dStart to \a v3dEnd, calling \a callback for each | ||||
| 	 * voxel it passes through until \a callback returns \a false. In this case it | ||||
| 	 * returns a RaycastResults::Interupted. If it passes from start to end | ||||
| 	 * without \a callback returning \a false, it returns RaycastResults::Completed. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \param volData The volume to pass the ray though | ||||
| 	 * \param v3dStart The start position in the volume | ||||
| 	 * \param v3dEnd The end position in the volume | ||||
| 	 * \param callback The callback to call for each voxel | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \return A RaycastResults designating whether the ray hit anything or not | ||||
| 	 */ | ||||
| 	template<typename VolumeType, typename Callback> | ||||
| @@ -83,7 +83,7 @@ namespace PolyVox | ||||
| 		const float x2 = v3dEnd.getX() + 0.5f; | ||||
| 		const float y2 = v3dEnd.getY() + 0.5f; | ||||
| 		const float z2 = v3dEnd.getZ() + 0.5f; | ||||
| 		 | ||||
|  | ||||
| 		int i = (int)floorf(x1); | ||||
| 		int j = (int)floorf(y1); | ||||
| 		int k = (int)floorf(z1); | ||||
| @@ -107,39 +107,41 @@ namespace PolyVox | ||||
| 		const float minz = floorf(z1), maxz = minz + 1.0f; | ||||
| 		float tz = ((z1 > z2) ? (z1 - minz) : (maxz - z1)) * deltatz; | ||||
|  | ||||
| 		sampler.setPosition(i,j,k); | ||||
| 		sampler.setPosition(i, j, k); | ||||
|  | ||||
| 		for(;;) | ||||
| 		for (;;) | ||||
| 		{ | ||||
| 			if(!callback(sampler)) | ||||
| 			if (!callback(sampler)) | ||||
| 			{ | ||||
| 				return RaycastResults::Interupted; | ||||
| 			} | ||||
|  | ||||
| 			if(tx <= ty && tx <= tz) | ||||
| 			if (tx <= ty && tx <= tz) | ||||
| 			{ | ||||
| 				if(i == iend) break; | ||||
| 				if (i == iend) break; | ||||
| 				tx += deltatx; | ||||
| 				i += di; | ||||
|  | ||||
| 				if(di == 1) sampler.movePositiveX(); | ||||
| 				if(di == -1) sampler.moveNegativeX(); | ||||
| 			} else if (ty <= tz) | ||||
| 				if (di == 1) sampler.movePositiveX(); | ||||
| 				if (di == -1) sampler.moveNegativeX(); | ||||
| 			} | ||||
| 			else if (ty <= tz) | ||||
| 			{ | ||||
| 				if(j == jend) break; | ||||
| 				if (j == jend) break; | ||||
| 				ty += deltaty; | ||||
| 				j += dj; | ||||
|  | ||||
| 				if(dj == 1) sampler.movePositiveY(); | ||||
| 				if(dj == -1) sampler.moveNegativeY(); | ||||
| 			} else  | ||||
| 				if (dj == 1) sampler.movePositiveY(); | ||||
| 				if (dj == -1) sampler.moveNegativeY(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if(k == kend) break; | ||||
| 				if (k == kend) break; | ||||
| 				tz += deltatz; | ||||
| 				k += dk; | ||||
|  | ||||
| 				if(dk == 1) sampler.movePositiveZ(); | ||||
| 				if(dk == -1) sampler.moveNegativeZ(); | ||||
| 				if (dk == 1) sampler.movePositiveZ(); | ||||
| 				if (dk == -1) sampler.moveNegativeZ(); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -148,13 +150,13 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * Cast a ray through a volume by specifying the start and a direction | ||||
| 	 *  | ||||
| 	 * The ray will move from \a v3dStart along \a v3dDirectionAndLength, calling  | ||||
| 	 * \a callback for each voxel it passes through until \a callback returns  | ||||
| 	 * \a false. In this case it returns a RaycastResults::Interupted. If it  | ||||
| 	 * passes from start to end without \a callback returning \a false, it  | ||||
| 	 * | ||||
| 	 * The ray will move from \a v3dStart along \a v3dDirectionAndLength, calling | ||||
| 	 * \a callback for each voxel it passes through until \a callback returns | ||||
| 	 * \a false. In this case it returns a RaycastResults::Interupted. If it | ||||
| 	 * passes from start to end without \a callback returning \a false, it | ||||
| 	 * returns RaycastResults::Completed. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \note 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 | ||||
| @@ -162,12 +164,12 @@ namespace PolyVox | ||||
| 	 * 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. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \param volData The volume to pass the ray though | ||||
| 	 * \param v3dStart The start position in the volume | ||||
| 	 * \param v3dDirectionAndLength The direction and length of the ray | ||||
| 	 * \param callback The callback to call for each voxel | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \return A RaycastResults designating whether the ray hit anything or not | ||||
| 	 */ | ||||
| 	template<typename VolumeType, typename Callback> | ||||
|   | ||||
| @@ -32,23 +32,23 @@ | ||||
| namespace PolyVox | ||||
| { | ||||
| 	/** Represents a part of a Volume. | ||||
| 	 *  | ||||
| 	 *  Many operations in PolyVox are constrained to only part of a volume. For example, when running the surface extractors  | ||||
| 	 *  it is unlikely that you will want to run it on the whole volume at once, as this will give a very large mesh which may  | ||||
| 	 *  be too much to render. Instead you will probably want to run a surface extractor a number of times on different parts  | ||||
| 	 * | ||||
| 	 *  Many operations in PolyVox are constrained to only part of a volume. For example, when running the surface extractors | ||||
| 	 *  it is unlikely that you will want to run it on the whole volume at once, as this will give a very large mesh which may | ||||
| 	 *  be too much to render. Instead you will probably want to run a surface extractor a number of times on different parts | ||||
| 	 *  of the volume, there by giving a number of meshes which can be culled and rendered seperately. | ||||
| 	 *  | ||||
| 	 *  The Region class is used to define these parts (regions) of the volume. Essentially it consists of an upper and lower  | ||||
| 	 *  bound which specify the range of voxels positions considered to be part of the region. Note that these bounds are  | ||||
| 	 * | ||||
| 	 *  The Region class is used to define these parts (regions) of the volume. Essentially it consists of an upper and lower | ||||
| 	 *  bound which specify the range of voxels positions considered to be part of the region. Note that these bounds are | ||||
| 	 *  <em>inclusive</em>. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 *  As well as the expected set of getters and setters, this class also provide utility functions for increasing and decresing | ||||
| 	 *  the size of the Region, shifting the Region in 3D space, testing whether it contains a given position, enlarging it so that | ||||
| 	 *  it does contain a given position, croppng it to another Region, and various other utility functions. | ||||
| 	 *  | ||||
| 	 *  \Note The dimensions of a region can be measured either in voxels or in cells. See the manual for more information  | ||||
| 	 * | ||||
| 	 *  \Note The dimensions of a region can be measured either in voxels or in cells. See the manual for more information | ||||
| 	 *  about these definitions. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 */ | ||||
| 	class Region | ||||
| 	{ | ||||
| @@ -67,9 +67,9 @@ namespace PolyVox | ||||
| 		Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ); | ||||
|  | ||||
| 		/// Equality Operator. | ||||
|         bool operator==(const Region& rhs) const; | ||||
| 		bool operator==(const Region& rhs) const; | ||||
| 		/// Inequality Operator. | ||||
|         bool operator!=(const Region& rhs) const; | ||||
| 		bool operator!=(const Region& rhs) const; | ||||
|  | ||||
| 		/// Gets the 'x' position of the centre. | ||||
| 		int32_t getCentreX(void) const; | ||||
| @@ -189,7 +189,7 @@ namespace PolyVox | ||||
| 		/// Moves the upper corner of the Region by the amount specified. | ||||
| 		void shiftUpperCorner(int32_t iAmountX, int32_t iAmountY, int32_t iAmountZ); | ||||
| 		/// Moves the upper corner of the Region by the amount specified. | ||||
| 		void shiftUpperCorner(const Vector3DInt32& v3dAmount);		 | ||||
| 		void shiftUpperCorner(const Vector3DInt32& v3dAmount); | ||||
|  | ||||
| 		/// Shrinks this region by the amount specified. | ||||
| 		void shrink(int32_t iAmount); | ||||
|   | ||||
| @@ -80,10 +80,10 @@ namespace PolyVox | ||||
| 	 */ | ||||
| 	inline void Region::accumulate(const Region& reg) | ||||
| 	{ | ||||
| 		if(!reg.isValid()) | ||||
| 		if (!reg.isValid()) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(invalid_operation, "You cannot accumulate an invalid region."); //The result of accumulating an invalid region is not defined. | ||||
| 		}  | ||||
| 		} | ||||
|  | ||||
| 		m_iLowerX = ((std::min)(m_iLowerX, reg.getLowerX())); | ||||
| 		m_iLowerY = ((std::min)(m_iLowerY, reg.getLowerY())); | ||||
| @@ -98,11 +98,11 @@ namespace PolyVox | ||||
| 	 */ | ||||
| 	inline Region::Region() | ||||
| 		:m_iLowerX(0) | ||||
| 		,m_iLowerY(0) | ||||
| 		,m_iLowerZ(0) | ||||
| 		,m_iUpperX(0) | ||||
| 		,m_iUpperY(0) | ||||
| 		,m_iUpperZ(0) | ||||
| 		, m_iLowerY(0) | ||||
| 		, m_iLowerZ(0) | ||||
| 		, m_iUpperX(0) | ||||
| 		, m_iUpperY(0) | ||||
| 		, m_iUpperZ(0) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| @@ -113,11 +113,11 @@ namespace PolyVox | ||||
| 	 */ | ||||
| 	inline Region::Region(const Vector3DInt32& v3dLowerCorner, const Vector3DInt32& v3dUpperCorner) | ||||
| 		:m_iLowerX(v3dLowerCorner.getX()) | ||||
| 		,m_iLowerY(v3dLowerCorner.getY()) | ||||
| 		,m_iLowerZ(v3dLowerCorner.getZ()) | ||||
| 		,m_iUpperX(v3dUpperCorner.getX()) | ||||
| 		,m_iUpperY(v3dUpperCorner.getY()) | ||||
| 		,m_iUpperZ(v3dUpperCorner.getZ()) | ||||
| 		, m_iLowerY(v3dLowerCorner.getY()) | ||||
| 		, m_iLowerZ(v3dLowerCorner.getZ()) | ||||
| 		, m_iUpperX(v3dUpperCorner.getX()) | ||||
| 		, m_iUpperY(v3dUpperCorner.getY()) | ||||
| 		, m_iUpperZ(v3dUpperCorner.getZ()) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| @@ -132,11 +132,11 @@ namespace PolyVox | ||||
| 	 */ | ||||
| 	inline Region::Region(int32_t iLowerX, int32_t iLowerY, int32_t iLowerZ, int32_t iUpperX, int32_t iUpperY, int32_t iUpperZ) | ||||
| 		:m_iLowerX(iLowerX) | ||||
| 		,m_iLowerY(iLowerY) | ||||
| 		,m_iLowerZ(iLowerZ) | ||||
| 		,m_iUpperX(iUpperX) | ||||
| 		,m_iUpperY(iUpperY) | ||||
| 		,m_iUpperZ(iUpperZ) | ||||
| 		, m_iLowerY(iLowerY) | ||||
| 		, m_iLowerZ(iLowerZ) | ||||
| 		, m_iUpperX(iUpperX) | ||||
| 		, m_iUpperY(iUpperY) | ||||
| 		, m_iUpperZ(iUpperZ) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| @@ -147,25 +147,25 @@ namespace PolyVox | ||||
| 	 * \sa operator!= | ||||
| 	 */ | ||||
| 	inline bool Region::operator==(const Region& rhs) const | ||||
|     { | ||||
| 	{ | ||||
| 		return ((m_iLowerX == rhs.m_iLowerX) && (m_iLowerY == rhs.m_iLowerY) && (m_iLowerZ == rhs.m_iLowerZ) | ||||
| 			&&  (m_iUpperX == rhs.m_iUpperX) && (m_iUpperY == rhs.m_iUpperY) && (m_iUpperZ == rhs.m_iUpperZ)); | ||||
|     } | ||||
| 			&& (m_iUpperX == rhs.m_iUpperX) && (m_iUpperY == rhs.m_iUpperY) && (m_iUpperZ == rhs.m_iUpperZ)); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 *  Two regions are considered different if any of their extents differ. | ||||
| 	 *  \param rhs The Region to compare to. | ||||
|      *  \return true if the Regions are different. | ||||
|      *  \sa operator== | ||||
| 	 *  \return true if the Regions are different. | ||||
| 	 *  \sa operator== | ||||
| 	 */ | ||||
| 	inline bool Region::operator!=(const Region& rhs) const | ||||
|     { | ||||
| 	{ | ||||
| 		return !(*this == rhs); | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 *  The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 *  the Region if it is that far in in all directions. Also, the test is inclusive such  | ||||
| 	 *  the Region if it is that far in in all directions. Also, the test is inclusive such | ||||
| 	 *  that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 *  \param fX The 'x' position of the point to test. | ||||
| 	 *  \param fY The 'y' position of the point to test. | ||||
| @@ -184,7 +184,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in all directions. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in all directions. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| @@ -196,7 +196,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 *  The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 *  the Region if it is that far in in all directions. Also, the test is inclusive such  | ||||
| 	 *  the Region if it is that far in in all directions. Also, the test is inclusive such | ||||
| 	 *  that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 *  \param iX The 'x' position of the point to test. | ||||
| 	 *  \param iY The 'y' position of the point to test. | ||||
| @@ -206,7 +206,7 @@ namespace PolyVox | ||||
| 	inline bool Region::containsPoint(int32_t iX, int32_t iY, int32_t iZ, uint8_t boundary) const | ||||
| 	{ | ||||
| 		return (iX <= m_iUpperX - boundary) | ||||
| 			&& (iY <= m_iUpperY - boundary)  | ||||
| 			&& (iY <= m_iUpperY - boundary) | ||||
| 			&& (iZ <= m_iUpperZ - boundary) | ||||
| 			&& (iX >= m_iLowerX + boundary) | ||||
| 			&& (iY >= m_iLowerY + boundary) | ||||
| @@ -215,7 +215,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in all directions. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in all directions. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| @@ -227,7 +227,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in the 'x' direction. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in the 'x' direction. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| @@ -240,7 +240,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in the 'x' direction. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in the 'x' direction. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| @@ -253,7 +253,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in the 'y' direction. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in the 'y' direction. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| @@ -266,20 +266,20 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in the 'y' direction. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in the 'y' direction. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| 	 */ | ||||
| 	inline bool Region::containsPointInY(int32_t pos, uint8_t boundary) const | ||||
| 	{ | ||||
| 		return (pos <= m_iUpperY - boundary)  | ||||
| 		return (pos <= m_iUpperY - boundary) | ||||
| 			&& (pos >= m_iLowerY + boundary); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in the 'z' direction. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in the 'z' direction. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| @@ -292,7 +292,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 * The boundary value can be used to ensure a position is only considered to be inside | ||||
| 	 * the Region if it is that far in in the 'z' direction. Also, the test is inclusive such  | ||||
| 	 * the Region if it is that far in in the 'z' direction. Also, the test is inclusive such | ||||
| 	 * that positions lying exactly on the edge of the Region are considered to be inside it. | ||||
| 	 * \param pos The position to test. | ||||
| 	 * \param boundary The desired boundary value. | ||||
| @@ -305,7 +305,7 @@ namespace PolyVox | ||||
|  | ||||
| 	/** | ||||
| 	 *  The boundary value can be used to ensure a region is only considered to be inside | ||||
| 	 *  another Region if it is that far in in all directions. Also, the test is inclusive such  | ||||
| 	 *  another Region if it is that far in in all directions. Also, the test is inclusive such | ||||
| 	 *  that a region is considered to be inside of itself. | ||||
| 	 *  \param reg The region to test. | ||||
| 	 *  \param boundary The desired boundary value. | ||||
| @@ -313,7 +313,7 @@ namespace PolyVox | ||||
| 	inline bool Region::containsRegion(const Region& reg, uint8_t boundary) const | ||||
| 	{ | ||||
| 		return (reg.m_iUpperX <= m_iUpperX - boundary) | ||||
| 			&& (reg.m_iUpperY <= m_iUpperY - boundary)  | ||||
| 			&& (reg.m_iUpperY <= m_iUpperY - boundary) | ||||
| 			&& (reg.m_iUpperZ <= m_iUpperZ - boundary) | ||||
| 			&& (reg.m_iLowerX >= m_iLowerX + boundary) | ||||
| 			&& (reg.m_iLowerY >= m_iLowerY + boundary) | ||||
| @@ -496,24 +496,24 @@ namespace PolyVox | ||||
| 	inline bool intersects(const Region& a, const Region& b) | ||||
| 	{ | ||||
| 		// No intersection if seperated along an axis. | ||||
| 		if(a.getUpperX() < b.getLowerX() || a.getLowerX() > b.getUpperX()) return false; | ||||
| 		if(a.getUpperY() < b.getLowerY() || a.getLowerY() > b.getUpperY()) return false; | ||||
| 		if(a.getUpperZ() < b.getLowerZ() || a.getLowerZ() > b.getUpperZ()) return false; | ||||
| 		if (a.getUpperX() < b.getLowerX() || a.getLowerX() > b.getUpperX()) return false; | ||||
| 		if (a.getUpperY() < b.getLowerY() || a.getLowerY() > b.getUpperY()) return false; | ||||
| 		if (a.getUpperZ() < b.getLowerZ() || a.getLowerZ() > b.getUpperZ()) return false; | ||||
|  | ||||
| 		// Overlapping on all axes means Regions are intersecting. | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Enables the Region to be used intuitively with output streams such as cout. | ||||
|      * \param os The output stream to write to. | ||||
|      * \param region The Region to write to the stream. | ||||
|      * \return A reference to the output stream to allow chaining. | ||||
|      */ | ||||
| 	 * Enables the Region to be used intuitively with output streams such as cout. | ||||
| 	 * \param os The output stream to write to. | ||||
| 	 * \param region The Region to write to the stream. | ||||
| 	 * \return A reference to the output stream to allow chaining. | ||||
| 	 */ | ||||
| 	inline std::ostream& operator<<(std::ostream& os, const Region& region) | ||||
|     { | ||||
| 	{ | ||||
| 		os << "(" << region.getLowerX() << "," << region.getLowerY() << "," << region.getLowerZ() << | ||||
| 			") to (" << region.getUpperX() << "," << region.getUpperY() << "," << region.getUpperZ() << ")"; | ||||
|         return os; | ||||
|     } | ||||
| 		return os; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -39,7 +39,7 @@ namespace PolyVox | ||||
| { | ||||
| 	/** | ||||
| 	 * Represents a vector in space. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * This is a generl purpose vector class designed to represent both positions and directions. It is templatised | ||||
| 	 * on both size and data type but note that some of the operations do not make sense with integer types. For | ||||
| 	 * example it does not make conceptual sense to try and normalise an integer Vector. | ||||
| @@ -48,7 +48,7 @@ namespace PolyVox | ||||
| 	 * X, Y, Z and W elements. Note that W is last even though it comes before X in the alphabet. These elements can | ||||
| 	 * be accessed through getX(), setX(), getY(), setY(), getZ(), setZ(), getW() and setW(), while other elements | ||||
| 	 * can be accessed through getElemen() and setElement(). | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * This class includes a number of common mathematical operations (addition, subtraction, etc) as well as vector | ||||
| 	 * specific operations such as the dot and cross products. Note that this class is also templatised on an | ||||
| 	 * OperationType which is used for many internal calculations and some results. For example, the square of a | ||||
| @@ -58,66 +58,66 @@ namespace PolyVox | ||||
| 	 * | ||||
| 	 * Typedefs are provided for 2, 3 and 4 dimensional vector with int8_t, uint8_t, int16_t, uint6_t, int32_t, | ||||
| 	 * uint32_t, float and double types. These typedefs are used as follows: | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \code | ||||
| 	 * Vector2DInt32 test(1,2); //Declares a 2 dimensional Vector of type int32_t. | ||||
| 	 * \endcode | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType = StorageType> | ||||
| 	class Vector | ||||
|     { | ||||
|     public: | ||||
| 	{ | ||||
| 	public: | ||||
| 		/// Constructor | ||||
| 		Vector(void); | ||||
| 		/// Constructor. | ||||
|         Vector(StorageType tFillValue); | ||||
|         /// Constructor. | ||||
|         Vector(StorageType x, StorageType y); | ||||
| 		Vector(StorageType tFillValue); | ||||
| 		/// Constructor. | ||||
| 		Vector(StorageType x, StorageType y); | ||||
| 		/// Constructor. | ||||
| 		Vector(StorageType x, StorageType y, StorageType z); | ||||
| 		/// Constructor. | ||||
| 		Vector(StorageType x, StorageType y, StorageType z, StorageType w); | ||||
|         /// Copy Constructor. | ||||
|         Vector(const Vector<Size,StorageType,OperationType>& vector); | ||||
| 		/// Copy Constructor. | ||||
| 		Vector(const Vector<Size, StorageType, OperationType>& vector); | ||||
| 		/// Copy Constructor which performs casting. | ||||
| 		template <typename CastType> explicit Vector(const Vector<Size,CastType>& vector); | ||||
|         /// Destructor. | ||||
|         ~Vector(void); | ||||
| 		template <typename CastType> explicit Vector(const Vector<Size, CastType>& vector); | ||||
| 		/// Destructor. | ||||
| 		~Vector(void); | ||||
|  | ||||
|         /// Assignment Operator. | ||||
|         Vector<Size,StorageType,OperationType>& operator=(const Vector<Size,StorageType,OperationType>& rhs); | ||||
|         /// Equality Operator. | ||||
|         bool operator==(const Vector<Size,StorageType,OperationType>& rhs) const; | ||||
| 		/// Assignment Operator. | ||||
| 		Vector<Size, StorageType, OperationType>& operator=(const Vector<Size, StorageType, OperationType>& rhs); | ||||
| 		/// Equality Operator. | ||||
| 		bool operator==(const Vector<Size, StorageType, OperationType>& rhs) const; | ||||
| 		/// Inequality Operator. | ||||
|         bool operator!=(const Vector<Size,StorageType,OperationType>& rhs) const; | ||||
|         /// Addition and Assignment Operator. | ||||
|         Vector<Size,StorageType,OperationType>& operator+=(const Vector<Size,StorageType,OperationType> &rhs); | ||||
|         /// Subtraction and Assignment Operator. | ||||
|         Vector<Size,StorageType,OperationType>& operator-=(const Vector<Size,StorageType,OperationType> &rhs); | ||||
| 		bool operator!=(const Vector<Size, StorageType, OperationType>& rhs) const; | ||||
| 		/// Addition and Assignment Operator. | ||||
| 		Vector<Size, StorageType, OperationType>& operator+=(const Vector<Size, StorageType, OperationType> &rhs); | ||||
| 		/// Subtraction and Assignment Operator. | ||||
| 		Vector<Size, StorageType, OperationType>& operator-=(const Vector<Size, StorageType, OperationType> &rhs); | ||||
| 		/// Multiplication and Assignment Operator. | ||||
|         Vector<Size,StorageType,OperationType>& operator*=(const Vector<Size,StorageType,OperationType> &rhs); | ||||
|         /// Division and Assignment Operator. | ||||
|         Vector<Size,StorageType,OperationType>& operator/=(const Vector<Size,StorageType,OperationType> &rhs); | ||||
|         /// Multiplication and Assignment Operator. | ||||
|         Vector<Size,StorageType,OperationType>& operator*=(const StorageType& rhs); | ||||
|         /// Division and Assignment Operator. | ||||
|         Vector<Size,StorageType,OperationType>& operator/=(const StorageType& rhs); | ||||
| 		Vector<Size, StorageType, OperationType>& operator*=(const Vector<Size, StorageType, OperationType> &rhs); | ||||
| 		/// Division and Assignment Operator. | ||||
| 		Vector<Size, StorageType, OperationType>& operator/=(const Vector<Size, StorageType, OperationType> &rhs); | ||||
| 		/// Multiplication and Assignment Operator. | ||||
| 		Vector<Size, StorageType, OperationType>& operator*=(const StorageType& rhs); | ||||
| 		/// Division and Assignment Operator. | ||||
| 		Vector<Size, StorageType, OperationType>& operator/=(const StorageType& rhs); | ||||
|  | ||||
| 		/// Element Access. | ||||
| 		StorageType getElement(uint32_t index) const; | ||||
|         /// Get the x component of the vector. | ||||
|         StorageType getX(void) const;         | ||||
|         /// Get the y component of the vector. | ||||
|         StorageType getY(void) const;         | ||||
|         /// Get the z component of the vector. | ||||
|         StorageType getZ(void) const;         | ||||
| 		/// Get the x component of the vector. | ||||
| 		StorageType getX(void) const; | ||||
| 		/// Get the y component of the vector. | ||||
| 		StorageType getY(void) const; | ||||
| 		/// Get the z component of the vector. | ||||
| 		StorageType getZ(void) const; | ||||
| 		/// Get the w component of the vector. | ||||
| 		StorageType getW(void) const;		 | ||||
| 		StorageType getW(void) const; | ||||
|  | ||||
| 		/// Element Access. | ||||
| 		void setElement(uint32_t index, StorageType tValue); | ||||
| 		/// Element Access. | ||||
|         void setElements(StorageType x, StorageType y); | ||||
| 		void setElements(StorageType x, StorageType y); | ||||
| 		/// Element Access. | ||||
| 		void setElements(StorageType x, StorageType y, StorageType z); | ||||
| 		/// Element Access. | ||||
| @@ -131,99 +131,99 @@ namespace PolyVox | ||||
| 		/// Set the w component of the vector. | ||||
| 		void setW(StorageType tW); | ||||
|  | ||||
|         /// Get the length of the vector. | ||||
|         float length(void) const; | ||||
|         /// Get the squared length of the vector. | ||||
|         OperationType lengthSquared(void) const; | ||||
|         /// Find the angle between this vector and that which is passed as a parameter. | ||||
|         float angleTo(const Vector<Size,StorageType,OperationType>& vector) const; | ||||
|         /// Find the cross product between this vector and the vector passed as a parameter. | ||||
|         Vector<Size,StorageType,OperationType> cross(const Vector<Size,StorageType,OperationType>& vector) const; | ||||
|         /// Find the dot product between this vector and the vector passed as a parameter. | ||||
|         OperationType dot(const Vector<Size,StorageType,OperationType>& rhs) const; | ||||
|         /// Normalise the vector. | ||||
|         void normalise(void); | ||||
| 		/// Get the length of the vector. | ||||
| 		float length(void) const; | ||||
| 		/// Get the squared length of the vector. | ||||
| 		OperationType lengthSquared(void) const; | ||||
| 		/// Find the angle between this vector and that which is passed as a parameter. | ||||
| 		float angleTo(const Vector<Size, StorageType, OperationType>& vector) const; | ||||
| 		/// Find the cross product between this vector and the vector passed as a parameter. | ||||
| 		Vector<Size, StorageType, OperationType> cross(const Vector<Size, StorageType, OperationType>& vector) const; | ||||
| 		/// Find the dot product between this vector and the vector passed as a parameter. | ||||
| 		OperationType dot(const Vector<Size, StorageType, OperationType>& rhs) const; | ||||
| 		/// Normalise the vector. | ||||
| 		void normalise(void); | ||||
|  | ||||
|     private: | ||||
|         // Values for the vector | ||||
| 	private: | ||||
| 		// Values for the vector | ||||
| 		StorageType m_tElements[Size]; | ||||
|     }; | ||||
| 	}; | ||||
|  | ||||
|     // Non-member overloaded operators.  | ||||
| 	// Non-member overloaded operators.  | ||||
| 	/// Addition operator. | ||||
| 	template <uint32_t Size,typename StorageType,typename OperationType> | ||||
| 	    Vector<Size,StorageType,OperationType> operator+(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator+(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs); | ||||
| 	/// Subtraction operator. | ||||
| 	template <uint32_t Size,typename StorageType,typename OperationType> | ||||
| 	    Vector<Size,StorageType,OperationType> operator-(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator-(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs); | ||||
| 	/// Multiplication operator. | ||||
| 	template <uint32_t Size,typename StorageType,typename OperationType> | ||||
| 	    Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs); | ||||
| 	/// Division operator. | ||||
| 	template <uint32_t Size,typename StorageType,typename OperationType> | ||||
| 	    Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs); | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs); | ||||
| 	/// Multiplication operator. | ||||
| 	template <uint32_t Size,typename StorageType,typename OperationType> | ||||
| 	    Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs); | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs); | ||||
| 	/// Division operator. | ||||
| 	template <uint32_t Size,typename StorageType,typename OperationType> | ||||
| 	    Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs); | ||||
|     /// Stream insertion operator. | ||||
|     template <uint32_t Size, typename StorageType,typename OperationType> | ||||
|         std::ostream& operator<<(std::ostream& os, const Vector<Size,StorageType,OperationType>& vector); | ||||
| 		 | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs); | ||||
| 	/// Stream insertion operator. | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	std::ostream& operator<<(std::ostream& os, const Vector<Size, StorageType, OperationType>& vector); | ||||
|  | ||||
| 	//Some handy typedefs | ||||
|  | ||||
| 	/// A 2D Vector of floats. | ||||
| 	typedef Vector<2,float,float> Vector2DFloat; | ||||
| 	typedef Vector<2, float, float> Vector2DFloat; | ||||
| 	/// A 2D Vector of doubles. | ||||
|     typedef Vector<2,double,double> Vector2DDouble; | ||||
| 	typedef Vector<2, double, double> Vector2DDouble; | ||||
| 	/// A 2D Vector of signed 8-bit values. | ||||
| 	typedef Vector<2,int8_t,int32_t> Vector2DInt8; | ||||
| 	typedef Vector<2, int8_t, int32_t> Vector2DInt8; | ||||
| 	/// A 2D Vector of unsigned 8-bit values. | ||||
| 	typedef Vector<2,uint8_t,int32_t> Vector2DUint8; | ||||
| 	typedef Vector<2, uint8_t, int32_t> Vector2DUint8; | ||||
| 	/// A 2D Vector of signed 16-bit values. | ||||
| 	typedef Vector<2,int16_t,int32_t> Vector2DInt16; | ||||
| 	typedef Vector<2, int16_t, int32_t> Vector2DInt16; | ||||
| 	/// A 2D Vector of unsigned 16-bit values. | ||||
| 	typedef Vector<2,uint16_t,int32_t> Vector2DUint16; | ||||
| 	typedef Vector<2, uint16_t, int32_t> Vector2DUint16; | ||||
| 	/// A 2D Vector of signed 32-bit values. | ||||
| 	typedef Vector<2,int32_t,int32_t> Vector2DInt32; | ||||
| 	typedef Vector<2, int32_t, int32_t> Vector2DInt32; | ||||
| 	/// A 2D Vector of unsigned 32-bit values. | ||||
| 	typedef Vector<2,uint32_t,int32_t> Vector2DUint32; | ||||
| 	typedef Vector<2, uint32_t, int32_t> Vector2DUint32; | ||||
|  | ||||
| 	/// A 3D Vector of floats. | ||||
| 	typedef Vector<3,float,float> Vector3DFloat; | ||||
| 	typedef Vector<3, float, float> Vector3DFloat; | ||||
| 	/// A 3D Vector of doubles. | ||||
|     typedef Vector<3,double,double> Vector3DDouble; | ||||
| 	typedef Vector<3, double, double> Vector3DDouble; | ||||
| 	/// A 3D Vector of signed 8-bit values. | ||||
| 	typedef Vector<3,int8_t,int32_t> Vector3DInt8; | ||||
| 	typedef Vector<3, int8_t, int32_t> Vector3DInt8; | ||||
| 	/// A 3D Vector of unsigned 8-bit values. | ||||
| 	typedef Vector<3,uint8_t,int32_t> Vector3DUint8; | ||||
| 	typedef Vector<3, uint8_t, int32_t> Vector3DUint8; | ||||
| 	/// A 3D Vector of signed 16-bit values. | ||||
| 	typedef Vector<3,int16_t,int32_t> Vector3DInt16; | ||||
| 	typedef Vector<3, int16_t, int32_t> Vector3DInt16; | ||||
| 	/// A 3D Vector of unsigned 16-bit values. | ||||
| 	typedef Vector<3,uint16_t,int32_t> Vector3DUint16; | ||||
| 	typedef Vector<3, uint16_t, int32_t> Vector3DUint16; | ||||
| 	/// A 3D Vector of signed 32-bit values. | ||||
| 	typedef Vector<3,int32_t,int32_t> Vector3DInt32; | ||||
| 	typedef Vector<3, int32_t, int32_t> Vector3DInt32; | ||||
| 	/// A 3D Vector of unsigned 32-bit values. | ||||
| 	typedef Vector<3,uint32_t,int32_t> Vector3DUint32; | ||||
| 	typedef Vector<3, uint32_t, int32_t> Vector3DUint32; | ||||
|  | ||||
| 	/// A 4D Vector of floats. | ||||
| 	typedef Vector<4,float,float> Vector4DFloat; | ||||
| 	typedef Vector<4, float, float> Vector4DFloat; | ||||
| 	/// A 4D Vector of doubles. | ||||
|     typedef Vector<4,double,double> Vector4DDouble; | ||||
| 	typedef Vector<4, double, double> Vector4DDouble; | ||||
| 	/// A 4D Vector of signed 8-bit values. | ||||
| 	typedef Vector<4,int8_t,int32_t> Vector4DInt8; | ||||
| 	typedef Vector<4, int8_t, int32_t> Vector4DInt8; | ||||
| 	/// A 4D Vector of unsigned 8-bit values. | ||||
| 	typedef Vector<4,uint8_t,int32_t> Vector4DUint8; | ||||
| 	typedef Vector<4, uint8_t, int32_t> Vector4DUint8; | ||||
| 	/// A 4D Vector of signed 16-bit values. | ||||
| 	typedef Vector<4,int16_t,int32_t> Vector4DInt16; | ||||
| 	typedef Vector<4, int16_t, int32_t> Vector4DInt16; | ||||
| 	/// A 4D Vector of unsigned 16-bit values. | ||||
| 	typedef Vector<4,uint16_t,int32_t> Vector4DUint16; | ||||
| 	typedef Vector<4, uint16_t, int32_t> Vector4DUint16; | ||||
| 	/// A 4D Vector of signed 32-bit values. | ||||
| 	typedef Vector<4,int32_t,int32_t> Vector4DInt32; | ||||
| 	typedef Vector<4, int32_t, int32_t> Vector4DInt32; | ||||
| 	/// A 4D Vector of unsigned 32-bit values. | ||||
| 	typedef Vector<4,uint32_t,int32_t> Vector4DUint32; | ||||
| 	typedef Vector<4, uint32_t, int32_t> Vector4DUint32; | ||||
|  | ||||
|  | ||||
| }//namespace PolyVox | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
|  | ||||
| namespace PolyVox | ||||
| { | ||||
|     //-------------------------- Constructors, etc --------------------------------- | ||||
| 	//-------------------------- Constructors, etc --------------------------------- | ||||
| 	/** | ||||
| 	 * Creates a Vector object but does not initialise it. | ||||
| 	 */ | ||||
| @@ -34,28 +34,28 @@ namespace PolyVox | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Creates a Vector object and initialises all components with the given value. | ||||
|      * \param tFillValue The value to write to every component. | ||||
|      */ | ||||
|     template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType>::Vector(StorageType tFillValue) | ||||
|     { | ||||
| 	 * Creates a Vector object and initialises all components with the given value. | ||||
| 	 * \param tFillValue The value to write to every component. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType>::Vector(StorageType tFillValue) | ||||
| 	{ | ||||
| 		std::fill(m_tElements, m_tElements + Size, tFillValue); | ||||
|     } | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Creates a Vector object and initialises it with given values. | ||||
|      * \param x The X component to set. | ||||
|      * \param y The Y component to set. | ||||
|      */ | ||||
|     template <uint32_t Size,typename StorageType, typename OperationType> | ||||
|     Vector<Size,StorageType,OperationType>::Vector(StorageType x, StorageType y) | ||||
|     { | ||||
| 	/** | ||||
| 	 * Creates a Vector object and initialises it with given values. | ||||
| 	 * \param x The X component to set. | ||||
| 	 * \param y The Y component to set. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType>::Vector(StorageType x, StorageType y) | ||||
| 	{ | ||||
| 		static_assert(Size == 2, "This constructor should only be used for vectors with two elements."); | ||||
|  | ||||
| 		m_tElements[0] = x; | ||||
| 		m_tElements[1] = y; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates a Vector3D object and initialises it with given values. | ||||
| @@ -63,8 +63,8 @@ namespace PolyVox | ||||
| 	 * \param y The Y component to set. | ||||
| 	 * \param z the Z component to set. | ||||
| 	 */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType>::Vector(StorageType x, StorageType y, StorageType z) | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType>::Vector(StorageType x, StorageType y, StorageType z) | ||||
| 	{ | ||||
| 		static_assert(Size == 3, "This constructor should only be used for vectors with three elements."); | ||||
|  | ||||
| @@ -81,8 +81,8 @@ namespace PolyVox | ||||
| 	 * \param z The Z component to set. | ||||
| 	 * \param w The W component to set. | ||||
| 	 */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType>::Vector(StorageType x, StorageType y, StorageType z, StorageType w) | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType>::Vector(StorageType x, StorageType y, StorageType z, StorageType w) | ||||
| 	{ | ||||
| 		static_assert(Size == 4, "This constructor should only be used for vectors with four elements."); | ||||
|  | ||||
| @@ -92,41 +92,41 @@ namespace PolyVox | ||||
| 		m_tElements[3] = w; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Copy constructor builds object based on object passed as parameter. | ||||
|      * \param vector A reference to the Vector to be copied. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Copy constructor builds object based on object passed as parameter. | ||||
| 	 * \param vector A reference to the Vector to be copied. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType>::Vector(const Vector<Size, StorageType, OperationType>& vector) | ||||
|     { | ||||
| 		std::memcpy(m_tElements, vector.m_tElements, sizeof(StorageType) * Size); | ||||
|     } | ||||
| 	{ | ||||
| 		std::memcpy(m_tElements, vector.m_tElements, sizeof(StorageType)* Size); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * This copy constructor allows casting between vectors with different data types. | ||||
| 	 * It makes it possible to use code such as: | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * Vector3DDouble v3dDouble(1.0,2.0,3.0); | ||||
| 	 * Vector3DFloat v3dFloat = static_cast<Vector3DFloat>(v3dDouble); //Casting | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \param vector A reference to the Vector to be copied. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	template <typename CastType> | ||||
| 		Vector<Size, StorageType, OperationType>::Vector(const Vector<Size, CastType>& vector) | ||||
| 	Vector<Size, StorageType, OperationType>::Vector(const Vector<Size, CastType>& vector) | ||||
| 	{ | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			m_tElements[ct] = static_cast<StorageType>(vector.getElement(ct)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Destroys the Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Destroys the Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType>::~Vector(void) | ||||
|     { | ||||
| 	{ | ||||
| 		// We put the static asserts in the destructor because there is one one of these, | ||||
| 		// where as there are multiple constructors. | ||||
|  | ||||
| @@ -135,213 +135,213 @@ namespace PolyVox | ||||
| 		// behaviour of the constructor taking a single value, as this fills all elements | ||||
| 		// to that value rather than just the first one. | ||||
| 		static_assert(Size > 1, "Vector must have a length greater than one."); | ||||
|     } | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Assignment operator copies each element of first Vector to the second. | ||||
|      * \param rhs Vector to assign to. | ||||
|      * \return A reference to the result to allow chaining. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Assignment operator copies each element of first Vector to the second. | ||||
| 	 * \param rhs Vector to assign to. | ||||
| 	 * \return A reference to the result to allow chaining. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator=(const Vector<Size, StorageType, OperationType>& rhs) | ||||
|     { | ||||
|         if(this == &rhs) | ||||
| 	{ | ||||
| 		if (this == &rhs) | ||||
| 		{ | ||||
| 			return *this; | ||||
| 		} | ||||
|         std::memcpy(m_tElements, rhs.m_tElements, sizeof(StorageType) * Size); | ||||
|         return *this; | ||||
|     } | ||||
| 		std::memcpy(m_tElements, rhs.m_tElements, sizeof(StorageType)* Size); | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Checks whether two Vectors are equal. | ||||
|      * \param rhs The Vector to compare to. | ||||
|      * \return true if the Vectors match. | ||||
|      * \see operator!= | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Checks whether two Vectors are equal. | ||||
| 	 * \param rhs The Vector to compare to. | ||||
| 	 * \return true if the Vectors match. | ||||
| 	 * \see operator!= | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline bool Vector<Size, StorageType, OperationType>::operator==(const Vector<Size, StorageType, OperationType> &rhs) const | ||||
|     { | ||||
| 	{ | ||||
| 		bool equal = true; | ||||
|         for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			if(m_tElements[ct] != rhs.m_tElements[ct]) | ||||
| 			if (m_tElements[ct] != rhs.m_tElements[ct]) | ||||
| 			{ | ||||
| 				equal = false; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		return equal; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Checks whether two Vectors are not equal. | ||||
|      * \param rhs The Vector to compare to. | ||||
|      * \return true if the Vectors do not match. | ||||
|      * \see operator== | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 * Checks whether two Vectors are not equal. | ||||
| 	 * \param rhs The Vector to compare to. | ||||
| 	 * \return true if the Vectors do not match. | ||||
| 	 * \see operator== | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline bool Vector<Size, StorageType, OperationType>::operator!=(const Vector<Size, StorageType, OperationType> &rhs) const | ||||
|     { | ||||
| 	{ | ||||
| 		return !(*this == rhs); //Just call equality operator and invert the result. | ||||
|     }    | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Addition operator adds corresponding elements of the two Vectors. | ||||
|      * \param rhs The Vector to add | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Addition operator adds corresponding elements of the two Vectors. | ||||
| 	 * \param rhs The Vector to add | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator+=(const Vector<Size, StorageType, OperationType>& rhs) | ||||
|     { | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			m_tElements[ct] += rhs.m_tElements[ct]; | ||||
| 		} | ||||
|         return *this; | ||||
|     } | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Subtraction operator subtracts corresponding elements of one Vector from the other. | ||||
|      * \param rhs The Vector to subtract | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 * Subtraction operator subtracts corresponding elements of one Vector from the other. | ||||
| 	 * \param rhs The Vector to subtract | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator-=(const Vector<Size, StorageType, OperationType>& rhs) | ||||
|     { | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			m_tElements[ct] -= rhs.m_tElements[ct]; | ||||
| 		} | ||||
|         return *this; | ||||
|     } | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Multiplication operator multiplies corresponding elements of the two Vectors. | ||||
|      * \param rhs The Vector to multiply by | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 * Multiplication operator multiplies corresponding elements of the two Vectors. | ||||
| 	 * \param rhs The Vector to multiply by | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator*=(const Vector<Size, StorageType, OperationType>& rhs) | ||||
|     { | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			m_tElements[ct] *= rhs.m_tElements[ct]; | ||||
| 		} | ||||
|         return *this; | ||||
|     } | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Division operator divides corresponding elements of one Vector by the other. | ||||
|      * \param rhs The Vector to divide by | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 * Division operator divides corresponding elements of one Vector by the other. | ||||
| 	 * \param rhs The Vector to divide by | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator/=(const Vector<Size, StorageType, OperationType>& rhs) | ||||
|     { | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			m_tElements[ct] /= rhs.m_tElements[ct]; | ||||
| 		} | ||||
|         return *this; | ||||
|     } | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Multiplication operator multiplies each element of the Vector by a number. | ||||
|      * \param rhs The number the Vector is multiplied by. | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Multiplication operator multiplies each element of the Vector by a number. | ||||
| 	 * \param rhs The number the Vector is multiplied by. | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator*=(const StorageType& rhs) | ||||
|     { | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			m_tElements[ct] *= rhs; | ||||
| 		} | ||||
|         return *this; | ||||
|     } | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
| 	/** | ||||
| 	 * Division operator divides each element of the Vector by a number. | ||||
| 	 * \param rhs The number the Vector is divided by. | ||||
| 	 * \return The resulting Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline Vector<Size, StorageType, OperationType>& Vector<Size, StorageType, OperationType>::operator/=(const StorageType& rhs) | ||||
|     { | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			m_tElements[ct] /= rhs; | ||||
| 		} | ||||
|         return *this; | ||||
|     } | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Addition operator adds corresponding elements of the two Vectors. | ||||
| 	 * Addition operator adds corresponding elements of the two Vectors. | ||||
| 	 * \param lhs The Vector to add to. | ||||
|      * \param rhs The Vector to add. | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType> operator+(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) | ||||
| 	 * \param rhs The Vector to add. | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator+(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs) | ||||
| 	{ | ||||
| 		Vector<Size,StorageType,OperationType> result = lhs; | ||||
| 		Vector<Size, StorageType, OperationType> result = lhs; | ||||
| 		result += rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Subtraction operator subtracts corresponding elements of one Vector from the other. | ||||
| 	 * Subtraction operator subtracts corresponding elements of one Vector from the other. | ||||
| 	 * \param lhs The Vector to subtract from. | ||||
|      * \param rhs The Vector to subtract. | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType> operator-(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) | ||||
| 	 * \param rhs The Vector to subtract. | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator-(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs) | ||||
| 	{ | ||||
| 		Vector<Size,StorageType,OperationType> result = lhs; | ||||
| 		Vector<Size, StorageType, OperationType> result = lhs; | ||||
| 		result -= rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Multiplication operator mulitplies corresponding elements of the two Vectors. | ||||
| 	 * Multiplication operator mulitplies corresponding elements of the two Vectors. | ||||
| 	 * \param lhs The Vector to multiply. | ||||
|      * \param rhs The Vector to multiply by. | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) | ||||
| 	 * \param rhs The Vector to multiply by. | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs) | ||||
| 	{ | ||||
| 		Vector<Size,StorageType,OperationType> result = lhs; | ||||
| 		Vector<Size, StorageType, OperationType> result = lhs; | ||||
| 		result *= rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Division operator divides corresponding elements of one Vector by the other. | ||||
| 	 * Division operator divides corresponding elements of one Vector by the other. | ||||
| 	 * \param lhs The Vector to divide. | ||||
|      * \param rhs The Vector to divide by. | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs) | ||||
| 	 * \param rhs The Vector to divide by. | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const Vector<Size, StorageType, OperationType>& rhs) | ||||
| 	{ | ||||
| 		Vector<Size,StorageType,OperationType> result = lhs; | ||||
| 		Vector<Size, StorageType, OperationType> result = lhs; | ||||
| 		result /= rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Multiplication operator multiplies each element of the Vector by a number. | ||||
| 	 * Multiplication operator multiplies each element of the Vector by a number. | ||||
| 	 * \param lhs The Vector to multiply. | ||||
|      * \param rhs The number the Vector is multiplied by. | ||||
|      * \return The resulting Vector. | ||||
|      */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs) | ||||
| 	 * \param rhs The number the Vector is multiplied by. | ||||
| 	 * \return The resulting Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator*(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs) | ||||
| 	{ | ||||
| 		Vector<Size,StorageType,OperationType> result = lhs; | ||||
| 		Vector<Size, StorageType, OperationType> result = lhs; | ||||
| 		result *= rhs; | ||||
| 		return result; | ||||
| 	} | ||||
| @@ -351,36 +351,36 @@ namespace PolyVox | ||||
| 	 * \param lhs The Vector to divide. | ||||
| 	 * \param rhs The number the Vector is divided by. | ||||
| 	 * \return The resulting Vector. | ||||
|      */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs) | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	Vector<Size, StorageType, OperationType> operator/(const Vector<Size, StorageType, OperationType>& lhs, const StorageType& rhs) | ||||
| 	{ | ||||
| 		Vector<Size,StorageType,OperationType> result = lhs; | ||||
| 		Vector<Size, StorageType, OperationType> result = lhs; | ||||
| 		result /= rhs; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Enables the Vector to be used intuitively with output streams such as cout. | ||||
|      * \param os The output stream to write to. | ||||
|      * \param vector The Vector to write to the stream. | ||||
|      * \return A reference to the output stream to allow chaining. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Enables the Vector to be used intuitively with output streams such as cout. | ||||
| 	 * \param os The output stream to write to. | ||||
| 	 * \param vector The Vector to write to the stream. | ||||
| 	 * \return A reference to the output stream to allow chaining. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	std::ostream& operator<<(std::ostream& os, const Vector<Size, StorageType, OperationType>& vector) | ||||
|     { | ||||
|         os << "("; | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		os << "("; | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			os << vector.getElement(ct); | ||||
| 			if(ct < (Size-1)) | ||||
| 			if (ct < (Size - 1)) | ||||
| 			{ | ||||
| 				os << ","; | ||||
| 			} | ||||
| 		} | ||||
| 		os << ")"; | ||||
|         return os; | ||||
|     }		 | ||||
| 		return os; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns the element at the given position. | ||||
| @@ -390,7 +390,7 @@ namespace PolyVox | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline StorageType Vector<Size, StorageType, OperationType>::getElement(uint32_t index) const | ||||
| 	{ | ||||
| 		if(index >= Size) | ||||
| 		if (index >= Size) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element."); | ||||
| 		} | ||||
| @@ -398,34 +398,34 @@ namespace PolyVox | ||||
| 		return m_tElements[index]; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * \return A const reference to the X component of a 1, 2, 3, or 4 dimensional Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * \return A const reference to the X component of a 1, 2, 3, or 4 dimensional Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline StorageType Vector<Size, StorageType, OperationType>::getX(void) const | ||||
|     { | ||||
|         return m_tElements[0]; // This is fine, a Vector always contains at least two elements. | ||||
|     }	 | ||||
| 	{ | ||||
| 		return m_tElements[0]; // This is fine, a Vector always contains at least two elements. | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \return A const reference to the Y component of a 2, 3, or 4 dimensional Vector. | ||||
| 	 */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline StorageType Vector<Size, StorageType, OperationType>::getY(void) const | ||||
|     { | ||||
|         return m_tElements[1]; // This is fine, a Vector always contains at least two elements. | ||||
|     }	 | ||||
| 	{ | ||||
| 		return m_tElements[1]; // This is fine, a Vector always contains at least two elements. | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \return A const reference to the Z component of a 3 or 4 dimensional Vector. | ||||
| 	 */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline StorageType Vector<Size, StorageType, OperationType>::getZ(void) const | ||||
|     { | ||||
| 	{ | ||||
| 		static_assert(Size >= 3, "You can only get the 'z' component from a vector with at least three elements."); | ||||
|  | ||||
|         return m_tElements[2]; | ||||
|     }	 | ||||
| 		return m_tElements[2]; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \return A const reference to the W component of a 4 dimensional Vector. | ||||
| @@ -436,7 +436,7 @@ namespace PolyVox | ||||
| 		static_assert(Size >= 4, "You can only get the 'w' component from a vector with at least four elements."); | ||||
|  | ||||
| 		return m_tElements[3]; | ||||
| 	}   | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \param index The index of the element to set. | ||||
| @@ -445,7 +445,7 @@ namespace PolyVox | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setElement(uint32_t index, StorageType tValue) | ||||
| 	{ | ||||
| 		if(index >= Size) | ||||
| 		if (index >= Size) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(std::out_of_range, "Attempted to access invalid vector element."); | ||||
| 		} | ||||
| @@ -454,17 +454,17 @@ namespace PolyVox | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
|      * Sets several elements of a vector at once. | ||||
|      * \param x The X component to set. | ||||
|      * \param y The Y component to set. | ||||
|      */ | ||||
|     template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size,StorageType,OperationType>::setElements(StorageType x, StorageType y) | ||||
|     { | ||||
| 	 * Sets several elements of a vector at once. | ||||
| 	 * \param x The X component to set. | ||||
| 	 * \param y The Y component to set. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setElements(StorageType x, StorageType y) | ||||
| 	{ | ||||
| 		// This is fine, a Vector always contains at least two elements. | ||||
| 		m_tElements[0] = x; | ||||
| 		m_tElements[1] = y; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets several elements of a vector at once. | ||||
| @@ -472,8 +472,8 @@ namespace PolyVox | ||||
| 	 * \param y The Y component to set. | ||||
| 	 * \param z The Z component to set. | ||||
| 	 */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size,StorageType,OperationType>::setElements(StorageType x, StorageType y, StorageType z) | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setElements(StorageType x, StorageType y, StorageType z) | ||||
| 	{ | ||||
| 		static_assert(Size >= 3, "You can only use this version of setElements() on a vector with at least three elements."); | ||||
|  | ||||
| @@ -489,8 +489,8 @@ namespace PolyVox | ||||
| 	 * \param z The Z component to set. | ||||
| 	 * \param w The W component to set. | ||||
| 	 */ | ||||
| 	template <uint32_t Size,typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size,StorageType,OperationType>::setElements(StorageType x, StorageType y, StorageType z, StorageType w) | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setElements(StorageType x, StorageType y, StorageType z, StorageType w) | ||||
| 	{ | ||||
| 		static_assert(Size >= 4, "You can only use this version of setElements() on a vector with at least four elements."); | ||||
|  | ||||
| @@ -503,141 +503,141 @@ namespace PolyVox | ||||
| 	/** | ||||
| 	 * \param tX The new value for the X component of a 1, 2, 3, or 4 dimensional Vector. | ||||
| 	 */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setX(StorageType tX) | ||||
|     { | ||||
|         m_tElements[0] = tX; // This is fine, a Vector always contains at least two elements. | ||||
|     } | ||||
| 	{ | ||||
| 		m_tElements[0] = tX; // This is fine, a Vector always contains at least two elements. | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \param tY The new value for the Y component of a 2, 3, or 4 dimensional Vector. | ||||
| 	 */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setY(StorageType tY) | ||||
|     { | ||||
|         m_tElements[1] = tY; // This is fine, a Vector always contains at least two elements. | ||||
|     } | ||||
| 	{ | ||||
| 		m_tElements[1] = tY; // This is fine, a Vector always contains at least two elements. | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \param tZ The new value for the Z component of a 3 or 4 dimensional Vector. | ||||
| 	 */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setZ(StorageType tZ) | ||||
|     { | ||||
| 	{ | ||||
| 		static_assert(Size >= 3, "You can only set the 'w' component from a vector with at least three elements."); | ||||
|  | ||||
| 		m_tElements[2] = tZ; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \param tW The new value for the W component of a 4 dimensional Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::setW(StorageType tW) | ||||
|     { | ||||
| 	{ | ||||
| 		static_assert(Size >= 4, "You can only set the 'w' component from a vector with at least four elements."); | ||||
|  | ||||
| 		m_tElements[3] = tW; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * \note This function always returns a single precision floating point value, even when the StorageType is a double precision floating point value or an integer. | ||||
|      * \return The length of the Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 * \return The length of the Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline float Vector<Size, StorageType, OperationType>::length(void) const | ||||
|     { | ||||
|         return sqrt(static_cast<float>(lengthSquared())); | ||||
|     } | ||||
| 	{ | ||||
| 		return sqrt(static_cast<float>(lengthSquared())); | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * \return The squared length of the Vector. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * \return The squared length of the Vector. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline OperationType Vector<Size, StorageType, OperationType>::lengthSquared(void) const | ||||
|     { | ||||
| 	{ | ||||
| 		OperationType tLengthSquared = static_cast<OperationType>(0); | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			tLengthSquared += static_cast<OperationType>(m_tElements[ct]) * static_cast<OperationType>(m_tElements[ct]); | ||||
| 		} | ||||
| 		return tLengthSquared; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * This function is commutative, such that a.angleTo(b) == b.angleTo(a). The angle | ||||
|      * returned is in radians and varies between 0 and 3.14(pi). It is always positive. | ||||
| 	 *  | ||||
| 	/** | ||||
| 	 * This function is commutative, such that a.angleTo(b) == b.angleTo(a). The angle | ||||
| 	 * returned is in radians and varies between 0 and 3.14(pi). It is always positive. | ||||
| 	 * | ||||
| 	 * \note This function always returns a single precision floating point value, even when the StorageType is a double precision floating point value or an integer. | ||||
| 	 *  | ||||
|      * \param vector The Vector to find the angle to. | ||||
|      * \return The angle between them in radians. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 * | ||||
| 	 * \param vector The Vector to find the angle to. | ||||
| 	 * \return The angle between them in radians. | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline float Vector<Size, StorageType, OperationType>::angleTo(const Vector<Size, StorageType, OperationType>& vector) const | ||||
|     { | ||||
|         return acos(static_cast<float>(dot(vector)) / (vector.length() * this->length())); | ||||
|     } | ||||
| 	{ | ||||
| 		return acos(static_cast<float>(dot(vector)) / (vector.length() * this->length())); | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * This function is used to calculate the cross product of two Vectors. | ||||
|      * The cross product is the Vector which is perpendicular to the two | ||||
|      * given Vectors. It is worth remembering that, unlike the dot product, | ||||
|      * it is not commutative. E.g a.b != b.a. The cross product obeys the  | ||||
| 	/** | ||||
| 	 * This function is used to calculate the cross product of two Vectors. | ||||
| 	 * The cross product is the Vector which is perpendicular to the two | ||||
| 	 * given Vectors. It is worth remembering that, unlike the dot product, | ||||
| 	 * it is not commutative. E.g a.b != b.a. The cross product obeys the | ||||
| 	 * right-hand rule such that if the two vectors are given by the index | ||||
| 	 * finger and middle finger respectively then the cross product is given | ||||
| 	 * by the thumb. | ||||
|      * \param vector The vector to cross with this | ||||
|      * \return The value of the cross product. | ||||
|      * \see dot() | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 * \param vector The vector to cross with this | ||||
| 	 * \return The value of the cross product. | ||||
| 	 * \see dot() | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline Vector<Size, StorageType, OperationType> Vector<Size, StorageType, OperationType>::cross(const Vector<Size, StorageType, OperationType>& vector) const | ||||
|     { | ||||
|         StorageType i = vector.getZ() * this->getY() - vector.getY() * this->getZ(); | ||||
|         StorageType j = vector.getX() * this->getZ() - vector.getZ() * this->getX(); | ||||
|         StorageType k = vector.getY() * this->getX() - vector.getX() * this->getY(); | ||||
|         return Vector<Size, StorageType, OperationType>(i,j,k); | ||||
|     } | ||||
| 	{ | ||||
| 		StorageType i = vector.getZ() * this->getY() - vector.getY() * this->getZ(); | ||||
| 		StorageType j = vector.getX() * this->getZ() - vector.getZ() * this->getX(); | ||||
| 		StorageType k = vector.getY() * this->getX() - vector.getX() * this->getY(); | ||||
| 		return Vector<Size, StorageType, OperationType>(i, j, k); | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Calculates the dot product of the Vector and the parameter. | ||||
|      * This function is commutative, such that a.dot(b) == b.dot(a). | ||||
|      * \param rhs The Vector to find the dot product with. | ||||
|      * \return The value of the dot product. | ||||
|      * \see cross() | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	/** | ||||
| 	 * Calculates the dot product of the Vector and the parameter. | ||||
| 	 * This function is commutative, such that a.dot(b) == b.dot(a). | ||||
| 	 * \param rhs The Vector to find the dot product with. | ||||
| 	 * \return The value of the dot product. | ||||
| 	 * \see cross() | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline OperationType Vector<Size, StorageType, OperationType>::dot(const Vector<Size, StorageType, OperationType>& rhs) const | ||||
|     { | ||||
|         OperationType dotProduct = static_cast<OperationType>(0); | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 	{ | ||||
| 		OperationType dotProduct = static_cast<OperationType>(0); | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			dotProduct += static_cast<OperationType>(m_tElements[ct]) * static_cast<OperationType>(rhs.m_tElements[ct]); | ||||
| 		} | ||||
| 		return dotProduct; | ||||
|     } | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
|      * Divides the i, j, and k components by the length to give a Vector of length 1.0. If the vector is | ||||
| 	/** | ||||
| 	 * Divides the i, j, and k components by the length to give a Vector of length 1.0. If the vector is | ||||
| 	 * very short (or zero) then a divide by zero may cause elements to take on invalid values. You may | ||||
| 	 * want to check for this before normalising. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * \note You should not attempt to normalise a vector whose StorageType is an integer. | ||||
|      */ | ||||
|     template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	 */ | ||||
| 	template <uint32_t Size, typename StorageType, typename OperationType> | ||||
| 	inline void Vector<Size, StorageType, OperationType>::normalise(void) | ||||
|     { | ||||
|         float fLength = this->length(); | ||||
| 	{ | ||||
| 		float fLength = this->length(); | ||||
|  | ||||
| 		// We could wait until the NAN occurs before throwing, but then we'd have to add some roll-back code. | ||||
| 		// This seems like a lot of overhead for a common operation which should rarely go wrong. | ||||
| 		if(fLength <= 0.0001) | ||||
| 		if (fLength <= 0.0001) | ||||
| 		{ | ||||
| 			POLYVOX_THROW(invalid_operation, "Cannot normalise a vector with a length of zero"); | ||||
| 		} | ||||
|  | ||||
| 		for(uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		for (uint32_t ct = 0; ct < Size; ++ct) | ||||
| 		{ | ||||
| 			// Standard float rules apply for divide-by-zero | ||||
| 			m_tElements[ct] /= fLength; | ||||
| @@ -645,5 +645,5 @@ namespace PolyVox | ||||
| 			//This shouldn't happen as we had the length check earlier. So it's probably a bug if it does happen. | ||||
| 			POLYVOX_ASSERT(m_tElements[ct] == m_tElements[ct], "Obtained NAN during vector normalisation. Perhaps the input vector was too short?"); | ||||
| 		} | ||||
|     } | ||||
| 	} | ||||
| }//namespace PolyVox | ||||
|   | ||||
| @@ -37,9 +37,9 @@ namespace PolyVox | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType> | ||||
| 	VolumeResampler<SrcVolumeType, DstVolumeType>::VolumeResampler(SrcVolumeType* pVolSrc, const Region ®Src, DstVolumeType* pVolDst, const Region& regDst) | ||||
| 		:m_pVolSrc(pVolSrc) | ||||
| 		,m_regSrc(regSrc) | ||||
| 		,m_pVolDst(pVolDst) | ||||
| 		,m_regDst(regDst) | ||||
| 		, m_regSrc(regSrc) | ||||
| 		, m_pVolDst(pVolDst) | ||||
| 		, m_regDst(regDst) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| @@ -54,7 +54,7 @@ namespace PolyVox | ||||
| 		int32_t uDstHeight = m_regDst.getUpperY() - m_regDst.getLowerY() + 1; | ||||
| 		int32_t uDstDepth = m_regDst.getUpperZ() - m_regDst.getLowerZ() + 1; | ||||
|  | ||||
| 		if((uSrcWidth == uDstWidth) && (uSrcHeight == uDstHeight) && (uSrcDepth == uDstDepth)) | ||||
| 		if ((uSrcWidth == uDstWidth) && (uSrcHeight == uDstHeight) && (uSrcDepth == uDstDepth)) | ||||
| 		{ | ||||
| 			resampleSameSize(); | ||||
| 		} | ||||
| @@ -67,15 +67,15 @@ namespace PolyVox | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType> | ||||
| 	void VolumeResampler<SrcVolumeType, DstVolumeType>::resampleSameSize() | ||||
| 	{ | ||||
| 		for(int32_t sz = m_regSrc.getLowerZ(), dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); sz++, dz++) | ||||
| 		for (int32_t sz = m_regSrc.getLowerZ(), dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); sz++, dz++) | ||||
| 		{ | ||||
| 			for(int32_t sy = m_regSrc.getLowerY(), dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); sy++, dy++) | ||||
| 			for (int32_t sy = m_regSrc.getLowerY(), dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); sy++, dy++) | ||||
| 			{ | ||||
| 				for(int32_t sx = m_regSrc.getLowerX(), dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); sx++,dx++) | ||||
| 				for (int32_t sx = m_regSrc.getLowerX(), dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); sx++, dx++) | ||||
| 				{ | ||||
| 					const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx,sy,sz); | ||||
| 					const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxel(sx, sy, sz); | ||||
| 					const typename DstVolumeType::VoxelType& tDstVoxel = static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel); | ||||
| 					m_pVolDst->setVoxel(dx,dy,dz,tDstVoxel); | ||||
| 					m_pVolDst->setVoxel(dx, dy, dz, tDstVoxel); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -84,25 +84,25 @@ namespace PolyVox | ||||
| 	template< typename SrcVolumeType, typename DstVolumeType> | ||||
| 	void VolumeResampler<SrcVolumeType, DstVolumeType>::resampleArbitrary() | ||||
| 	{ | ||||
| 		float srcWidth  = m_regSrc.getWidthInCells(); | ||||
| 		float srcWidth = m_regSrc.getWidthInCells(); | ||||
| 		float srcHeight = m_regSrc.getHeightInCells(); | ||||
| 		float srcDepth  = m_regSrc.getDepthInCells(); | ||||
| 		float srcDepth = m_regSrc.getDepthInCells(); | ||||
|  | ||||
| 		float dstWidth  = m_regDst.getWidthInCells(); | ||||
| 		float dstWidth = m_regDst.getWidthInCells(); | ||||
| 		float dstHeight = m_regDst.getHeightInCells(); | ||||
| 		float dstDepth  = m_regDst.getDepthInCells(); | ||||
| 		 | ||||
| 		float dstDepth = m_regDst.getDepthInCells(); | ||||
|  | ||||
| 		float fScaleX = srcWidth / dstWidth; | ||||
| 		float fScaleY = srcHeight / dstHeight; | ||||
| 		float fScaleZ = srcDepth / dstDepth; | ||||
|  | ||||
| 		typename SrcVolumeType::Sampler sampler(m_pVolSrc); | ||||
|  | ||||
| 		for(int32_t dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); dz++) | ||||
| 		for (int32_t dz = m_regDst.getLowerZ(); dz <= m_regDst.getUpperZ(); dz++) | ||||
| 		{ | ||||
| 			for(int32_t dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); dy++) | ||||
| 			for (int32_t dy = m_regDst.getLowerY(); dy <= m_regDst.getUpperY(); dy++) | ||||
| 			{ | ||||
| 				for(int32_t dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); dx++) | ||||
| 				for (int32_t dx = m_regDst.getLowerX(); dx <= m_regDst.getUpperX(); dx++) | ||||
| 				{ | ||||
| 					float sx = (dx - m_regDst.getLowerX()) * fScaleX; | ||||
| 					float sy = (dy - m_regDst.getLowerY()) * fScaleY; | ||||
| @@ -112,7 +112,7 @@ namespace PolyVox | ||||
| 					sy += m_regSrc.getLowerY(); | ||||
| 					sz += m_regSrc.getLowerZ(); | ||||
|  | ||||
| 					sampler.setPosition(sx,sy,sz); | ||||
| 					sampler.setPosition(sx, sy, sz); | ||||
| 					const typename SrcVolumeType::VoxelType& voxel000 = sampler.peekVoxel0px0py0pz(); | ||||
| 					const typename SrcVolumeType::VoxelType& voxel001 = sampler.peekVoxel0px0py1pz(); | ||||
| 					const typename SrcVolumeType::VoxelType& voxel010 = sampler.peekVoxel0px1py0pz(); | ||||
| @@ -128,10 +128,10 @@ namespace PolyVox | ||||
| 					sy = modf(sy, &dummy); | ||||
| 					sz = modf(sz, &dummy); | ||||
|  | ||||
| 					typename SrcVolumeType::VoxelType tInterpolatedValue = trilerp<float>(voxel000,voxel100,voxel010,voxel110,voxel001,voxel101,voxel011,voxel111,sx,sy,sz); | ||||
| 					typename SrcVolumeType::VoxelType tInterpolatedValue = trilerp<float>(voxel000, voxel100, voxel010, voxel110, voxel001, voxel101, voxel011, voxel111, sx, sy, sz); | ||||
|  | ||||
| 					typename DstVolumeType::VoxelType result = static_cast<typename DstVolumeType::VoxelType>(tInterpolatedValue); | ||||
| 					m_pVolDst->setVoxel(dx,dy,dz,result); | ||||
| 					m_pVolDst->setVoxel(dx, dy, dz, result); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user