Added NoiseState offsets to FractalNoise
This commit is contained in:
parent
22cf9fde51
commit
67ae34ddbd
5 changed files with 112 additions and 5 deletions
|
@ -32,18 +32,33 @@ void FractalNoise::setRidge(double ridge_factor)
|
||||||
this->ridge = ridge_factor;
|
this->ridge = ridge_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FractalNoise::setState(const NoiseState &state)
|
||||||
|
{
|
||||||
|
state.copy(&this->state);
|
||||||
|
}
|
||||||
|
|
||||||
double FractalNoise::get1d(double detail, double x) const
|
double FractalNoise::get1d(double detail, double x) const
|
||||||
{
|
{
|
||||||
double current_scaling = scaling;
|
double current_scaling = scaling;
|
||||||
double current_height = height;
|
double current_height = height;
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
|
int state_level_count = state.level_offsets.size();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
while (current_height >= detail)
|
while (current_height >= detail)
|
||||||
{
|
{
|
||||||
result += getBase1d(x * current_scaling) * current_height;
|
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
||||||
|
|
||||||
|
result += getBase1d(offset.x + x * current_scaling) * current_height;
|
||||||
|
|
||||||
current_scaling *= step_scaling;
|
current_scaling *= step_scaling;
|
||||||
current_height *= step_height;
|
current_height *= step_height;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
if (i >= state_level_count)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -54,13 +69,23 @@ double FractalNoise::get2d(double detail, double x, double y) const
|
||||||
double current_scaling = scaling;
|
double current_scaling = scaling;
|
||||||
double current_height = height;
|
double current_height = height;
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
|
int state_level_count = state.level_offsets.size();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
while (current_height >= detail)
|
while (current_height >= detail)
|
||||||
{
|
{
|
||||||
result += getBase2d(x * current_scaling, y * current_scaling) * current_height;
|
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
||||||
|
|
||||||
|
result += getBase2d(offset.x + x * current_scaling, offset.y + y * current_scaling) * current_height;
|
||||||
|
|
||||||
current_scaling *= step_scaling;
|
current_scaling *= step_scaling;
|
||||||
current_height *= step_height;
|
current_height *= step_height;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
if (i >= state_level_count)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -71,13 +96,23 @@ double FractalNoise::get3d(double detail, double x, double y, double z) const
|
||||||
double current_scaling = scaling;
|
double current_scaling = scaling;
|
||||||
double current_height = height;
|
double current_height = height;
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
|
int state_level_count = state.level_offsets.size();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
while (current_height >= detail)
|
while (current_height >= detail)
|
||||||
{
|
{
|
||||||
result += getBase3d(x * current_scaling, y * current_scaling, z * current_scaling) * current_height;
|
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
||||||
|
|
||||||
|
result += getBase3d(offset.x + x * current_scaling, offset.y + y * current_scaling, offset.z + z * current_scaling) * current_height;
|
||||||
|
|
||||||
current_scaling *= step_scaling;
|
current_scaling *= step_scaling;
|
||||||
current_height *= step_height;
|
current_height *= step_height;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
if (i >= state_level_count)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -20,6 +20,7 @@ public:
|
||||||
void setStep(double scaling_factor, double height_factor=1.0);
|
void setStep(double scaling_factor, double height_factor=1.0);
|
||||||
void setSlope(double slope_factor);
|
void setSlope(double slope_factor);
|
||||||
void setRidge(double ridge_factor);
|
void setRidge(double ridge_factor);
|
||||||
|
void setState(const NoiseState &state);
|
||||||
|
|
||||||
double get1d(double detail, double x) const;
|
double get1d(double detail, double x) const;
|
||||||
double get2d(double detail, double x, double y) const;
|
double get2d(double detail, double x, double y) const;
|
||||||
|
|
|
@ -63,3 +63,14 @@ void NoiseState::resetOffsets(double x, double y, double z)
|
||||||
level_offset.z = z;
|
level_offset.z = z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NoiseState::setLevel(int level, double x, double y, double z)
|
||||||
|
{
|
||||||
|
NoiseOffset offset = {x, y, z};
|
||||||
|
level_offsets.at(level) = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NoiseState::setLevelCount(int level_count)
|
||||||
|
{
|
||||||
|
level_offsets.resize(level_count);
|
||||||
|
}
|
||||||
|
|
|
@ -30,10 +30,14 @@ public:
|
||||||
void randomizeOffsets();
|
void randomizeOffsets();
|
||||||
void resetOffsets(double x=0.0, double y=0.0, double z=0.0);
|
void resetOffsets(double x=0.0, double y=0.0, double z=0.0);
|
||||||
|
|
||||||
|
void setLevel(int level, double x, double y, double z);
|
||||||
|
void setLevelCount(int level_count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<NoiseOffset> level_offsets;
|
std::vector<NoiseOffset> level_offsets;
|
||||||
|
|
||||||
friend class NoiseGenerator;
|
friend class NoiseGenerator;
|
||||||
|
friend class FractalNoise;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,10 @@ class TestFractalNoise:public FractalNoise
|
||||||
public:
|
public:
|
||||||
TestFractalNoise(double value=0.0):FractalNoise(), value(value)
|
TestFractalNoise(double value=0.0):FractalNoise(), value(value)
|
||||||
{
|
{
|
||||||
|
NoiseState state;
|
||||||
|
state.resetOffsets();
|
||||||
|
setState(state);
|
||||||
|
|
||||||
calls = 0;
|
calls = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,22 +152,74 @@ TEST(FractalNoise, StepScalingAndHeight)
|
||||||
EXPECT_DOUBLE_EQ(1.8 + 0.7 + 0.3, result);
|
EXPECT_DOUBLE_EQ(1.8 + 0.7 + 0.3, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FractalNoise, StateOffset)
|
||||||
|
{
|
||||||
|
TestFractalNoise noise(0.8);
|
||||||
|
NoiseState state;
|
||||||
|
state.resetOffsets(0.2);
|
||||||
|
noise.setState(state);
|
||||||
|
|
||||||
|
double result = noise.get1d(0.4, 1.0);
|
||||||
|
|
||||||
|
ASSERT_EQ(2, noise.calls);
|
||||||
|
EXPECT_DOUBLE_EQ(2.0 + 1.5, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FractalNoise, StateOffsetIter)
|
||||||
|
{
|
||||||
|
TestFractalNoise noise(0.8);
|
||||||
|
NoiseState state;
|
||||||
|
state.setLevel(0, 0.1, 0.1, 0.1);
|
||||||
|
state.setLevel(1, 0.6, 0.6, 0.6);
|
||||||
|
noise.setState(state);
|
||||||
|
|
||||||
|
double result = noise.get1d(0.4, 1.0);
|
||||||
|
|
||||||
|
ASSERT_EQ(2, noise.calls);
|
||||||
|
EXPECT_DOUBLE_EQ(1.9 + 1.7, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FractalNoise, StateOffsetLoop)
|
||||||
|
{
|
||||||
|
TestFractalNoise noise(0.8);
|
||||||
|
NoiseState state;
|
||||||
|
state.setLevelCount(2);
|
||||||
|
state.setLevel(0, 0.1, 0.1, 0.1);
|
||||||
|
state.setLevel(1, 0.6, 0.6, 0.6);
|
||||||
|
noise.setState(state);
|
||||||
|
|
||||||
|
double result = noise.get1d(0.2, 1.0);
|
||||||
|
|
||||||
|
ASSERT_EQ(3, noise.calls);
|
||||||
|
EXPECT_DOUBLE_EQ(1.9 + 1.7 + 1.225, result);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FractalNoise, Noise2d)
|
TEST(FractalNoise, Noise2d)
|
||||||
{
|
{
|
||||||
TestFractalNoise noise(0.8);
|
TestFractalNoise noise(0.8);
|
||||||
|
NoiseState state;
|
||||||
|
state.setLevelCount(2);
|
||||||
|
state.setLevel(0, 0.1, 0.2, 0.3);
|
||||||
|
state.setLevel(1, 0.6, 0.7, 0.8);
|
||||||
|
noise.setState(state);
|
||||||
|
|
||||||
double result = noise.get2d(0.4, 1.0, 0.5);
|
double result = noise.get2d(0.4, 1.0, 0.5);
|
||||||
|
|
||||||
ASSERT_EQ(2, noise.calls);
|
ASSERT_EQ(2, noise.calls);
|
||||||
EXPECT_DOUBLE_EQ(2.3 + 1.9, result);
|
EXPECT_DOUBLE_EQ(2.6 + 2.55, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FractalNoise, Noise3d)
|
TEST(FractalNoise, Noise3d)
|
||||||
{
|
{
|
||||||
TestFractalNoise noise(0.8);
|
TestFractalNoise noise(0.8);
|
||||||
|
NoiseState state;
|
||||||
|
state.setLevelCount(2);
|
||||||
|
state.setLevel(0, 0.1, 0.2, 0.3);
|
||||||
|
state.setLevel(1, 0.6, 0.7, 0.8);
|
||||||
|
noise.setState(state);
|
||||||
|
|
||||||
double result = noise.get3d(0.4, 1.0, 0.5, 0.3);
|
double result = noise.get3d(0.4, 1.0, 0.5, 0.3);
|
||||||
|
|
||||||
ASSERT_EQ(2, noise.calls);
|
ASSERT_EQ(2, noise.calls);
|
||||||
EXPECT_DOUBLE_EQ(2.6 + 2.2, result);
|
EXPECT_DOUBLE_EQ(3.2 + 3.25, result);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue