summaryrefslogtreecommitdiffstats
path: root/src/Noise/Noise.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Noise/Noise.h (renamed from src/Noise.h)262
1 files changed, 105 insertions, 157 deletions
diff --git a/src/Noise.h b/src/Noise/Noise.h
index b7a90d5b7..323194bfd 100644
--- a/src/Noise.h
+++ b/src/Noise/Noise.h
@@ -7,22 +7,11 @@
#include <cmath>
+/** The datatype used by all the noise generators. */
+typedef float NOISE_DATATYPE;
-
-
-
-// Some settings
-#define NOISE_DATATYPE float
-
-
-
-
-
-#ifdef _MSC_VER
- #define INLINE __forceinline
-#else
- #define INLINE inline
-#endif
+#include "OctavedNoise.h"
+#include "RidgedNoise.h"
@@ -35,20 +24,20 @@ public:
cNoise(const cNoise & a_Noise);
// The following functions, if not marked INLINE, are about 20 % slower
- INLINE NOISE_DATATYPE IntNoise1D(int a_X) const;
- INLINE NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const;
- INLINE NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const;
+ inline NOISE_DATATYPE IntNoise1D(int a_X) const;
+ inline NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const;
+ inline NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const;
// Return a float number in the specified range:
- INLINE NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const
+ inline NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const
{
return a_Min + std::abs(IntNoise2D(a_X, a_Y)) * (a_Max - a_Min);
}
// Note: These functions have a mod8-irregular chance - each of the mod8 remainders has different chance of occurrence. Divide by 8 to rectify.
- INLINE int IntNoise1DInt(int a_X) const;
- INLINE int IntNoise2DInt(int a_X, int a_Y) const;
- INLINE int IntNoise3DInt(int a_X, int a_Y, int a_Z) const;
+ inline int IntNoise1DInt(int a_X) const;
+ inline int IntNoise2DInt(int a_X, int a_Y) const;
+ inline int IntNoise3DInt(int a_X, int a_Y, int a_Z) const;
NOISE_DATATYPE LinearNoise1D(NOISE_DATATYPE a_X) const;
NOISE_DATATYPE CosineNoise1D(NOISE_DATATYPE a_X) const;
@@ -61,9 +50,9 @@ public:
void SetSeed(int a_Seed) { m_Seed = a_Seed; }
- INLINE static NOISE_DATATYPE CubicInterpolate (NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct);
- INLINE static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct);
- INLINE static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct);
+ inline static NOISE_DATATYPE CubicInterpolate (NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct);
+ inline static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct);
+ inline static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct);
private:
int m_Seed;
@@ -76,19 +65,15 @@ private:
class cCubicNoise
{
public:
- static const int MAX_SIZE = 512; ///< Maximum size of each dimension of the query arrays.
+ /** Maximum size of each dimension of the query arrays. */
+ static const int MAX_SIZE = 512;
+ /** Creates a new instance with the specified seed. */
cCubicNoise(int a_Seed);
- void Generate1D(
- NOISE_DATATYPE * a_Array, ///< Array to generate into
- int a_SizeX, ///< Count of the array
- NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX ///< Noise-space coords of the array
- ) const;
-
-
+ /** Fills a 2D array with the values of the noise. */
void Generate2D(
NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y]
int a_SizeX, int a_SizeY, ///< Count of the array, in each direction
@@ -97,6 +82,7 @@ public:
) const;
+ /** Fills a 3D array with the values of the noise. */
void Generate3D(
NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z]
int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction
@@ -106,163 +92,87 @@ public:
) const;
protected:
- typedef NOISE_DATATYPE Workspace1D[4];
- typedef NOISE_DATATYPE Workspace2D[4][4];
-
- cNoise m_Noise; // Used for integral rnd values
-
- #ifdef _DEBUG
- // Statistics on the noise-space coords:
- static int m_NumSingleX;
- static int m_NumSingleXY;
- static int m_NumSingleY;
- static int m_NumCalls;
- #endif // _DEBUG
- /// Calculates the integral and fractional parts along one axis.
+ /** Noise used for integral random values. */
+ cNoise m_Noise;
+
+
+ /** Calculates the integral and fractional parts along one axis.
+ a_Floor will receive the integral parts (array of a_Size ints).
+ a_Frac will receive the fractional parts (array of a_Size floats).
+ a_Same will receive the counts of items that have the same integral parts (array of up to a_Size ints).
+ a_NumSame will receive the count of a_Same elements (total count of different integral parts). */
void CalcFloorFrac(
int a_Size,
NOISE_DATATYPE a_Start, NOISE_DATATYPE a_End,
int * a_Floor, NOISE_DATATYPE * a_Frac,
int * a_Same, int & a_NumSame
) const;
-
- void UpdateWorkRnds2DX(
- Workspace2D & a_WorkRnds,
- Workspace1D & a_Interps,
- int a_LastFloorX, int a_NewFloorX,
- int a_FloorY,
- NOISE_DATATYPE a_FractionY
- ) const;
} ;
-class cPerlinNoise
+/** Improved noise, as described by Ken Perlin: http://mrl.nyu.edu/~perlin/paper445.pdf
+Implementation adapted from Perlin's Java implementation: http://mrl.nyu.edu/~perlin/noise/ */
+class cImprovedNoise
{
public:
- cPerlinNoise(void);
- cPerlinNoise(int a_Seed);
-
-
- void SetSeed(int a_Seed);
-
- void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude);
-
- void Generate1D(
- NOISE_DATATYPE * a_Array, ///< Array to generate into
- int a_SizeX, ///< Count of the array
- NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array
- NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash
- ) const;
-
-
+ /** Constructs a new instance of the noise obbject.
+ Note that this operation is quite expensive (the permutation array being constructed). */
+ cImprovedNoise(int a_Seed);
+
+
+ /** Fills a 2D array with the values of the noise. */
void Generate2D(
NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y]
int a_SizeX, int a_SizeY, ///< Count of the array, in each direction
NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
- NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
- NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash
+ NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY ///< Noise-space coords of the array in the Y direction
) const;
+ /** Fills a 3D array with the values of the noise. */
void Generate3D(
NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z]
int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction
NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
- NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction
- NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash
+ NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ ///< Noise-space coords of the array in the Z direction
) const;
-
+
+ /** Returns the value at the specified integral coords. Used for raw speed measurement. */
+ NOISE_DATATYPE GetValueAt(int a_X, int a_Y, int a_Z);
+
protected:
- class cOctave
+
+ /** The permutation table used by the noise function. Initialized using seed. */
+ int m_Perm[512];
+
+
+ /** Calculates the fade curve, 6 * t^5 - 15 * t^4 + 10 * t^3. */
+ inline static NOISE_DATATYPE Fade(NOISE_DATATYPE a_T)
{
- public:
- cCubicNoise m_Noise;
-
- NOISE_DATATYPE m_Frequency; // Coord multiplier
- NOISE_DATATYPE m_Amplitude; // Value multiplier
-
- cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) :
- m_Noise(a_Seed),
- m_Frequency(a_Frequency),
- m_Amplitude(a_Amplitude)
- {
- }
- } ;
-
- typedef std::vector<cOctave> cOctaves;
-
- int m_Seed;
- cOctaves m_Octaves;
-} ;
+ return a_T * a_T * a_T * (a_T * (a_T * 6 - 15) + 10);
+ }
+ /** Returns the gradient value based on the hash. */
+ inline static NOISE_DATATYPE Grad(int a_Hash, NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z)
+ {
+ int hash = a_Hash % 16;
+ NOISE_DATATYPE u = (hash < 8) ? a_X : a_Y;
+ NOISE_DATATYPE v = (hash < 4) ? a_Y : (((hash == 12) || (hash == 14)) ? a_X : a_Z);
+ return (((hash & 1) == 0) ? u : -u) + (((hash & 2) == 0) ? v : -v);
+ }
+};
-class cRidgedMultiNoise
-{
-public:
- cRidgedMultiNoise(void);
- cRidgedMultiNoise(int a_Seed);
-
-
- void SetSeed(int a_Seed);
-
- void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude);
-
- void Generate1D(
- NOISE_DATATYPE * a_Array, ///< Array to generate into
- int a_SizeX, ///< Count of the array
- NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array
- NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash
- ) const;
-
-
- void Generate2D(
- NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y]
- int a_SizeX, int a_SizeY, ///< Count of the array, in each direction
- NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
- NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
- NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash
- ) const;
-
-
- void Generate3D(
- NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z]
- int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction
- NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
- NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
- NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction
- NOISE_DATATYPE * a_Workspace = nullptr ///< Workspace that this function can use and trash
- ) const;
-
-protected:
- class cOctave
- {
- public:
- cCubicNoise m_Noise;
-
- NOISE_DATATYPE m_Frequency; // Coord multiplier
- NOISE_DATATYPE m_Amplitude; // Value multiplier
-
- cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) :
- m_Noise(a_Seed),
- m_Frequency(a_Frequency),
- m_Amplitude(a_Amplitude)
- {
- }
- } ;
-
- typedef std::vector<cOctave> cOctaves;
-
- int m_Seed;
- cOctaves m_Octaves;
-} ;
+
+typedef cOctavedNoise<cCubicNoise> cPerlinNoise;
+typedef cOctavedNoise<cRidgedNoise<cCubicNoise>> cRidgedMultiNoise;
@@ -376,8 +286,46 @@ NOISE_DATATYPE cNoise::LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B,
////////////////////////////////////////////////////////////////////////////////
// Global functions:
-extern void Debug2DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, const AString & a_FileNameBase);
-extern void Debug3DNoise(const NOISE_DATATYPE * a_Noise, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase);
+/** Exports the noise array into a file.
+a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */
+extern void Debug2DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32);
+
+/** Exports the noise array into a set of files, ordered by XY and XZ.
+a_Coeff specifies the value that each array value is multiplied by before being converted into a byte. */
+extern void Debug3DNoise(const NOISE_DATATYPE * a_Array, int a_SizeX, int a_SizeY, int a_SizeZ, const AString & a_FileNameBase, NOISE_DATATYPE a_Coeff = 32);
+
+
+
+
+/** Linearly interpolates between two values.
+Assumes that a_Ratio is in range [0, 1]. */
+inline NOISE_DATATYPE Lerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio)
+{
+ return a_Val1 + (a_Val2 - a_Val1) * a_Ratio;
+}
+
+
+
+
+
+/** Linearly interpolates between two values, clamping the ratio to [0, 1] first. */
+inline NOISE_DATATYPE ClampedLerp(NOISE_DATATYPE a_Val1, NOISE_DATATYPE a_Val2, NOISE_DATATYPE a_Ratio)
+{
+ if (a_Ratio < 0)
+ {
+ return a_Val1;
+ }
+ if (a_Ratio > 1)
+ {
+ return a_Val2;
+ }
+ return Lerp(a_Val1, a_Val2, a_Ratio);
+}
+
+
+
+
+