/*
** 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));
}