temp_rtsBoundingVolumes.h 3.41 KB
#ifndef RTS_BOUNDING_VOLUMES
#define RTS_BOUNDING_VOLUMES

#include "rtsLinearAlgebra.h"
#include <math.h>

template <class T>
class rtsAABB
{
public:
	point3D<T> minimum;
	point3D<T> maximum;

	//overloaded operators
	rtsAABB<T> operator+(rtsAABB<T> param);
	rtsAABB<unsigned int> getGridAlignedAABB();
	inline bool isIn(T x, T y, T z);
};

template <class T>
class rtsBoundingSphere
{
public:
	point3D<T> center;
	T radius;

	inline bool isIn(T x, T y, T z);
};

template <class T>
class rtsTGC
{
public:
	point3D<T> posA;
	point3D<T> posB;
	vector3D<T> normA;
	vector3D<T> normB;
	T radA;
	T radB;

	rtsAABB<T> BoundAABB();
};

template <class T>
rtsAABB<T> rtsAABB<T>::operator+(rtsAABB<T> param)
{
/*	This function creates an AABB by finding the minimum bound
	of two other AABBs.
*/

	rtsAABB<T> result;
	
	result.minimum.x = min(minimum.x, param.minimum.x);
	result.minimum.y = min(minimum.y, param.minimum.y);
	result.minimum.z = min(minimum.z, param.minimum.z);

	result.maximum.x = max(maximum.x, param.maximum.x);
	result.maximum.y = max(maximum.y, param.maximum.y);
	result.maximum.z = max(maximum.z, param.maximum.z);
	return result;
}

template <class T>
inline bool rtsAABB<T>::isIn(T x, T y, T z)
{
	if(x >= minimum.x && x <= maximum.x &&
		y >= minimum.y && y <= maximum.y &&
		z >= minimum.z && z <= maximum.z)
		return true;
	else
		return false;
}

template <class T>
inline bool rtsBoundingSphere<T>::isIn(T x, T y, T z)
{
	vector3D<T> to_point = center - point3D<T>(x, y, z);
	T length_squared = to_point*to_point;
	if(length_squared < radius*radius)
		return true;
	else
		return false;
}

template <class T>
rtsAABB<unsigned int> rtsAABB<T>::getGridAlignedAABB()
{
/*	This function returns a version of the current AABB that is snapped
	to a grid (ie the floor of the position and the ceiling of the size).
*/
	rtsAABB<unsigned int> result;
	result.minimum.x = floor(minimum.x);
	result.minimum.y = floor(minimum.y);
	result.minimum.z = floor(minimum.z);
	result.maximum.x = ceil(maximum.x);
	result.maximum.y = ceil(maximum.y);
	result.maximum.z = ceil(maximum.z);
	return result;
}

template <class T>
rtsAABB<T> rtsTGC<T>::BoundAABB()
{
/*	This function returns an axis-aligned bounding box
	that is the minimum bound for the given truncated-generalized cone.
*/
	//create a vector representing each axis
	vector3D<double> x(1.0, 0.0, 0.0);
	vector3D<double> y(0.0, 1.0, 0.0);
	vector3D<double> z(0.0, 0.0, 1.0);

	//store the extents
	point3D<T> a_extents(radA*(1.0 - fabs(normA*x)),
					  radA*(1.0 - fabs(normA*y)),
					  radA*(1.0 - fabs(normA*z)));
	point3D<T> b_extents(radB*(1.0 - fabs(normB*x)),
					  radB*(1.0 - fabs(normB*y)),
					  radB*(1.0 - fabs(normB*z)));

	//create the AABB
	rtsAABB<T> result;

	//calculate the bounding box information
	//calculate bounding box position as the minima of all extents and positions
	result.minimum.x = min(posA.x - a_extents.x, posB.x - b_extents.x);
	result.minimum.y = min(posA.y - a_extents.y, posB.y - b_extents.y);
	result.minimum.z = min(posA.z - a_extents.z, posB.z - b_extents.z);

	//now find the size of the block
	result.maximum.x = max(posA.x + a_extents.x, posB.x + b_extents.x);
	result.maximum.y = max(posA.y + a_extents.y, posB.y + b_extents.y);
	result.maximum.z = max(posA.z + a_extents.z, posB.z + b_extents.z);
	
	return result;
}








#endif