forked from 0ad/0ad
cc2b6afdac
This was SVN commit r96.
141 lines
3.3 KiB
C++
Executable File
141 lines
3.3 KiB
C++
Executable File
//-----------------------------------------------------------
|
|
//
|
|
// 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 <float.h>
|
|
#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[0][i])
|
|
m_Data[0][i]=b[0][i];
|
|
if (b[1][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[0][i])
|
|
m_Data[0][i]=pt[i];
|
|
else 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[0][0] || 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[0][1] || 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 (t1<tfar)
|
|
tfar = t1;
|
|
} else {
|
|
if (t1>tnear)
|
|
tnear = t1;
|
|
if (t2<tfar)
|
|
tfar = t2;
|
|
}
|
|
|
|
if (tnear>tfar || tfar<0)
|
|
return false;
|
|
}
|
|
|
|
if (dir[2]==0 && (origin[2]<m_Data[0][2] || 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 (t1<tfar)
|
|
tfar = t1;
|
|
} else {
|
|
if (t1>tnear)
|
|
tnear = t1;
|
|
if (t2<tfar)
|
|
tfar = t2;
|
|
}
|
|
|
|
if (tnear>tfar || 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);
|
|
}
|
|
|
|
|