diff options
Diffstat (limited to 'hammer/noise.cpp')
| -rw-r--r-- | hammer/noise.cpp | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/hammer/noise.cpp b/hammer/noise.cpp new file mode 100644 index 0000000..538eb38 --- /dev/null +++ b/hammer/noise.cpp @@ -0,0 +1,147 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include <stdafx.h> +#include <math.h> + +#define OCTAVE_COUNT 4 +#define OCTAVE_COUNT_MINUS_ONE OCTAVE_COUNT - 1 + +//----------------------------------------------------------------------------- +// quick random number generator - returns a value -1.0f to 1.0 +//----------------------------------------------------------------------------- +float RandomNoise2D( int x, int y ) +{ + int n = x + y * 57; + n = ( n << 13 ) ^ n; + + float value ( 1.0f - ( float )( ( n * ( n * n * 15731 + 789221 ) + 1376312589 ) & 0x7fffffff ) / 1073741824.0f ); + + return value; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +float SmoothNoise2D( int x, int y ) +{ + float corners = ( RandomNoise2D( x-1, y-1 ) + RandomNoise2D( x+1, y-1 ) + + RandomNoise2D( x-1, y+1 ) + RandomNoise2D( x+1, y+1 ) ) / 16.0f; + float sides = ( RandomNoise2D( x-1, y ) + RandomNoise2D( x+1, y ) + + RandomNoise2D( x, y-1 ) + RandomNoise2D( x, y+1 ) ) / 8.0f; + float center = RandomNoise2D( x, y ) / 4.0f; + return corners + sides + center; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline float InterpLinear( float a, float b, float x ) +{ + return ( a * ( 1.0f - x ) + b * x ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline float InterpCos( float a, float b, float x ) +{ + float alpha = x * 3.1415927f; /* PI */ + float frac = 1.0f - ( float )cos( alpha ) * 0.5f; + return ( a * ( 1.0f - frac ) + b * frac ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline float InterpCubic( float a, float b, float c, float d, float x ) +{ + float P = ( d - c ) - ( a - b ); + float Q = ( a - b ) - P; + float R = ( c - a ); + float S = b; + + return ( ( P * x * 3.0f ) + ( Q * x * 2.0f ) + ( R * x ) + S ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +float InterpNoise2D( float x, float y ) +{ + int iX = ( int )x; + float fracX = x - iX; + + int iY = ( int )y; + float fracY = y - iY; + + float n[4]; + n[0] = SmoothNoise2D( iX, iY ); + n[1] = SmoothNoise2D( iX+1, iY ); + n[2] = SmoothNoise2D( iX, iY+1 ); + n[3] = SmoothNoise2D( iX+1, iY+1 ); + + float interpX[2]; + interpX[0] = InterpLinear( n[0], n[1], fracX ); + interpX[1] = InterpLinear( n[2], n[3], fracX ); + + return InterpLinear( interpX[0], interpX[1], fracY ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input: x - +// y - +// rockiness - 0.0f - 1.0f (0.0 = smooth, 1.0f = jagged) +// Output: +//----------------------------------------------------------------------------- +float PerlinNoise2D( float x, float y, float rockiness ) +{ + float total = 0.0; + float persistence = rockiness; + + for( int ndxOctave = 0; ndxOctave < OCTAVE_COUNT_MINUS_ONE; ndxOctave++ ) + { + float frequency = ( float )pow( 2.f, ndxOctave ); + float amplitude = ( float )pow( persistence, ndxOctave ); + + total += InterpNoise2D( x * frequency, y * frequency ) * amplitude; + } + + return total; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input: x - +// y - +// rockiness - 0.0f - 1.0f (0.0 = smooth, 1.0f = jagged) +// Output: is between -1.0f and 1.0f +//----------------------------------------------------------------------------- +float PerlinNoise2DScaled( float x, float y, float rockiness ) +{ + float total = 0.0; + float persistence = rockiness; + + for( int ndxOctave = 0; ndxOctave < OCTAVE_COUNT_MINUS_ONE; ndxOctave++ ) + { + float frequency = ( float )pow( 2.f, ndxOctave ); + float amplitude = ( float )pow( persistence, ndxOctave ); + + total += InterpNoise2D( x * frequency, y * frequency ) * amplitude; + } + + total /= ( float )OCTAVE_COUNT; + + return total; +} |