Started the new FractalNoise implementation

This commit is contained in:
Michaël Lemaire 2014-01-01 17:45:50 +01:00
parent 5579045604
commit 22cf9fde51
8 changed files with 328 additions and 3 deletions

View file

@ -0,0 +1,94 @@
#include "FractalNoise.h"
FractalNoise::FractalNoise()
{
scaling = 1.0;
height = 1.0;
step_scaling = 2.0;
step_height = 0.5;
slope = 0.0;
ridge = 0.0;
}
void FractalNoise::setScaling(double scaling, double height)
{
this->scaling = scaling < 0.00000001 ? 0.0 : 1.0 / scaling;
this->height = scaling * height;
}
void FractalNoise::setStep(double scaling_factor, double height_factor)
{
this->step_scaling = scaling_factor < 0.00000001 ? 0.0 : 1.0 / scaling_factor;
this->step_height = scaling_factor * height_factor;
}
void FractalNoise::setSlope(double slope_factor)
{
this->slope = slope_factor;
}
void FractalNoise::setRidge(double ridge_factor)
{
this->ridge = ridge_factor;
}
double FractalNoise::get1d(double detail, double x) const
{
double current_scaling = scaling;
double current_height = height;
double result = 0.0;
while (current_height >= detail)
{
result += getBase1d(x * current_scaling) * current_height;
current_scaling *= step_scaling;
current_height *= step_height;
}
return result;
}
double FractalNoise::get2d(double detail, double x, double y) const
{
double current_scaling = scaling;
double current_height = height;
double result = 0.0;
while (current_height >= detail)
{
result += getBase2d(x * current_scaling, y * current_scaling) * current_height;
current_scaling *= step_scaling;
current_height *= step_height;
}
return result;
}
double FractalNoise::get3d(double detail, double x, double y, double z) const
{
double current_scaling = scaling;
double current_height = height;
double result = 0.0;
while (current_height >= detail)
{
result += getBase3d(x * current_scaling, y * current_scaling, z * current_scaling) * current_height;
current_scaling *= step_scaling;
current_height *= step_height;
}
return result;
}
double FractalNoise::getBase1d(double x) const
{
return getBase2d(x, 0.0);
}
double FractalNoise::getBase2d(double x, double y) const
{
return getBase3d(x, y, 0.0);
}

46
src/basics/FractalNoise.h Normal file
View file

@ -0,0 +1,46 @@
#ifndef FRACTALNOISE_H
#define FRACTALNOISE_H
#include "basics_global.h"
#include "NoiseState.h"
namespace paysages {
namespace basics {
/*!
* \brief Fractal noise generator, based on a sum of simple noise functions.
*/
class BASICSSHARED_EXPORT FractalNoise
{
public:
FractalNoise();
void setScaling(double scaling, double height=1.0);
void setStep(double scaling_factor, double height_factor=1.0);
void setSlope(double slope_factor);
void setRidge(double ridge_factor);
double get1d(double detail, double x) const;
double get2d(double detail, double x, double y) const;
double get3d(double detail, double x, double y, double z) const;
virtual double getBase1d(double x) const;
virtual double getBase2d(double x, double y) const;
virtual double getBase3d(double x, double y, double z) const = 0;
private:
NoiseState state;
double scaling;
double height;
double step_scaling;
double step_height;
double slope;
double ridge;
};
}
}
#endif // FRACTALNOISE_H

View file

