Counter Strike : Global Offensive Source Code
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.
 
 
 
 
 
 

125 lines
3.9 KiB

//--------------------------------------------------------------------------------------------------
// qhMath.cpp
//
// Copyright(C) 2011 by D. Gregorius. All rights reserved.
//--------------------------------------------------------------------------------------------------
#include "qhMath.h"
//--------------------------------------------------------------------------------------------------
// Local utilities
//--------------------------------------------------------------------------------------------------
static inline qhBounds3 qhComputeBounds( const qhArray< qhVector3 >& Vertices, const qhTransform& Transform )
{
qhBounds3 Bounds = QH_BOUNDS3_EMPTY;
for ( int Index = 0; Index < Vertices.Size(); ++Index )
{
Bounds += qhTMul( Transform, Vertices[ Index ] );
}
return Bounds;
}
//--------------------------------------------------------------------------------------------------
// qhBox
//--------------------------------------------------------------------------------------------------
void qhBox::GetVertices( qhVector3 Vertices[ 8 ] ) const
{
Vertices[ 0 ] = Orientation * qhVector3( Extent.X, -Extent.Y, Extent.Z ) + Center;
Vertices[ 1 ] = Orientation * qhVector3( -Extent.X, -Extent.Y, Extent.Z ) + Center;
Vertices[ 2 ] = Orientation * qhVector3( -Extent.X, -Extent.Y, -Extent.Z ) + Center;
Vertices[ 3 ] = Orientation * qhVector3( Extent.X, -Extent.Y, -Extent.Z ) + Center;
Vertices[ 4 ] = Orientation * qhVector3( Extent.X, Extent.Y, Extent.Z ) + Center;
Vertices[ 5 ] = Orientation * qhVector3( -Extent.X, Extent.Y, Extent.Z ) + Center;
Vertices[ 6 ] = Orientation * qhVector3( -Extent.X, Extent.Y, -Extent.Z ) + Center;
Vertices[ 7 ] = Orientation * qhVector3( Extent.X, Extent.Y, -Extent.Z ) + Center;
}
//--------------------------------------------------------------------------------------------------
qhBox qhBestFit( const qhArray< qhVector3 >& Vertices, qhReal Threshold )
{
qhVector3 Center( 0, 0, 0 );
for ( int Index = 0; Index < Vertices.Size(); ++Index )
{
Center += Vertices[ Index ];
}
Center = Center / float( Vertices.Size() );
qhBox BestBox;
qhReal BestVolume = QH_REAL_MAX;
qhReal Sweep = qhReal( 45 );
qhVector3 SweepCenter( 0, 0, 0 );
while ( Sweep >= Threshold )
{
bool Improved = false;
qhVector3 BestAngles;
static const qhReal kSteps = 7.0;
qhReal StepSize = Sweep / kSteps;
for ( qhReal X = SweepCenter.X - Sweep; X <= SweepCenter.X + Sweep; X += StepSize )
{
for ( qhReal Y = SweepCenter.Y - Sweep; Y <= SweepCenter.Y + Sweep; Y += StepSize )
{
for ( qhReal Z = SweepCenter.Z - Sweep; Z <= SweepCenter.Z + Sweep; Z += StepSize )
{
qhQuaternion Rx = qhRotationX( X * QH_DEG2RAD );
qhQuaternion Ry = qhRotationY( Y * QH_DEG2RAD );
qhQuaternion Rz = qhRotationZ( Z * QH_DEG2RAD );
qhQuaternion R = Rz * Ry * Rx;
qhTransform Transform;
Transform.Rotation = qhConvert( R );
Transform.Translation = Center;
qhBounds3 Bounds = qhComputeBounds( Vertices, Transform );
float Volume = Bounds.GetVolume();
if ( Volume < BestVolume )
{
BestBox.Center = Transform * Bounds.GetCenter();
BestBox.Orientation = R;
BestBox.Extent = Bounds.GetExtent();
BestVolume = Volume;
BestAngles = qhVector3( X, Y, Z );
Improved = true;
}
}
}
}
if ( Improved )
{
SweepCenter = BestAngles;
Sweep *= 0.5f;
}
else
{
break;
}
}
return BestBox;
}
//--------------------------------------------------------------------------------------------------
qhBox qhBestFit( int VertexCount, const void* VertexBase, int VertexStride, qhReal Threshold )
{
qhArray< qhVector3 > Vertices;
Vertices.Resize( VertexCount );
for ( int Index = 0; Index < VertexCount; ++Index )
{
Vertices[ Index ] = qhVector3( reinterpret_cast< const qhReal* >( VertexBase ) );
VertexBase = qhAddByteOffset( VertexBase, VertexStride );
}
return qhBestFit( Vertices, Threshold );
}