The-Simpsons-Hit-and-Run/game/code/render/Culling/BoxPts.cpp

371 lines
7.9 KiB
C++

#include <render/culling/BoxPts.h>
#include <debug/profiler.h>
// ISpatialProxyAA
// <0.0 - Less than comparison object in posn
// =0.0 - Intersection with comparison object
// >0.0 - Greater than comparison object in posn
float BoxPts::CompareTo( AAPlane3f& irPlane )
{
if( irPlane.mPosn - msIntersectionEpsilon <= mBounds.mMin[(int)irPlane.mAxis] )
{
return -1.0f;
}
if( irPlane.mPosn + msIntersectionEpsilon >= mBounds.mMax[(int)irPlane.mAxis] )
{
return 1.0f;
}
return 0.0f;
}
bool BoxPts::DoesIntersect( AAPlane3f& irClipPlane )
{
rAssert(false);
return true;
}
bool BoxPts::DoesntIntersect( AAPlane3f& irClipPlane )
{
rAssert(false);
return true;
}
float BoxPts::TestNotOutsideMinX( ISpatialProxyAA& irSpatialProxy )
{
for( int i=irSpatialProxy.nPts()-2; i>-1; i-- )
{
if( irSpatialProxy.mPt(i).x >= mBounds.mMin.x )
{
//Inside
return -1.0f;
}
}
//Outside
return 1.0f;
}
float BoxPts::TestNotOutsideMinY( ISpatialProxyAA& irSpatialProxy )
{
for( int i=irSpatialProxy.nPts()-2; i>-1; i-- )
{
if( irSpatialProxy.mPt(i).y >= mBounds.mMin.y )
{
//Inside
return -1.0f;
}
}
//Outside
return 1.0f;
}
float BoxPts::TestNotOutsideMinZ( ISpatialProxyAA& irSpatialProxy )
{
for( int i=irSpatialProxy.nPts()-2; i>-1; i-- )
{
if( irSpatialProxy.mPt(i).z >= mBounds.mMin.z )
{
//Inside
return -1.0f;
}
}
//Outside
return 1.0f;
}
float BoxPts::TestNotOutsideMaxX( ISpatialProxyAA& irSpatialProxy )
{
for( int i=irSpatialProxy.nPts()-2; i>-1; i-- )
{
if( irSpatialProxy.mPt(i).x <= mBounds.mMax.x )
{
//Inside
return -1.0f;
}
}
//Outside
return 1.0f;
}
float BoxPts::TestNotOutsideMaxY( ISpatialProxyAA& irSpatialProxy )
{
for( int i=irSpatialProxy.nPts()-2; i>-1; i-- )
{
if( irSpatialProxy.mPt(i).y <= mBounds.mMax.y )
{
//Inside
return -1.0f;
}
}
//Outside
return 1.0f;
}
float BoxPts::TestNotOutsideMaxZ( ISpatialProxyAA& irSpatialProxy )
{
for( int i=irSpatialProxy.nPts()-2; i>-1; i-- )
{
if( irSpatialProxy.mPt(i).z <= mBounds.mMax.z )
{
//Inside
return -1.0f;
}
}
//Outside
return 1.0f;
}
int BoxPts::nPts()
{
return msPtCount;
}
Vector3f BoxPts::mPt( int iIndex )
{
switch(iIndex)
{
case 0:
return mBounds.mMin;
break;
case 1:
return Vector3f( mBounds.mMin.x, mBounds.mMin.y, mBounds.mMax.z );
break;
case 2:
return Vector3f( mBounds.mMin.x, mBounds.mMax.y, mBounds.mMin.z );
break;
case 3:
return Vector3f( mBounds.mMax.x, mBounds.mMin.y, mBounds.mMin.z );
break;
case 4:
return Vector3f( mBounds.mMin.x, mBounds.mMax.y, mBounds.mMax.z );
break;
case 5:
return Vector3f( mBounds.mMax.x, mBounds.mMax.y, mBounds.mMin.z );
break;
case 6:
return Vector3f( mBounds.mMax.x, mBounds.mMin.y, mBounds.mMax.z );
break;
case 7:
return mBounds.mMax;
break;
default:
rAssert(false);
return mBounds.mMin;
break;
/*
m[0] = irBounds.mMin;
m[1].x = irBounds.mMin.x;
m[1].y = irBounds.mMin.y;
m[1].z = irBounds.mMax.z;
m[2].x = irBounds.mMin.x;
m[2].y = irBounds.mMax.y;
m[2].z = irBounds.mMin.z;
m[3].x = irBounds.mMax.x;
m[3].y = irBounds.mMin.y;
m[3].z = irBounds.mMin.z;
m[4].x = irBounds.mMin.x;
m[4].y = irBounds.mMax.y;
m[4].z = irBounds.mMax.z;
m[5].x = irBounds.mMax.x;
m[5].y = irBounds.mMax.y;
m[5].z = irBounds.mMin.z;
m[6].x = irBounds.mMax.x;
m[6].y = irBounds.mMin.y;
m[6].z = irBounds.mMax.z;
m[7] = irBounds.mMax;
*/
}
}
Vector3f BoxPts::GetPoint()
{
return mBounds.mMin;
}
void BoxPts::CutOffGT( AAPlane3f& irPlane3f )
{
if( mBounds.mMax[(int)irPlane3f.mAxis] > irPlane3f.mPosn )
{
mBounds.mMax[(int)irPlane3f.mAxis] = irPlane3f.mPosn;
if( mBounds.mMin[(int)irPlane3f.mAxis] > irPlane3f.mPosn )
{
mBounds.mMin[(int)irPlane3f.mAxis] = irPlane3f.mPosn;
}
}
//Temporary debug;
//Though it's conceivable that you'd want to cut a box down into a plane,
//SpatialIterators don't want to.
rAssert( mBounds.mMin[(int)irPlane3f.mAxis] != mBounds.mMax[(int)irPlane3f.mAxis] );
}
void BoxPts::CutOffLT( AAPlane3f& irPlane3f )
{
if( mBounds.mMin[(int)irPlane3f.mAxis] < irPlane3f.mPosn )
{
mBounds.mMin[(int)irPlane3f.mAxis] = irPlane3f.mPosn;
if( mBounds.mMax[(int)irPlane3f.mAxis] < irPlane3f.mPosn )
{
mBounds.mMax[(int)irPlane3f.mAxis] = irPlane3f.mPosn;
}
}
//Temporary debug;
//Though it's conceivable that you'd want to cut a box down into a plane,
//SpatialIterators don't want to.
rAssert( mBounds.mMin[(int)irPlane3f.mAxis] != mBounds.mMax[(int)irPlane3f.mAxis] );
}
float BoxPts::CompareTo( const Vector3f& irPoint )
{
if( irPoint.x < mBounds.mMin.x )
return 1.0f;
if( irPoint.y < mBounds.mMin.y )
return 1.0f;
if( irPoint.z < mBounds.mMin.z )
return 1.0f;
if( irPoint.x > mBounds.mMax.x )
return 1.0f;
if( irPoint.y > mBounds.mMax.y )
return 1.0f;
if( irPoint.z > mBounds.mMax.z )
return 1.0f;
return -1.0f;
}
float BoxPts::CompareToXZ( const Vector3f& irPoint )
{
if( irPoint.x < mBounds.mMin.x )
return 1.0f;
if( irPoint.z < mBounds.mMin.z )
return 1.0f;
if( irPoint.x > mBounds.mMax.x )
return 1.0f;
if( irPoint.z > mBounds.mMax.z )
return 1.0f;
return -1.0f;
}
void BoxPts::SetTo( Bounds3f& irBounds )
{
mBounds = irBounds;
}
Vector3f BoxPts::operator[]( int i )
{
return mPt(i);
}
// <0.0 - Inside Spatial Proxy
// =0.0 - On Spatial Proxy Surface
// >0.0 - Outside Spatial Proxy
float BoxPts::TestNotOutside( ISpatialProxyAA& irSpatialProxy )
{
//BEGIN_PROFILE("BoxPts::TestNotOutside")
Vector3f testPt( irSpatialProxy.mPt(irSpatialProxy.nPts()-1) );
//Test the first Pt, if it's outside a plane,
//ensure all other pts are outside the same plane
//Gives false positives for crossing the corner on the outside
/*
if( testPt.x < mBounds.mMin.x )
return TestNotOutsideMinX( irSpatialProxy );
if( testPt.y < mBounds.mMin.y )
return TestNotOutsideMinY( irSpatialProxy );
if( testPt.z < mBounds.mMin.z )
return TestNotOutsideMinZ( irSpatialProxy );
if( testPt.x > mBounds.mMax.x )
return TestNotOutsideMaxX( irSpatialProxy );
if( testPt.y > mBounds.mMax.y )
return TestNotOutsideMaxY( irSpatialProxy );
if( testPt.z > mBounds.mMax.z )
return TestNotOutsideMinZ( irSpatialProxy );
*/
if( testPt.x < mBounds.mMin.x )
{
if( TestNotOutsideMinX( irSpatialProxy ) > 0.0f )
{
//END_PROFILE("BoxPts::TestNotOutside")
return 1.0f;
}
}
else if( testPt.x > mBounds.mMax.x )
{
if( TestNotOutsideMaxX( irSpatialProxy ) > 0.0f )
{
//END_PROFILE("BoxPts::TestNotOutside")
return 1.0f;
}
}
if( testPt.y < mBounds.mMin.y )
{
if( TestNotOutsideMinY( irSpatialProxy ) > 0.0f )
{
//END_PROFILE("BoxPts::TestNotOutside")
return 1.0f;
}
}
else if( testPt.y > mBounds.mMax.y )
{
if( TestNotOutsideMaxY( irSpatialProxy ) > 0.0f )
{
//END_PROFILE("BoxPts::TestNotOutside")
return 1.0f;
}
}
if( testPt.z < mBounds.mMin.z )
{
if( TestNotOutsideMinZ( irSpatialProxy ) > 0.0f )
{
//END_PROFILE("BoxPts::TestNotOutside")
return 1.0f;
}
}
else if( testPt.z > mBounds.mMax.z )
{
if( TestNotOutsideMaxZ( irSpatialProxy ) > 0.0f )
{
//END_PROFILE("BoxPts::TestNotOutside")
return 1.0f;
}
}
//END_PROFILE("BoxPts::TestNotOutside")
return -1.0f;
}