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