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.

124 lines
3.9 KiB

  1. //--------------------------------------------------------------------------------------------------
  2. // qhMath.cpp
  3. //
  4. // Copyright(C) 2011 by D. Gregorius. All rights reserved.
  5. //--------------------------------------------------------------------------------------------------
  6. #include "qhMath.h"
  7. //--------------------------------------------------------------------------------------------------
  8. // Local utilities
  9. //--------------------------------------------------------------------------------------------------
  10. static inline qhBounds3 qhComputeBounds( const qhArray< qhVector3 >& Vertices, const qhTransform& Transform )
  11. {
  12. qhBounds3 Bounds = QH_BOUNDS3_EMPTY;
  13. for ( int Index = 0; Index < Vertices.Size(); ++Index )
  14. {
  15. Bounds += qhTMul( Transform, Vertices[ Index ] );
  16. }
  17. return Bounds;
  18. }
  19. //--------------------------------------------------------------------------------------------------
  20. // qhBox
  21. //--------------------------------------------------------------------------------------------------
  22. void qhBox::GetVertices( qhVector3 Vertices[ 8 ] ) const
  23. {
  24. Vertices[ 0 ] = Orientation * qhVector3( Extent.X, -Extent.Y, Extent.Z ) + Center;
  25. Vertices[ 1 ] = Orientation * qhVector3( -Extent.X, -Extent.Y, Extent.Z ) + Center;
  26. Vertices[ 2 ] = Orientation * qhVector3( -Extent.X, -Extent.Y, -Extent.Z ) + Center;
  27. Vertices[ 3 ] = Orientation * qhVector3( Extent.X, -Extent.Y, -Extent.Z ) + Center;
  28. Vertices[ 4 ] = Orientation * qhVector3( Extent.X, Extent.Y, Extent.Z ) + Center;
  29. Vertices[ 5 ] = Orientation * qhVector3( -Extent.X, Extent.Y, Extent.Z ) + Center;
  30. Vertices[ 6 ] = Orientation * qhVector3( -Extent.X, Extent.Y, -Extent.Z ) + Center;
  31. Vertices[ 7 ] = Orientation * qhVector3( Extent.X, Extent.Y, -Extent.Z ) + Center;
  32. }
  33. //--------------------------------------------------------------------------------------------------
  34. qhBox qhBestFit( const qhArray< qhVector3 >& Vertices, qhReal Threshold )
  35. {
  36. qhVector3 Center( 0, 0, 0 );
  37. for ( int Index = 0; Index < Vertices.Size(); ++Index )
  38. {
  39. Center += Vertices[ Index ];
  40. }
  41. Center = Center / float( Vertices.Size() );
  42. qhBox BestBox;
  43. qhReal BestVolume = QH_REAL_MAX;
  44. qhReal Sweep = qhReal( 45 );
  45. qhVector3 SweepCenter( 0, 0, 0 );
  46. while ( Sweep >= Threshold )
  47. {
  48. bool Improved = false;
  49. qhVector3 BestAngles;
  50. static const qhReal kSteps = 7.0;
  51. qhReal StepSize = Sweep / kSteps;
  52. for ( qhReal X = SweepCenter.X - Sweep; X <= SweepCenter.X + Sweep; X += StepSize )
  53. {
  54. for ( qhReal Y = SweepCenter.Y - Sweep; Y <= SweepCenter.Y + Sweep; Y += StepSize )
  55. {
  56. for ( qhReal Z = SweepCenter.Z - Sweep; Z <= SweepCenter.Z + Sweep; Z += StepSize )
  57. {
  58. qhQuaternion Rx = qhRotationX( X * QH_DEG2RAD );
  59. qhQuaternion Ry = qhRotationY( Y * QH_DEG2RAD );
  60. qhQuaternion Rz = qhRotationZ( Z * QH_DEG2RAD );
  61. qhQuaternion R = Rz * Ry * Rx;
  62. qhTransform Transform;
  63. Transform.Rotation = qhConvert( R );
  64. Transform.Translation = Center;
  65. qhBounds3 Bounds = qhComputeBounds( Vertices, Transform );
  66. float Volume = Bounds.GetVolume();
  67. if ( Volume < BestVolume )
  68. {
  69. BestBox.Center = Transform * Bounds.GetCenter();
  70. BestBox.Orientation = R;
  71. BestBox.Extent = Bounds.GetExtent();
  72. BestVolume = Volume;
  73. BestAngles = qhVector3( X, Y, Z );
  74. Improved = true;
  75. }
  76. }
  77. }
  78. }
  79. if ( Improved )
  80. {
  81. SweepCenter = BestAngles;
  82. Sweep *= 0.5f;
  83. }
  84. else
  85. {
  86. break;
  87. }
  88. }
  89. return BestBox;
  90. }
  91. //--------------------------------------------------------------------------------------------------
  92. qhBox qhBestFit( int VertexCount, const void* VertexBase, int VertexStride, qhReal Threshold )
  93. {
  94. qhArray< qhVector3 > Vertices;
  95. Vertices.Resize( VertexCount );
  96. for ( int Index = 0; Index < VertexCount; ++Index )
  97. {
  98. Vertices[ Index ] = qhVector3( reinterpret_cast< const qhReal* >( VertexBase ) );
  99. VertexBase = qhAddByteOffset( VertexBase, VertexStride );
  100. }
  101. return qhBestFit( Vertices, Threshold );
  102. }