#ifndef RTS_BOUNDING_VOLUMES #define RTS_BOUNDING_VOLUMES #include "rtsLinearAlgebra.h" #include template class rtsAABB { public: point3D minimum; point3D maximum; //overloaded operators rtsAABB operator+(rtsAABB param); rtsAABB getGridAlignedAABB(); inline bool isIn(T x, T y, T z); }; template class rtsBoundingSphere { public: point3D center; T radius; inline bool isIn(T x, T y, T z); }; template class rtsTGC { public: point3D posA; point3D posB; vector3D normA; vector3D normB; T radA; T radB; rtsAABB BoundAABB(); }; template rtsAABB rtsAABB::operator+(rtsAABB param) { /* This function creates an AABB by finding the minimum bound of two other AABBs. */ rtsAABB 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 inline bool rtsAABB::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 inline bool rtsBoundingSphere::isIn(T x, T y, T z) { vector3D to_point = center - point3D(x, y, z); T length_squared = to_point*to_point; if(length_squared < radius*radius) return true; else return false; } template rtsAABB rtsAABB::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 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 rtsAABB rtsTGC::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 x(1.0, 0.0, 0.0); vector3D y(0.0, 1.0, 0.0); vector3D z(0.0, 0.0, 1.0); //store the extents point3D a_extents(radA*(1.0 - fabs(normA*x)), radA*(1.0 - fabs(normA*y)), radA*(1.0 - fabs(normA*z))); point3D b_extents(radB*(1.0 - fabs(normB*x)), radB*(1.0 - fabs(normB*y)), radB*(1.0 - fabs(normB*z))); //create the AABB rtsAABB 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