summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2014-11-17 23:02:53 +0100
committerMattes D <github@xoft.cz>2014-11-17 23:02:53 +0100
commite9082263c92549aebd3cb136935db28784adcf01 (patch)
tree235d076e8ce2ed1c2218bb2212aae38826eb438e
parentFixed include path. (diff)
downloadcuberite-e9082263c92549aebd3cb136935db28784adcf01.tar
cuberite-e9082263c92549aebd3cb136935db28784adcf01.tar.gz
cuberite-e9082263c92549aebd3cb136935db28784adcf01.tar.bz2
cuberite-e9082263c92549aebd3cb136935db28784adcf01.tar.lz
cuberite-e9082263c92549aebd3cb136935db28784adcf01.tar.xz
cuberite-e9082263c92549aebd3cb136935db28784adcf01.tar.zst
cuberite-e9082263c92549aebd3cb136935db28784adcf01.zip
-rw-r--r--src/Noise.cpp174
-rw-r--r--src/Noise.h98
-rw-r--r--src/OctavedNoise.h192
3 files changed, 206 insertions, 258 deletions
diff --git a/src/Noise.cpp b/src/Noise.cpp
index d3098c295..d16c0849c 100644
--- a/src/Noise.cpp
+++ b/src/Noise.cpp
@@ -1043,10 +1043,6 @@ NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z)
a_Z = a_Z & 255;
int A = m_Perm[a_X] + a_Y;
int AA = m_Perm[A] + a_Z;
- int AB = m_Perm[A + 1] + a_Z;
- int B = m_Perm[a_X + 1] + a_Y;
- int BA = m_Perm[B] + a_Z;
- int BB = m_Perm[B + 1] + a_Z;
return Grad(m_Perm[AA], 0, 0, 0);
}
@@ -1056,176 +1052,6 @@ NOISE_DATATYPE cImprovedNoise::GetValueAt(int a_X, int a_Y, int a_Z)
////////////////////////////////////////////////////////////////////////////////
-// cPerlinNoise:
-
-cPerlinNoise::cPerlinNoise(void) :
- m_Seed(0)
-{
-}
-
-
-
-
-
-cPerlinNoise::cPerlinNoise(int a_Seed) :
- m_Seed(a_Seed)
-{
-}
-
-
-
-
-
-void cPerlinNoise::SetSeed(int a_Seed)
-{
- m_Seed = a_Seed;
-}
-
-
-
-
-
-void cPerlinNoise::AddOctave(float a_Frequency, float a_Amplitude)
-{
- m_Octaves.push_back(cOctave(m_Seed * ((int)m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude));
-}
-
-
-
-
-
-void cPerlinNoise::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 ///< Workspace that this function can use and trash
-) const
-{
- if (m_Octaves.empty())
- {
- // No work to be done
- ASSERT(!"Perlin: No octaves to generate!");
- return;
- }
-
- bool ShouldFreeWorkspace = (a_Workspace == nullptr);
- int ArrayCount = a_SizeX * a_SizeY;
- if (ShouldFreeWorkspace)
- {
- a_Workspace = new NOISE_DATATYPE[ArrayCount];
- }
-
- // Generate the first octave directly into array:
- const cOctave & FirstOctave = m_Octaves.front();
-
- FirstOctave.m_Noise.Generate2D(
- a_Workspace, a_SizeX, a_SizeY,
- a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
- a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency
- );
- NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
- for (int i = 0; i < ArrayCount; i++)
- {
- a_Array[i] = a_Workspace[i] * Amplitude;
- }
-
- // Add each octave:
- for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr)
- {
- // Generate cubic noise for the octave:
- itr->m_Noise.Generate2D(
- a_Workspace, a_SizeX, a_SizeY,
- a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
- a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency
- );
- // Add the cubic noise into the output:
- NOISE_DATATYPE Amplitude = itr->m_Amplitude;
- for (int i = 0; i < ArrayCount; i++)
- {
- a_Array[i] += a_Workspace[i] * Amplitude;
- }
- }
-
- if (ShouldFreeWorkspace)
- {
- delete[] a_Workspace;
- a_Workspace = nullptr;
- }
-}
-
-
-
-
-
-void cPerlinNoise::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 ///< Workspace that this function can use and trash
-) const
-{
- if (m_Octaves.empty())
- {
- // No work to be done
- ASSERT(!"Perlin: No octaves to generate!");
- return;
- }
-
- bool ShouldFreeWorkspace = (a_Workspace == nullptr);
- int ArrayCount = a_SizeX * a_SizeY * a_SizeZ;
- if (ShouldFreeWorkspace)
- {
- a_Workspace = new NOISE_DATATYPE[ArrayCount];
- }
-
- // Generate the first octave directly into array:
- const cOctave & FirstOctave = m_Octaves.front();
-
- FirstOctave.m_Noise.Generate3D(
- a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
- a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
- a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency,
- a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency
- );
- NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
- for (int i = 0; i < ArrayCount; i++)
- {
- a_Array[i] = a_Workspace[i] * Amplitude;
- }
-
- // Add each octave:
- for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr)
- {
- // Generate cubic noise for the octave:
- itr->m_Noise.Generate3D(
- a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
- a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
- a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency,
- a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency
- );
- // Add the cubic noise into the output:
- NOISE_DATATYPE Amplitude = itr->m_Amplitude;
- for (int i = 0; i < ArrayCount; i++)
- {
- a_Array[i] += a_Workspace[i] * Amplitude;
- }
- }
-
- if (ShouldFreeWorkspace)
- {
- delete[] a_Workspace;
- a_Workspace = nullptr;
- }
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
// cRidgedMultiNoise:
cRidgedMultiNoise::cRidgedMultiNoise(void) :
diff --git a/src/Noise.h b/src/Noise.h
index 3c5caded7..8b9ee2f3b 100644
--- a/src/Noise.h
+++ b/src/Noise.h
@@ -7,22 +7,10 @@
#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"
@@ -35,20 +23,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 +49,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;
@@ -197,65 +185,7 @@ protected:
-class cPerlinNoise
-{
-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;
-
-
- 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;
diff --git a/src/OctavedNoise.h b/src/OctavedNoise.h
new file mode 100644
index 000000000..86fb0ddb0
--- /dev/null
+++ b/src/OctavedNoise.h
@@ -0,0 +1,192 @@
+
+// OctavedNoise.h
+
+// Implements the cOctavedNoise class template representing a noise generator that layers several octaves of another noise
+
+
+
+
+
+#pragma once
+
+
+
+
+
+template <typename N>
+class cOctavedNoise
+{
+public:
+ cOctavedNoise(int a_Seed = 0):
+ m_Seed(a_Seed)
+ {
+ }
+
+
+ /** Sets a new seed for the generators. Relays the seed to all underlying octaves. */
+ void SetSeed(int a_Seed)
+ {
+ m_Seed = a_Seed;
+ for (auto oct: m_Octaves)
+ {
+ oct->SetSeed(a_Seed);
+ }
+ }
+
+
+ /** */
+ void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude)
+ {
+ m_Octaves.emplace_back(m_Seed, a_Frequency, a_Amplitude);
+ }
+
+
+ /** 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 ///< Workspace that this function can use and trash. Must be valid.
+ ) const
+ {
+ // Check that state is alright:
+ if (m_Octaves.empty())
+ {
+ ASSERT(!"Perlin: No octaves to generate!");
+ return;
+ }
+
+ // Allocate the workspace on the heap, if it wasn't given:
+ std::unique_ptr<NOISE_DATATYPE[]> workspaceHeap;
+ if (a_Workspace == nullptr)
+ {
+ workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY]);
+ a_Workspace = workspaceHeap.get();
+ }
+
+ // Generate the first octave directly into array:
+ const cOctave & FirstOctave = m_Octaves.front();
+ int ArrayCount = a_SizeX * a_SizeY;
+ FirstOctave.m_Noise.Generate2D(
+ a_Workspace, a_SizeX, a_SizeY,
+ a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
+ a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency
+ );
+ NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] = a_Workspace[i] * Amplitude;
+ }
+
+ // Add each octave:
+ for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr)
+ {
+ // Generate the noise for the octave:
+ itr->m_Noise.Generate2D(
+ a_Workspace, a_SizeX, a_SizeY,
+ a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
+ a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency
+ );
+ // Add it into the output:
+ NOISE_DATATYPE Amplitude = itr->m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] += a_Workspace[i] * Amplitude;
+ }
+ } // for itr - m_Octaves[]
+ }
+
+
+ /** 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, same size as a_Array
+ ) const
+ {
+ // Check that state is alright:
+ if (m_Octaves.empty())
+ {
+ ASSERT(!"Perlin: No octaves to generate!");
+ return;
+ }
+
+ // Allocate the workspace on the heap, if it wasn't given:
+ std::unique_ptr<NOISE_DATATYPE[]> workspaceHeap;
+ if (a_Workspace == nullptr)
+ {
+ workspaceHeap.reset(new NOISE_DATATYPE[a_SizeX * a_SizeY * a_SizeZ]);
+ a_Workspace = workspaceHeap.get();
+ }
+
+ // Generate the first octave directly into array:
+ const cOctave & FirstOctave = m_Octaves.front();
+ int ArrayCount = a_SizeX * a_SizeY * a_SizeZ;
+ FirstOctave.m_Noise.Generate3D(
+ a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
+ a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
+ a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency,
+ a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency
+ );
+ NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] = a_Workspace[i] * Amplitude;
+ }
+
+ // Add each octave:
+ for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr)
+ {
+ // Generate the noise for the octave:
+ itr->m_Noise.Generate3D(
+ a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
+ a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
+ a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency,
+ a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency
+ );
+ // Add it into the output:
+ NOISE_DATATYPE Amplitude = itr->m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] += a_Workspace[i] * Amplitude;
+ }
+ } // for itr - m_Octaves[]
+ }
+
+protected:
+ /** Stores information and state for one octave of the noise. */
+ class cOctave
+ {
+ public:
+ N m_Noise;
+
+ /** Coord multiplier. */
+ NOISE_DATATYPE m_Frequency;
+
+ /** Value multiplier. */
+ NOISE_DATATYPE m_Amplitude;
+
+ 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;
+
+
+ /** The seed used by the underlying generators. */
+ int m_Seed;
+
+ /** The octaves that compose this noise. */
+ cOctaves m_Octaves;
+};
+
+
+
+