@ -32,7 +32,8 @@ SOURCES += \
Texture2D.cpp \
Texture3D.cpp \
Texture4D.cpp \
NoiseState.cpp
NoiseState.cpp \
FractalNoise.cpp
HEADERS +=\
basics_global.h \
@ -52,7 +53,8 @@ HEADERS +=\
Texture2D.h \
Texture3D.h \
Texture4D.h \
NoiseState.h
NoiseState.h \
FractalNoise.h
unix:!symbian {
maemo5 {

View file

@ -19,6 +19,7 @@ namespace basics {
class Color;
class NoiseGenerator;
class NoiseState;
class FractalNoise;
class Curve;
class ColorProfile;
class Texture2D;

View file

@ -18,6 +18,9 @@ static Color _postProcessFragment(SoftwareRenderer* renderer, const Vector3 &loc
TEST(Bruneton, AerialPerspective1)
{
#ifndef TESTS_FULL
return;
#endif
Scenery scenery;
SoftwareRenderer renderer(&scenery);
renderer.render_width = 800;
@ -45,6 +48,9 @@ TEST(Bruneton, AerialPerspective1)
TEST(Bruneton, AerialPerspective2)
{
#ifndef TESTS_FULL
return;
#endif
Scenery scenery;
AtmosphereDefinition* atmo = scenery.getAtmosphere();

View file

@ -0,0 +1,169 @@
#include "BaseTestCase.h"
#include "FractalNoise.h"
class TestFractalNoise:public FractalNoise
{
public:
TestFractalNoise(double value=0.0):FractalNoise(), value(value)
{
calls = 0;
}
virtual double getBase3d(double x, double y, double z) const override
{
((TestFractalNoise*)this)->calls++;
return value + x + y + z;
}
public:
int calls;
private:
double value;
};
TEST(FractalNoise, AutoBase2d)
{
TestFractalNoise noise(0.2);
double result = noise.getBase2d(0.4, 0.1);
ASSERT_EQ(1, noise.calls);
EXPECT_DOUBLE_EQ(0.7, result);
}
TEST(FractalNoise, AutoBase1d)
{
TestFractalNoise noise(0.2);
double result = noise.getBase1d(0.4);
ASSERT_EQ(1, noise.calls);
EXPECT_DOUBLE_EQ(0.6, result);
}
TEST(FractalNoise, NoStep)
{
TestFractalNoise noise(0.1);
double result = noise.get1d(1.1, 1.0);
ASSERT_EQ(0, noise.calls);
EXPECT_DOUBLE_EQ(0.0, result);
}
TEST(FractalNoise, SingleStep)
{
TestFractalNoise noise(0.1);
double result = noise.get1d(0.7, 1.0);
ASSERT_EQ(1, noise.calls);
EXPECT_DOUBLE_EQ(1.1, result);
}
TEST(FractalNoise, Sum2Steps)
{
TestFractalNoise noise(0.1);
double result = noise.get1d(0.3, 1.0);
ASSERT_EQ(2, noise.calls);
EXPECT_DOUBLE_EQ(1.1 + 1.05, result);
}
TEST(FractalNoise, Sum3Steps)
{
TestFractalNoise noise(0.1);
double result = noise.get1d(0.2, 1.0);
ASSERT_EQ(3, noise.calls);
EXPECT_DOUBLE_EQ(1.1 + 1.05 + 1.025, result);
}
TEST(FractalNoise, InitialScaling)
{
TestFractalNoise noise(0.8);
noise.setScaling(0.5);
double result = noise.get1d(0.2, 1.0);
ASSERT_EQ(2, noise.calls);
EXPECT_DOUBLE_EQ(1.4 + 1.2, result);
}
TEST(FractalNoise, InitialHeight)
{
TestFractalNoise noise(0.8);
noise.setScaling(1.0, 0.5);
double result = noise.get1d(0.2, 1.0);
ASSERT_EQ(2, noise.calls);
EXPECT_DOUBLE_EQ(0.9 + 0.7, result);
}
TEST(FractalNoise, InitialScalingAndHeight)
{
TestFractalNoise noise(0.8);
noise.setScaling(0.5, 0.5);
double result = noise.get1d(0.1, 1.0);
ASSERT_EQ(2, noise.calls);
EXPECT_DOUBLE_EQ(0.7 + 0.6, result);
}
TEST(FractalNoise, StepScaling)
{
TestFractalNoise noise(0.1);
noise.setStep(0.8);
double result = noise.get1d(0.55, 1.0);
ASSERT_EQ(3, noise.calls);
EXPECT_DOUBLE_EQ(1.1 + 1.08 + 1.064, result);
}
TEST(FractalNoise, StepHeight)
{
TestFractalNoise noise(0.1);
noise.setStep(0.5, 0.8);
double result = noise.get1d(0.4, 1.0);
ASSERT_EQ(2, noise.calls);
EXPECT_DOUBLE_EQ(1.1 + 0.84, result);
}
TEST(FractalNoise, StepScalingAndHeight)
{
TestFractalNoise noise(0.8);
noise.setStep(0.5, 0.5);
double result = noise.get1d(0.05, 1.0);
ASSERT_EQ(3, noise.calls);
EXPECT_DOUBLE_EQ(1.8 + 0.7 + 0.3, result);
}
TEST(FractalNoise, Noise2d)
{
TestFractalNoise noise(0.8);
double result = noise.get2d(0.4, 1.0, 0.5);
ASSERT_EQ(2, noise.calls);
EXPECT_DOUBLE_EQ(2.3 + 1.9, result);
}
TEST(FractalNoise, Noise3d)
{
TestFractalNoise noise(0.8);
double result = noise.get3d(0.4, 1.0, 0.5, 0.3);
ASSERT_EQ(2, noise.calls);
EXPECT_DOUBLE_EQ(2.6 + 2.2, result);
}

View file

@ -51,6 +51,9 @@ static void _render_quad_checker(SoftwareRenderer &renderer)
TEST(Render, quad)
{
#ifndef TESTS_FULL
return;
#endif
SoftwareRenderer renderer;
renderer.render_camera->setLocationCoords(0.0, 0.5, 2.0);
@ -73,6 +76,9 @@ TEST(Render, quad)
TEST(Render, quad_cut)
{
#ifndef TESTS_FULL
return;
#endif
SoftwareRenderer renderer;
renderer.render_camera->setLocationCoords(0.8, 0.7, 1.0);

View file

@ -18,7 +18,8 @@ SOURCES += main.cpp \
Camera_Test.cpp \
Clouds_Test.cpp \
FluidMediumManager_Test.cpp \
VertexArray_Test.cpp
VertexArray_Test.cpp \
FractalNoise_Test.cpp
HEADERS += \
BaseTestCase.h