//----------------------------------------------------------- // // Name: Bound.h // Last Update: 25/11/03 // Author: Rich Cross // Contact: rich@0ad.wildfiregames.com // // Description: Basic axis aligned bounding box class // //----------------------------------------------------------- // necessary includes #include #include "Bound.h" //----------------------------------------------------------- // operator+=: extend this bound to include given bound //----------------------------------------------------------- CBound& CBound::operator+=(const CBound& b) { for (int i=0;i<3;++i) { if (b[0][i]m_Data[1][i]) m_Data[1][i]=b[1][i]; } return *this; } //----------------------------------------------------------- // operator+=: extend this bound to include given point //----------------------------------------------------------- CBound& CBound::operator+=(const CVector3D& pt) { for (int i=0;i<3;++i) { if (pt[i]m_Data[1][i]) m_Data[1][i]=pt[i]; } return *this; } //----------------------------------------------------------- // RayIntersect: intersect ray with this bound; return true // if ray hits (and store entry and exit times), or false // otherwise // note: incoming ray direction must be normalised //----------------------------------------------------------- bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir, float& tmin,float& tmax) const { float t1,t2; float tnear,tfar; if (dir[0]==0) { if (origin[0]m_Data[1][0]) return false; else { tnear=(float) FLT_MIN; tfar=(float) FLT_MAX; } } else { t1=(m_Data[0][0]-origin[0])/dir[0]; t2=(m_Data[1][0]-origin[0])/dir[0]; if (dir[0]<0) { tnear = t2; tfar = t1; } else { tnear = t1; tfar = t2; } if (tfar<0) return false; } if (dir[1]==0 && (origin[1]m_Data[1][1])) return false; else { t1=(m_Data[0][1]-origin[1])/dir[1]; t2=(m_Data[1][1]-origin[1])/dir[1]; if (dir[1]<0) { if (t2>tnear) tnear = t2; if (t1tnear) tnear = t1; if (t2tfar || tfar<0) return false; } if (dir[2]==0 && (origin[2]m_Data[1][2])) return false; else { t1=(m_Data[0][2]-origin[2])/dir[2]; t2=(m_Data[1][2]-origin[2])/dir[2]; if (dir[2]<0) { if (t2>tnear) tnear = t2; if (t1tnear) tnear = t1; if (t2tfar || tfar<0) return false; } tmin=tnear; tmax=tfar; return true; } //----------------------------------------------------------- // SetEmpty: initialise this bound as empty //----------------------------------------------------------- void CBound::SetEmpty() { m_Data[0]=CVector3D(FLT_MAX,FLT_MAX,FLT_MAX); m_Data[1]=CVector3D(FLT_MIN,FLT_MIN,FLT_MIN); }