210 lines
10 KiB
C++
210 lines
10 KiB
C++
|
/*
|
||
|
** 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 <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
/***********************************************************************************************
|
||
|
*** Confidential - Westwood Studios ***
|
||
|
***********************************************************************************************
|
||
|
* *
|
||
|
* Project Name : LightMap *
|
||
|
* *
|
||
|
* $Archive:: /Commando/Code/Tool $*
|
||
|
* *
|
||
|
* $Author:: Ian_l $*
|
||
|
* *
|
||
|
* $Modtime:: 2/14/01 2:21p $*
|
||
|
* *
|
||
|
* $Revision:: 3 $*
|
||
|
* *
|
||
|
*---------------------------------------------------------------------------------------------*
|
||
|
* Functions: *
|
||
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
|
||
|
#include <limits.h>
|
||
|
#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));
|
||
|
}
|
||
|
|