mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-12-11 21:40:49 +00:00
736ec20d4d
Don't include the lazy precompiled.h everywhere, only what's required for the compilation unit. platform.h needs to be included instead to provide all essential defines and types. All includes use the relative path to the neo or the game specific root. Move all idlib related includes from idlib/Lib.h to precompiled.h. precompiled.h still exists for the MFC stuff in tools/. Add some missing header guards.
300 lines
10 KiB
C++
300 lines
10 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
|
|
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#ifndef __BV_BOX_H__
|
|
#define __BV_BOX_H__
|
|
|
|
#include "idlib/math/Vector.h"
|
|
#include "idlib/bv/Bounds.h"
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
Oriented Bounding Box
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
class idBox {
|
|
public:
|
|
idBox( void );
|
|
explicit idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis );
|
|
explicit idBox( const idVec3 &point );
|
|
explicit idBox( const idBounds &bounds );
|
|
explicit idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis );
|
|
|
|
idBox operator+( const idVec3 &t ) const; // returns translated box
|
|
idBox & operator+=( const idVec3 &t ); // translate the box
|
|
idBox operator*( const idMat3 &r ) const; // returns rotated box
|
|
idBox & operator*=( const idMat3 &r ); // rotate the box
|
|
idBox operator+( const idBox &a ) const;
|
|
idBox & operator+=( const idBox &a );
|
|
idBox operator-( const idBox &a ) const;
|
|
idBox & operator-=( const idBox &a );
|
|
|
|
bool Compare( const idBox &a ) const; // exact compare, no epsilon
|
|
bool Compare( const idBox &a, const float epsilon ) const; // compare with epsilon
|
|
bool operator==( const idBox &a ) const; // exact compare, no epsilon
|
|
bool operator!=( const idBox &a ) const; // exact compare, no epsilon
|
|
|
|
void Clear( void ); // inside out box
|
|
void Zero( void ); // single point at origin
|
|
|
|
const idVec3 & GetCenter( void ) const; // returns center of the box
|
|
const idVec3 & GetExtents( void ) const; // returns extents of the box
|
|
const idMat3 & GetAxis( void ) const; // returns the axis of the box
|
|
float GetVolume( void ) const; // returns the volume of the box
|
|
bool IsCleared( void ) const; // returns true if box are inside out
|
|
|
|
bool AddPoint( const idVec3 &v ); // add the point, returns true if the box expanded
|
|
bool AddBox( const idBox &a ); // add the box, returns true if the box expanded
|
|
idBox Expand( const float d ) const; // return box expanded in all directions with the given value
|
|
idBox & ExpandSelf( const float d ); // expand box in all directions with the given value
|
|
idBox Translate( const idVec3 &translation ) const; // return translated box
|
|
idBox & TranslateSelf( const idVec3 &translation ); // translate this box
|
|
idBox Rotate( const idMat3 &rotation ) const; // return rotated box
|
|
idBox & RotateSelf( const idMat3 &rotation ); // rotate this box
|
|
|
|
float PlaneDistance( const idPlane &plane ) const;
|
|
int PlaneSide( const idPlane &plane, const float epsilon = ON_EPSILON ) const;
|
|
|
|
bool ContainsPoint( const idVec3 &p ) const; // includes touching
|
|
bool IntersectsBox( const idBox &a ) const; // includes touching
|
|
bool LineIntersection( const idVec3 &start, const idVec3 &end ) const;
|
|
// intersection points are (start + dir * scale1) and (start + dir * scale2)
|
|
bool RayIntersection( const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2 ) const;
|
|
|
|
// tight box for a collection of points
|
|
void FromPoints( const idVec3 *points, const int numPoints );
|
|
// most tight box for a translation
|
|
void FromPointTranslation( const idVec3 &point, const idVec3 &translation );
|
|
void FromBoxTranslation( const idBox &box, const idVec3 &translation );
|
|
// most tight box for a rotation
|
|
void FromPointRotation( const idVec3 &point, const idRotation &rotation );
|
|
void FromBoxRotation( const idBox &box, const idRotation &rotation );
|
|
|
|
void ToPoints( idVec3 points[8] ) const;
|
|
idSphere ToSphere( void ) const;
|
|
|
|
// calculates the projection of this box onto the given axis
|
|
void AxisProjection( const idVec3 &dir, float &min, float &max ) const;
|
|
void AxisProjection( const idMat3 &ax, idBounds &bounds ) const;
|
|
|
|
// calculates the silhouette of the box
|
|
int GetProjectionSilhouetteVerts( const idVec3 &projectionOrigin, idVec3 silVerts[6] ) const;
|
|
int GetParallelProjectionSilhouetteVerts( const idVec3 &projectionDir, idVec3 silVerts[6] ) const;
|
|
|
|
private:
|
|
idVec3 center;
|
|
idVec3 extents;
|
|
idMat3 axis;
|
|
};
|
|
|
|
extern idBox box_zero;
|
|
|
|
ID_INLINE idBox::idBox( void ) {
|
|
}
|
|
|
|
ID_INLINE idBox::idBox( const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis ) {
|
|
this->center = center;
|
|
this->extents = extents;
|
|
this->axis = axis;
|
|
}
|
|
|
|
ID_INLINE idBox::idBox( const idVec3 &point ) {
|
|
this->center = point;
|
|
this->extents.Zero();
|
|
this->axis.Identity();
|
|
}
|
|
|
|
ID_INLINE idBox::idBox( const idBounds &bounds ) {
|
|
this->center = ( bounds[0] + bounds[1] ) * 0.5f;
|
|
this->extents = bounds[1] - this->center;
|
|
this->axis.Identity();
|
|
}
|
|
|
|
ID_INLINE idBox::idBox( const idBounds &bounds, const idVec3 &origin, const idMat3 &axis ) {
|
|
this->center = ( bounds[0] + bounds[1] ) * 0.5f;
|
|
this->extents = bounds[1] - this->center;
|
|
this->center = origin + this->center * axis;
|
|
this->axis = axis;
|
|
}
|
|
|
|
ID_INLINE idBox idBox::operator+( const idVec3 &t ) const {
|
|
return idBox( center + t, extents, axis );
|
|
}
|
|
|
|
ID_INLINE idBox &idBox::operator+=( const idVec3 &t ) {
|
|
center += t;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE idBox idBox::operator*( const idMat3 &r ) const {
|
|
return idBox( center * r, extents, axis * r );
|
|
}
|
|
|
|
ID_INLINE idBox &idBox::operator*=( const idMat3 &r ) {
|
|
center *= r;
|
|
axis *= r;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE idBox idBox::operator+( const idBox &a ) const {
|
|
idBox newBox;
|
|
newBox = *this;
|
|
newBox.AddBox( a );
|
|
return newBox;
|
|
}
|
|
|
|
ID_INLINE idBox &idBox::operator+=( const idBox &a ) {
|
|
idBox::AddBox( a );
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE idBox idBox::operator-( const idBox &a ) const {
|
|
return idBox( center, extents - a.extents, axis );
|
|
}
|
|
|
|
ID_INLINE idBox &idBox::operator-=( const idBox &a ) {
|
|
extents -= a.extents;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE bool idBox::Compare( const idBox &a ) const {
|
|
return ( center.Compare( a.center ) && extents.Compare( a.extents ) && axis.Compare( a.axis ) );
|
|
}
|
|
|
|
ID_INLINE bool idBox::Compare( const idBox &a, const float epsilon ) const {
|
|
return ( center.Compare( a.center, epsilon ) && extents.Compare( a.extents, epsilon ) && axis.Compare( a.axis, epsilon ) );
|
|
}
|
|
|
|
ID_INLINE bool idBox::operator==( const idBox &a ) const {
|
|
return Compare( a );
|
|
}
|
|
|
|
ID_INLINE bool idBox::operator!=( const idBox &a ) const {
|
|
return !Compare( a );
|
|
}
|
|
|
|
ID_INLINE void idBox::Clear( void ) {
|
|
center.Zero();
|
|
extents[0] = extents[1] = extents[2] = -idMath::INFINITY;
|
|
axis.Identity();
|
|
}
|
|
|
|
ID_INLINE void idBox::Zero( void ) {
|
|
center.Zero();
|
|
extents.Zero();
|
|
axis.Identity();
|
|
}
|
|
|
|
ID_INLINE const idVec3 &idBox::GetCenter( void ) const {
|
|
return center;
|
|
}
|
|
|
|
ID_INLINE const idVec3 &idBox::GetExtents( void ) const {
|
|
return extents;
|
|
}
|
|
|
|
ID_INLINE const idMat3 &idBox::GetAxis( void ) const {
|
|
return axis;
|
|
}
|
|
|
|
ID_INLINE float idBox::GetVolume( void ) const {
|
|
return ( extents * 2.0f ).LengthSqr();
|
|
}
|
|
|
|
ID_INLINE bool idBox::IsCleared( void ) const {
|
|
return extents[0] < 0.0f;
|
|
}
|
|
|
|
ID_INLINE idBox idBox::Expand( const float d ) const {
|
|
return idBox( center, extents + idVec3( d, d, d ), axis );
|
|
}
|
|
|
|
ID_INLINE idBox &idBox::ExpandSelf( const float d ) {
|
|
extents[0] += d;
|
|
extents[1] += d;
|
|
extents[2] += d;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE idBox idBox::Translate( const idVec3 &translation ) const {
|
|
return idBox( center + translation, extents, axis );
|
|
}
|
|
|
|
ID_INLINE idBox &idBox::TranslateSelf( const idVec3 &translation ) {
|
|
center += translation;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE idBox idBox::Rotate( const idMat3 &rotation ) const {
|
|
return idBox( center * rotation, extents, axis * rotation );
|
|
}
|
|
|
|
ID_INLINE idBox &idBox::RotateSelf( const idMat3 &rotation ) {
|
|
center *= rotation;
|
|
axis *= rotation;
|
|
return *this;
|
|
}
|
|
|
|
ID_INLINE bool idBox::ContainsPoint( const idVec3 &p ) const {
|
|
idVec3 lp = p - center;
|
|
if ( idMath::Fabs( lp * axis[0] ) > extents[0] ||
|
|
idMath::Fabs( lp * axis[1] ) > extents[1] ||
|
|
idMath::Fabs( lp * axis[2] ) > extents[2] ) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
ID_INLINE idSphere idBox::ToSphere( void ) const {
|
|
return idSphere( center, extents.Length() );
|
|
}
|
|
|
|
ID_INLINE void idBox::AxisProjection( const idVec3 &dir, float &min, float &max ) const {
|
|
float d1 = dir * center;
|
|
float d2 = idMath::Fabs( extents[0] * ( dir * axis[0] ) ) +
|
|
idMath::Fabs( extents[1] * ( dir * axis[1] ) ) +
|
|
idMath::Fabs( extents[2] * ( dir * axis[2] ) );
|
|
min = d1 - d2;
|
|
max = d1 + d2;
|
|
}
|
|
|
|
ID_INLINE void idBox::AxisProjection( const idMat3 &ax, idBounds &bounds ) const {
|
|
for ( int i = 0; i < 3; i++ ) {
|
|
float d1 = ax[i] * center;
|
|
float d2 = idMath::Fabs( extents[0] * ( ax[i] * axis[0] ) ) +
|
|
idMath::Fabs( extents[1] * ( ax[i] * axis[1] ) ) +
|
|
idMath::Fabs( extents[2] * ( ax[i] * axis[2] ) );
|
|
bounds[0][i] = d1 - d2;
|
|
bounds[1][i] = d1 + d2;
|
|
}
|
|
}
|
|
|
|
#endif /* !__BV_BOX_H__ */
|