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
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 );
|
|
}
|