254 lines
7.6 KiB
C
254 lines
7.6 KiB
C
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
#ifndef __BV_BOUNDSSHORT_H__
|
||
|
#define __BV_BOUNDSSHORT_H__
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
Axis Aligned Bounding Box
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
class idBoundsShort {
|
||
|
public:
|
||
|
idBoundsShort( void );
|
||
|
explicit idBoundsShort( const idBounds &bounds );
|
||
|
|
||
|
void SetBounds( const idBounds &bounds );
|
||
|
|
||
|
void SetBounds( const short *list );
|
||
|
const short * GetBounds( void );
|
||
|
|
||
|
void AddPoint( const idVec3& a );
|
||
|
void AddBounds( const idBoundsShort& a );
|
||
|
|
||
|
void Combine( const idBoundsShort& x, const idBoundsShort& y );
|
||
|
|
||
|
void Clear( void ); // inside out bounds
|
||
|
void Zero( void ); // single point at origin
|
||
|
void Zero( const idVec3 ¢er ); // single point at center
|
||
|
|
||
|
bool IsCleared( void ) const; // returns true if bounds are inside out
|
||
|
|
||
|
float PlaneDistance( const idPlane &plane ) const;
|
||
|
int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
|
||
|
|
||
|
bool ContainsPoint( const idVec3 &p ) const;
|
||
|
bool ContainsPoint2D( const idVec3 &p ) const;
|
||
|
bool IntersectsBounds( const idBounds &a ) const;
|
||
|
bool IntersectsBounds( const idBoundsShort &a ) const;
|
||
|
bool IntersectsBounds2D( const idBoundsShort &a ) const;
|
||
|
|
||
|
int GetLargestAxis( void ) const;
|
||
|
|
||
|
const short* operator[]( const int index ) const { assert( index >= 0 && index < 2 ); return b[ index ]; }
|
||
|
short* operator[]( const int index ) { assert( index >= 0 && index < 2 ); return b[ index ]; }
|
||
|
|
||
|
idBoundsShort operator+( const idBoundsShort& a ) const;
|
||
|
|
||
|
idBounds ToBounds( void ) const;
|
||
|
|
||
|
void TranslateSelf( const idVec3& offset );
|
||
|
|
||
|
private:
|
||
|
short b[2][3];
|
||
|
};
|
||
|
|
||
|
extern idBoundsShort bounds_short_zero;
|
||
|
|
||
|
ID_INLINE idBoundsShort::idBoundsShort( void ) {
|
||
|
}
|
||
|
|
||
|
ID_INLINE idBoundsShort::idBoundsShort( const idBounds &bounds ) {
|
||
|
SetBounds( bounds );
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::SetBounds( const idBounds &bounds ) {
|
||
|
#if 0
|
||
|
// idMath::Ftoi doesn't always truncate, for example in this case:
|
||
|
/*
|
||
|
input[1] 1515.9961 const float
|
||
|
input[1] + 0xffff 67050.996093750000 double
|
||
|
b01 67051 int
|
||
|
*/
|
||
|
int b00 = idMath::Ftoi( bounds[0][0] + 0xffff );
|
||
|
int b01 = idMath::Ftoi( bounds[0][1] + 0xffff );
|
||
|
int b02 = idMath::Ftoi( bounds[0][2] + 0xffff );
|
||
|
int b10 = idMath::Ftoi( bounds[1][0] - 0xffff );
|
||
|
int b11 = idMath::Ftoi( bounds[1][1] - 0xffff );
|
||
|
int b12 = idMath::Ftoi( bounds[1][2] - 0xffff );
|
||
|
|
||
|
b[0][0] = b00 - 0xffff;
|
||
|
b[0][1] = b01 - 0xffff;
|
||
|
b[0][2] = b02 - 0xffff;
|
||
|
b[1][0] = b10 + 0xffff;
|
||
|
b[1][1] = b11 + 0xffff;
|
||
|
b[1][2] = b12 + 0xffff;
|
||
|
#else
|
||
|
b[0][0] = idMath::Ftoi( idMath::Floor( bounds[0][0] ) );
|
||
|
b[0][1] = idMath::Ftoi( idMath::Floor( bounds[0][1] ) );
|
||
|
b[0][2] = idMath::Ftoi( idMath::Floor( bounds[0][2] ) );
|
||
|
b[1][0] = idMath::Ftoi( idMath::Ceil( bounds[1][0] ) );
|
||
|
b[1][1] = idMath::Ftoi( idMath::Ceil( bounds[1][1] ) );
|
||
|
b[1][2] = idMath::Ftoi( idMath::Ceil( bounds[1][2] ) );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::SetBounds( const short *list ) {
|
||
|
b[0][0] = *list++;
|
||
|
b[0][1] = *list++;
|
||
|
b[0][2] = *list++;
|
||
|
b[1][0] = *list++;
|
||
|
b[1][1] = *list++;
|
||
|
b[1][2] = *list++;
|
||
|
}
|
||
|
|
||
|
ID_INLINE const short * idBoundsShort::GetBounds( void ) {
|
||
|
return b[0];
|
||
|
}
|
||
|
|
||
|
|
||
|
ID_INLINE void idBoundsShort::Clear( void ) {
|
||
|
b[0][0] = b[0][1] = b[0][2] = 32767;
|
||
|
b[1][0] = b[1][1] = b[1][2] = -32768;
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::Zero( void ) {
|
||
|
b[0][0] = b[0][1] = b[0][2] =
|
||
|
b[1][0] = b[1][1] = b[1][2] = 0;
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::Zero( const idVec3 ¢er ) {
|
||
|
b[0][0] = b[1][0] = idMath::Ftoi( center[0] + 0.5f );
|
||
|
b[0][1] = b[1][1] = idMath::Ftoi( center[1] + 0.5f );
|
||
|
b[0][2] = b[1][2] = idMath::Ftoi( center[2] + 0.5f );
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idBoundsShort::IsCleared( void ) const {
|
||
|
return b[0][0] > b[1][0];
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idBoundsShort::ContainsPoint( const idVec3 &p ) const {
|
||
|
if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2] ||
|
||
|
p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idBoundsShort::ContainsPoint2D( const idVec3 &p ) const {
|
||
|
if ( p[0] < b[0][0] || p[1] < b[0][1] || p[0] > b[1][0] || p[1] > b[1][1] ) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idBoundsShort::IntersectsBounds( const idBounds &a ) const {
|
||
|
if ( a.GetMaxs()[0] < b[0][0] || a.GetMaxs()[1] < b[0][1] || a.GetMaxs()[2] < b[0][2]
|
||
|
|| a.GetMins()[0] > b[1][0] || a.GetMins()[1] > b[1][1] || a.GetMins()[2] > b[1][2] ) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idBoundsShort::IntersectsBounds( const idBoundsShort &a ) const {
|
||
|
if ( a.b[1][0] < b[0][0] || a.b[1][1] < b[0][1] || a.b[1][2] < b[0][2]
|
||
|
|| a.b[0][0] > b[1][0] || a.b[0][1] > b[1][1] || a.b[0][2] > b[1][2] ) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idBoundsShort::IntersectsBounds2D( const idBoundsShort &a ) const {
|
||
|
if ( a.b[1][0] < b[0][0] || a.b[1][1] < b[0][1] || a.b[0][0] > b[1][0] || a.b[0][1] > b[1][1] ) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
ID_INLINE idBounds idBoundsShort::ToBounds( void ) const {
|
||
|
return idBounds( idVec3( b[0][0], b[0][1], b[0][2] ), idVec3( b[1][0], b[1][1], b[1][2] ) );
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::AddBounds( const idBoundsShort& a ) {
|
||
|
if ( a.b[0][0] < b[0][0] ) {
|
||
|
b[0][0] = a.b[0][0];
|
||
|
}
|
||
|
if ( a.b[0][1] < b[0][1] ) {
|
||
|
b[0][1] = a.b[0][1];
|
||
|
}
|
||
|
if ( a.b[0][2] < b[0][2] ) {
|
||
|
b[0][2] = a.b[0][2];
|
||
|
}
|
||
|
if ( a.b[1][0] > b[1][0] ) {
|
||
|
b[1][0] = a.b[1][0];
|
||
|
}
|
||
|
if ( a.b[1][1] > b[1][1] ) {
|
||
|
b[1][1] = a.b[1][1];
|
||
|
}
|
||
|
if ( a.b[1][2] > b[1][2] ) {
|
||
|
b[1][2] = a.b[1][2];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ID_INLINE idBoundsShort idBoundsShort::operator+( const idBoundsShort& a ) const {
|
||
|
idBoundsShort other;
|
||
|
other = *this;
|
||
|
other.AddBounds( a );
|
||
|
return other;
|
||
|
}
|
||
|
|
||
|
ID_INLINE int idBoundsShort::GetLargestAxis( void ) const {
|
||
|
short work[ 3 ];
|
||
|
work[ 0 ] = b[ 1 ][ 0 ] - b[ 0 ][ 0 ];
|
||
|
work[ 1 ] = b[ 1 ][ 1 ] - b[ 0 ][ 1 ];
|
||
|
work[ 2 ] = b[ 1 ][ 2 ] - b[ 0 ][ 2 ];
|
||
|
|
||
|
int axis = 0;
|
||
|
|
||
|
if ( work[ 1 ] > work[ 0 ] ) {
|
||
|
axis = 1;
|
||
|
}
|
||
|
|
||
|
if ( work[ 2 ] > work[ axis ] ) {
|
||
|
axis = 2;
|
||
|
}
|
||
|
|
||
|
return axis;
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::TranslateSelf( const idVec3& offset ) {
|
||
|
b[ 0 ][ 0 ] += idMath::Ftoi( idMath::Floor( offset[ 0 ] ) );
|
||
|
b[ 0 ][ 1 ] += idMath::Ftoi( idMath::Floor( offset[ 1 ] ) );
|
||
|
b[ 0 ][ 2 ] += idMath::Ftoi( idMath::Floor( offset[ 2 ] ) );
|
||
|
b[ 1 ][ 0 ] += idMath::Ftoi( idMath::Ceil( offset[ 0 ] ) );
|
||
|
b[ 1 ][ 1 ] += idMath::Ftoi( idMath::Ceil( offset[ 1 ] ) );
|
||
|
b[ 1 ][ 2 ] += idMath::Ftoi( idMath::Ceil( offset[ 2 ] ) );
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::Combine( const idBoundsShort& x, const idBoundsShort& y ) {
|
||
|
b[0][0] = ( x.b[0][0] < y.b[0][0] ) ? x.b[0][0] : y.b[0][0];
|
||
|
b[0][1] = ( x.b[0][1] < y.b[0][1] ) ? x.b[0][1] : y.b[0][1];
|
||
|
b[0][2] = ( x.b[0][2] < y.b[0][2] ) ? x.b[0][2] : y.b[0][2];
|
||
|
b[1][0] = ( x.b[1][0] > y.b[1][0] ) ? x.b[1][0] : y.b[1][0];
|
||
|
b[1][1] = ( x.b[1][1] > y.b[1][1] ) ? x.b[1][1] : y.b[1][1];
|
||
|
b[1][2] = ( x.b[1][2] > y.b[1][2] ) ? x.b[1][2] : y.b[1][2];
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idBoundsShort::AddPoint( const idVec3& x ) {
|
||
|
idBoundsShort temp;
|
||
|
temp.b[ 0 ][ 0 ] = idMath::Ftoi( idMath::Floor( x[ 0 ] ) );
|
||
|
temp.b[ 0 ][ 1 ] = idMath::Ftoi( idMath::Floor( x[ 1 ] ) );
|
||
|
temp.b[ 0 ][ 2 ] = idMath::Ftoi( idMath::Floor( x[ 2 ] ) );
|
||
|
temp.b[ 1 ][ 0 ] = idMath::Ftoi( idMath::Ceil( x[ 0 ] ) );
|
||
|
temp.b[ 1 ][ 1 ] = idMath::Ftoi( idMath::Ceil( x[ 1 ] ) );
|
||
|
temp.b[ 1 ][ 2 ] = idMath::Ftoi( idMath::Ceil( x[ 2 ] ) );
|
||
|
AddBounds( temp );
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif /* !__BV_BOUNDSSHORT_H__ */
|