You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
6.7 KiB
285 lines
6.7 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "vbsp.h" |
|
#include "BoundBox.h" |
|
//#include "hammer_mathlib.h" |
|
//#include "MapDefs.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
float V_rint(float f) |
|
{ |
|
if (f > 0.0f) { |
|
return (float) floor(f + 0.5f); |
|
} else if (f < 0.0f) { |
|
return (float) ceil(f - 0.5f); |
|
} else |
|
return 0.0f; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
BoundBox::BoundBox(void) |
|
{ |
|
ResetBounds(); |
|
} |
|
|
|
BoundBox::BoundBox(const Vector &mins, const Vector &maxs) |
|
{ |
|
bmins = mins; |
|
bmaxs = maxs; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sets the box to an uninitialized state, so that calls to UpdateBounds |
|
// will properly set the mins and maxs. |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::ResetBounds(void) |
|
{ |
|
bmins[0] = bmins[1] = bmins[2] = COORD_NOTINIT; |
|
bmaxs[0] = bmaxs[1] = bmaxs[2] = -COORD_NOTINIT; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : pt - |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::UpdateBounds(const Vector& pt) |
|
{ |
|
if(pt[0] < bmins[0]) |
|
bmins[0] = pt[0]; |
|
if(pt[1] < bmins[1]) |
|
bmins[1] = pt[1]; |
|
if(pt[2] < bmins[2]) |
|
bmins[2] = pt[2]; |
|
|
|
if(pt[0] > bmaxs[0]) |
|
bmaxs[0] = pt[0]; |
|
if(pt[1] > bmaxs[1]) |
|
bmaxs[1] = pt[1]; |
|
if(pt[2] > bmaxs[2]) |
|
bmaxs[2] = pt[2]; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : bmins - |
|
// bmaxs - |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::UpdateBounds(const Vector& mins, const Vector& maxs) |
|
{ |
|
if(mins[0] < bmins[0]) |
|
bmins[0] = mins[0]; |
|
if(mins[1] < bmins[1]) |
|
bmins[1] = mins[1]; |
|
if(mins[2] < bmins[2]) |
|
bmins[2] = mins[2]; |
|
|
|
if(maxs[0] > bmaxs[0]) |
|
bmaxs[0] = maxs[0]; |
|
if(maxs[1] > bmaxs[1]) |
|
bmaxs[1] = maxs[1]; |
|
if(maxs[2] > bmaxs[2]) |
|
bmaxs[2] = maxs[2]; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : pBox - |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::UpdateBounds(const BoundBox *pBox) |
|
{ |
|
UpdateBounds(pBox->bmins, pBox->bmaxs); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : ptdest - |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::GetBoundsCenter(Vector& ptdest) |
|
{ |
|
ptdest = (bmins + bmaxs)/2.0f; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : pt - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool BoundBox::ContainsPoint(const Vector& pt) const |
|
{ |
|
for (int i = 0; i < 3; i++) |
|
{ |
|
if (pt[i] < bmins[i] || pt[i] > bmaxs[i]) |
|
{ |
|
return(false); |
|
} |
|
} |
|
return(true); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : pfMins - |
|
// pfMaxs - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool BoundBox::IsIntersectingBox(const Vector& pfMins, const Vector& pfMaxs) const |
|
{ |
|
if ((bmins[0] >= pfMaxs[0]) || (bmaxs[0] <= pfMins[0])) |
|
{ |
|
return(false); |
|
|
|
} |
|
if ((bmins[1] >= pfMaxs[1]) || (bmaxs[1] <= pfMins[1])) |
|
{ |
|
return(false); |
|
} |
|
|
|
if ((bmins[2] >= pfMaxs[2]) || (bmaxs[2] <= pfMins[2])) |
|
{ |
|
return(false); |
|
} |
|
|
|
return(true); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : pfMins - |
|
// pfMaxs - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool BoundBox::IsInsideBox(const Vector& pfMins, const Vector& pfMaxs) const |
|
{ |
|
if ((bmins[0] < pfMins[0]) || (bmaxs[0] > pfMaxs[0])) |
|
{ |
|
return(false); |
|
} |
|
|
|
if ((bmins[1] < pfMins[1]) || (bmaxs[1] > pfMaxs[1])) |
|
{ |
|
return(false); |
|
} |
|
|
|
if ((bmins[2] < pfMins[2]) || (bmaxs[2] > pfMaxs[2])) |
|
{ |
|
return(false); |
|
} |
|
|
|
return(true); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Returns whether this bounding box is valid, ie maxs >= mins. |
|
//----------------------------------------------------------------------------- |
|
bool BoundBox::IsValidBox(void) const |
|
{ |
|
for (int i = 0; i < 3; i++) |
|
{ |
|
if (bmins[i] > bmaxs[i]) |
|
{ |
|
return(false); |
|
} |
|
} |
|
|
|
return(true); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : size - |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::GetBoundsSize(Vector& size) |
|
{ |
|
size[0] = bmaxs[0] - bmins[0]; |
|
size[1] = bmaxs[1] - bmins[1]; |
|
size[2] = bmaxs[2] - bmins[2]; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : iValue - |
|
// iGridSize - |
|
// Output : |
|
//----------------------------------------------------------------------------- |
|
static int Snap(/*int*/ float iValue, int iGridSize) |
|
{ |
|
return (int)(V_rint(iValue/iGridSize) * iGridSize); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : iGridSize - |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::SnapToGrid(int iGridSize) |
|
{ |
|
// does not alter the size of the box .. snaps its minimal coordinates |
|
// to the grid size specified in iGridSize |
|
Vector size; |
|
GetBoundsSize(size); |
|
|
|
for(int i = 0; i < 3; i++) |
|
{ |
|
bmins[i] = (float)Snap(/* YWB (int)*/bmins[i], iGridSize); |
|
bmaxs[i] = bmins[i] + size[i]; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : axis - |
|
//----------------------------------------------------------------------------- |
|
void BoundBox::Rotate90(int axis) |
|
{ |
|
int e1 = AXIS_X, e2 = AXIS_Y; |
|
|
|
// get bounds center first |
|
Vector center; |
|
GetBoundsCenter(center); |
|
|
|
switch(axis) |
|
{ |
|
case AXIS_Z: |
|
e1 = AXIS_X; |
|
e2 = AXIS_Y; |
|
break; |
|
case AXIS_X: |
|
e1 = AXIS_Y; |
|
e2 = AXIS_Z; |
|
break; |
|
case AXIS_Y: |
|
e1 = AXIS_X; |
|
e2 = AXIS_Z; |
|
break; |
|
} |
|
|
|
float tmp1, tmp2; |
|
tmp1 = bmins[e1] - center[e1] + center[e2]; |
|
tmp2 = bmaxs[e1] - center[e1] + center[e2]; |
|
bmins[e1] = bmins[e2] - center[e2] + center[e1]; |
|
bmaxs[e1] = bmaxs[e2] - center[e2] + center[e1]; |
|
bmins[e2] = tmp1; |
|
bmaxs[e2] = tmp2; |
|
} |
|
|
|
|