You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.3 KiB
148 lines
4.3 KiB
5 years ago
|
//========= 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;
|
||
|
}
|