PerlinNoise.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. ** Command & Conquer Renegade(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. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LightMap *
  23. * *
  24. * $Archive:: /Commando/Code/Tool $*
  25. * *
  26. * $Author:: Ian_l $*
  27. * *
  28. * $Modtime:: 2/14/01 2:21p $*
  29. * *
  30. * $Revision:: 3 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include <limits.h>
  36. #include "PerlinNoise.h"
  37. #include "Random.h"
  38. #include "WWMath.h"
  39. // Static data.
  40. float PerlinNoise::_NoiseTable [NOISE_TABLE_SIZE];
  41. /***********************************************************************************************
  42. * PerlinNoise::PerlinNoise -- *
  43. * *
  44. * INPUT: *
  45. * *
  46. * OUTPUT: *
  47. * *
  48. * WARNINGS: *
  49. * *
  50. * HISTORY: *
  51. * 09/05/00 IML : Created. *
  52. *=============================================================================================*/
  53. PerlinNoise::PerlinNoise()
  54. {
  55. static bool _initialized = false;
  56. if (!_initialized) {
  57. Random3Class randomnumber (0x3f198440, 0x92012324);
  58. float *noisetableptr;
  59. // Initialize the noise table with random values.
  60. noisetableptr = &_NoiseTable [0];
  61. for (unsigned i = 0; i < NOISE_TABLE_SIZE; i++) {
  62. *noisetableptr = randomnumber (0, 10000) * 0.0001f;
  63. noisetableptr++;
  64. }
  65. _initialized = true;
  66. }
  67. }
  68. /***********************************************************************************************
  69. * PerlinNoise::Value -- *
  70. * *
  71. * INPUT: *
  72. * *
  73. * OUTPUT: *
  74. * *
  75. * WARNINGS: *
  76. * *
  77. * HISTORY: *
  78. * 09/05/00 IML : Created. *
  79. *=============================================================================================*/
  80. float PerlinNoise::Noise (int x, int y, int z)
  81. {
  82. static unsigned char _permute [NOISE_TABLE_SIZE] = {
  83. 225, 155, 210, 108, 175, 199, 221, 144, 203, 116, 70, 213, 69, 158, 33, 252,
  84. 5, 82, 173, 133, 222, 139, 174, 27, 9, 71, 90, 246, 75, 130, 91, 191,
  85. 169, 138, 2, 151, 194, 235, 81, 7, 25, 113, 228, 159, 205, 253, 134, 142,
  86. 248, 65, 224, 217, 22, 121, 229, 63, 89, 103, 96, 104, 156, 17, 201, 129,
  87. 36, 8, 165, 110, 237, 117, 231, 56, 132, 211, 152, 20, 181, 111, 239, 218,
  88. 170, 163, 51, 172, 157, 47, 80, 212, 176, 250, 87, 49, 99, 242, 136, 189,
  89. 162, 115, 44, 43, 124, 94, 150, 16, 141, 247, 32, 10, 198, 223, 255, 72,
  90. 53, 131, 84, 57, 220, 197, 58, 50, 208, 11, 241, 28, 3, 192, 62, 202,
  91. 18, 215, 153, 24, 76, 41, 15, 179, 39, 46, 55, 6, 128, 167, 23, 188,
  92. 106, 34, 187, 140, 164, 73, 112, 182, 244, 195, 227, 13, 35, 77, 196, 185,
  93. 26, 200, 226, 119, 31, 123, 168, 125, 249, 68, 183, 230, 177, 135, 160, 180,
  94. 12, 1, 243, 148, 102, 166, 38, 238, 251, 37, 240, 126, 64, 74, 161, 40,
  95. 184, 149, 171, 178, 101, 66, 29, 59, 146, 61, 254, 107, 42, 86, 154, 4,
  96. 236, 232, 120, 21, 233, 209, 45, 98, 193, 114, 78, 19, 206, 14, 118, 127,
  97. 48, 79, 147, 85, 30, 207, 219, 54, 88, 234, 190, 122, 95, 67, 143, 109,
  98. 137, 214, 145, 93, 92, 100, 245, 0, 216, 186, 60, 83, 105, 97, 204, 52
  99. };
  100. #define PERMUTE(x) _permute [(x) & (NOISE_TABLE_MASK)]
  101. unsigned ux, uy, uz;
  102. ux = x + INT_MAX + 1;
  103. uy = y + INT_MAX + 1;
  104. uz = z + INT_MAX + 1;
  105. return (_NoiseTable [PERMUTE ((ux) + PERMUTE ((uy) + PERMUTE (uz)))]);
  106. #undef PERMUTE
  107. }
  108. /***********************************************************************************************
  109. * PerlinNoise::Noise -- *
  110. * *
  111. * INPUT: *
  112. * *
  113. * OUTPUT: *
  114. * *
  115. * WARNINGS: *
  116. * *
  117. * HISTORY: *
  118. * 09/05/00 IML : Created. *
  119. *=============================================================================================*/
  120. float PerlinNoise::Noise (const Vector3 &point)
  121. {
  122. int ix, iy, iz;
  123. float xf, yf, zf;
  124. float a, b, c, d, e, f, g, h;
  125. float x0, x1, x2, x3;
  126. float y0, y1;
  127. ix = floorf (point.X);
  128. iy = floorf (point.Y);
  129. iz = floorf (point.Z);
  130. xf = SmoothStep (point.X - ix);
  131. yf = SmoothStep (point.Y - iy);
  132. zf = SmoothStep (point.Z - iz);
  133. a = Noise (ix, iy, iz);
  134. b = Noise (ix + 1, iy, iz);
  135. c = Noise (ix + 1, iy + 1, iz);
  136. d = Noise (ix, iy + 1, iz);
  137. e = Noise (ix, iy, iz + 1);
  138. f = Noise (ix + 1, iy, iz + 1);
  139. g = Noise (ix + 1, iy + 1, iz + 1);
  140. h = Noise (ix, iy + 1, iz + 1);
  141. x0 = WWMath::Lerp (a, b, xf);
  142. x1 = WWMath::Lerp (d, c, xf);
  143. x2 = WWMath::Lerp (e, f, xf);
  144. x3 = WWMath::Lerp (h, g, xf);
  145. y0 = WWMath::Lerp (x0, x1, yf);
  146. y1 = WWMath::Lerp (x2, x3, yf);
  147. return (WWMath::Lerp (y0, y1, zf));
  148. }
  149. /***********************************************************************************************
  150. * PerlinNoise::Value -- *
  151. * *
  152. * INPUT: *
  153. * *
  154. * OUTPUT: *
  155. * *
  156. * WARNINGS: *
  157. * *
  158. * HISTORY: *
  159. * 09/05/00 IML : Created. *
  160. *=============================================================================================*/
  161. float PerlinNoise::Value (const Vector3 &point)
  162. {
  163. const unsigned octavecount = 5;
  164. float value, amplitudesum, frequency;
  165. value = 0.0f;
  166. amplitudesum = 0.0f;
  167. frequency = 0.5f;
  168. for (unsigned octave = 0; octave < octavecount; octave++) {
  169. float oofrequency;
  170. oofrequency = 1.0f / frequency;
  171. value += Noise (point * frequency) * oofrequency;
  172. amplitudesum += oofrequency;
  173. frequency *= 2.17f;
  174. }
  175. // Normalize.
  176. return (value * (1.0f / amplitudesum));
  177. }