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.

143 lines
4.0 KiB

  1. //=========== Copyright � Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Quadric math functionality used for squared distance error metrics.
  4. //
  5. //===========================================================================//
  6. #ifndef QUADRIC_H
  7. #define QUADRIC_H
  8. #if defined( COMPILER_MSVC )
  9. #pragma once
  10. #endif
  11. #include "vector.h"
  12. #include "cholesky.h"
  13. // this class holds a quadric error function and implements integrating and evaluating these functions.
  14. // see "Surface Simplfication using Quadric Error metrics. Garland, Heckbert"
  15. // http://mgarland.org/files/papers/quadric2.pdf (updated version)
  16. // NOTE: This will be expanded using Hughes Hoppe's method for including interpolated vertex attributes in a future version
  17. class CQuadricError
  18. {
  19. public:
  20. CQuadricError() {}
  21. // used this to track down error
  22. void CheckDebug()
  23. {
  24. Assert( IsFinite(m_coefficients[0]) );
  25. }
  26. // integrate these by summing coefficients
  27. FORCEINLINE CQuadricError& operator+=(const CQuadricError &inError)
  28. {
  29. for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
  30. {
  31. m_coefficients[i] += inError.m_coefficients[i];
  32. }
  33. return *this;
  34. }
  35. CQuadricError operator+(const CQuadricError& inError0 ) const
  36. {
  37. CQuadricError tmp;
  38. for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
  39. {
  40. tmp.m_coefficients[i] = inError0.m_coefficients[i] + m_coefficients[i];
  41. }
  42. return tmp;
  43. }
  44. // assignment
  45. CQuadricError& operator=(const CQuadricError &inError0)
  46. {
  47. for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
  48. {
  49. m_coefficients[i] = inError0.m_coefficients[i];
  50. }
  51. return *this;
  52. }
  53. CQuadricError& operator*=( float flScale )
  54. {
  55. for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
  56. {
  57. m_coefficients[i] *= flScale;
  58. }
  59. return *this;
  60. }
  61. // solves for the point with minimum error (inverts the matrix)
  62. Vector SolveForMinimumError()
  63. {
  64. matrix3x4_t tmp(
  65. m_coefficients[0], m_coefficients[1]*0.5f, m_coefficients[2]*0.5f, m_coefficients[3]*0.5f,
  66. m_coefficients[1]*0.5f, m_coefficients[4], m_coefficients[5]*0.5f, m_coefficients[6]*0.5f,
  67. m_coefficients[2]*0.5f, m_coefficients[5]*0.5f, m_coefficients[7], m_coefficients[8]*0.5f );
  68. return CholeskySolve( tmp );
  69. }
  70. // clear all coefficients
  71. void SetToZero()
  72. {
  73. for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
  74. {
  75. m_coefficients[i] = 0.0f;
  76. }
  77. }
  78. // usually these are initialized by summing quadrics for the planes coincident at each vert (one per triangle)
  79. // these are helpers to do that
  80. void InitFromPlane( const Vector &vNormal, float flDist, float flScale )
  81. {
  82. float flScale2 = flScale * 2.0f;
  83. m_coefficients[0] = vNormal.x * vNormal.x * flScale; // a^2
  84. m_coefficients[1] = vNormal.x * vNormal.y * flScale2; // 2ab
  85. m_coefficients[2] = vNormal.x * vNormal.z * flScale2; // 2ac
  86. m_coefficients[3] = vNormal.x * flDist * flScale2; // 2ad
  87. m_coefficients[4] = vNormal.y * vNormal.y * flScale; // b^2
  88. m_coefficients[5] = vNormal.y * vNormal.z * flScale2; // 2bc
  89. m_coefficients[6] = vNormal.y * flDist * flScale2; // 2bd
  90. m_coefficients[7] = vNormal.z * vNormal.z * flScale; // c^2
  91. m_coefficients[8] = vNormal.z * flDist * flScale2; // cd
  92. m_coefficients[9] = flDist * flDist * flScale; // d^2
  93. }
  94. void InitFromTriangle( const Vector &v0, const Vector &v1, const Vector &v2, float flMinArea )
  95. {
  96. Vector vNormal = CrossProduct( v2 - v0, v1 - v0 );
  97. float flArea = 0.5f * vNormal.NormalizeInPlace();
  98. flArea = MAX(flMinArea, flArea);
  99. float flDist = -DotProduct(vNormal, v0);
  100. InitFromPlane( vNormal, flDist, flArea );
  101. }
  102. // this evaluates the error at a point in space
  103. inline float ComputeError( const Vector &v0 )
  104. {
  105. float x = v0.x;
  106. float y = v0.y;
  107. float z = v0.z;
  108. float flVertex[9];
  109. flVertex[0] = x * x;
  110. flVertex[1] = x * y;
  111. flVertex[2] = x * z;
  112. flVertex[3] = x;
  113. flVertex[4] = y * y;
  114. flVertex[5] = y * z;
  115. flVertex[6] = y;
  116. flVertex[7] = z * z;
  117. flVertex[8] = z;
  118. float flTotal = m_coefficients[9];
  119. for ( int i = 0; i < 9; i++ )
  120. {
  121. flTotal += flVertex[i] * m_coefficients[i];
  122. }
  123. return flTotal;
  124. }
  125. private:
  126. float m_coefficients[10];
  127. };
  128. #endif // QUADRIC_H