QuickTrig.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: QuickTrig.h ////////////////////////////////////////////////////////////////////////////////
  24. // Author: Mark Lorenzen (adapted by srj)
  25. // Desc: fast trig
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef __QUICKTRIG_H_
  29. #define __QUICKTRIG_H_
  30. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  31. //-----------------------------------------------------------------------------
  32. extern Real TheQuickSinTable[];
  33. extern Real TheQuickTanTable[];
  34. // yes, Real. No, really.
  35. extern Real TheQuickSinTableCount;
  36. extern Real TheQuickTanTableCount;
  37. //-----------------------------------------------------------------------------
  38. #define QUARTER_CIRCLE (PI/2)
  39. //-----------------------------------------------------------------------------
  40. // quick magnitude estimation, without the square root
  41. // NOTE, this is a very rough estimate, and may be off by 10% or more, so
  42. // use it only when you don't need accuracy
  43. //-----------------------------------------------------------------------------
  44. inline Real QMag(Real x, Real y, Real z)
  45. {
  46. Real sTempV;
  47. Real sMaxV = fabs(x);
  48. Real sMedV = fabs(y);
  49. Real sMinV = fabs(z);
  50. if (sMaxV < sMedV)
  51. {
  52. sTempV = sMaxV;
  53. sMaxV = sMedV;
  54. sMedV = sTempV;
  55. }
  56. if (sMaxV < sMinV)
  57. {
  58. sTempV = sMaxV;
  59. sMaxV = sMinV;
  60. sMinV = sTempV;
  61. }
  62. sMedV += sMinV;
  63. sMaxV += (sMedV*0.25f);
  64. return sMaxV;
  65. }
  66. //-----------------------------------------------------------------------------
  67. // table based trig functions
  68. //-----------------------------------------------------------------------------
  69. //-----------------------------------------------------------------------------
  70. inline Real QSin(Real a)
  71. {
  72. register Real angle = a;
  73. register long sgn = 1;
  74. if (angle < 0) // DO POSITIVE MATH AND PRESERVE SIGN
  75. {
  76. sgn = -1;
  77. angle = -angle;
  78. }
  79. while ( angle > (PI)) // MODULATE ANGLE INTO RANGE OF PI
  80. {
  81. angle -= PI;
  82. sgn = -sgn;
  83. }
  84. if (angle > PI/2)
  85. {
  86. angle = PI - angle; // FLIP
  87. }
  88. register int index = REAL_TO_INT((angle/QUARTER_CIRCLE) * TheQuickTanTableCount);
  89. register Real x = TheQuickSinTable[index];
  90. return x * sgn;
  91. /*
  92. Real remainder = node - index;
  93. Real next = TheQuickSinTable[index + 1];
  94. Real range = next - x;
  95. Real scalar = remainder / SIN_TABLE_BRACKET;
  96. Real finetune = scalar * range;
  97. x += finetune;
  98. */
  99. }
  100. //-----------------------------------------------------------------------------
  101. inline Real QCos(Real angle)
  102. {
  103. return QSin((QUARTER_CIRCLE) - angle);
  104. }
  105. //-----------------------------------------------------------------------------
  106. inline Real QTan(Real angle)
  107. {
  108. return TheQuickTanTable[REAL_TO_INT(angle * TheQuickSinTableCount)];
  109. }
  110. //-----------------------------------------------------------------------------
  111. inline Real QCsc(Real angle)
  112. {
  113. return 1.0f / QSin(angle);
  114. }
  115. //-----------------------------------------------------------------------------
  116. inline Real QSec(Real angle)
  117. {
  118. return 1.0f / QCos(angle);
  119. }
  120. //-----------------------------------------------------------------------------
  121. inline Real QCot(Real angle)
  122. {
  123. return 1.0f / QTan(angle);
  124. }
  125. #endif