paysages : Added noise ridge factor.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@425 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
6cd571f92f
commit
163cca53a9
10 changed files with 174 additions and 44 deletions
|
@ -8,6 +8,7 @@
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
/**************** Previews ****************/
|
/**************** Previews ****************/
|
||||||
class PreviewLevel:public BasePreview
|
class PreviewLevel:public BasePreview
|
||||||
|
@ -34,13 +35,13 @@ protected:
|
||||||
}
|
}
|
||||||
QColor getColor(double x, double y)
|
QColor getColor(double x, double y)
|
||||||
{
|
{
|
||||||
if ((_level >= 0) && (y > noiseGet1DLevel(_noise_preview, _level, x)))
|
if ((_level >= 0) && (-y > noiseGet1DLevel(_noise_preview, _level, x)))
|
||||||
{
|
{
|
||||||
return QColor(255, 255, 255);
|
return Qt::black;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return QColor(0, 0, 0);
|
return Qt::white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -66,13 +67,13 @@ protected:
|
||||||
}
|
}
|
||||||
QColor getColor(double x, double y)
|
QColor getColor(double x, double y)
|
||||||
{
|
{
|
||||||
if (y > noiseGet1DTotal(_noise_preview, x))
|
if (-y > noiseGet1DTotal(_noise_preview, x))
|
||||||
{
|
{
|
||||||
return QColor(255, 255, 255);
|
return Qt::black;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return QColor(0, 0, 0);
|
return Qt::white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -84,6 +85,7 @@ private:
|
||||||
DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
|
DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
|
||||||
DialogWithPreview(parent)
|
DialogWithPreview(parent)
|
||||||
{
|
{
|
||||||
|
QWidget* function;
|
||||||
QWidget* previews;
|
QWidget* previews;
|
||||||
QWidget* form;
|
QWidget* form;
|
||||||
QWidget* buttons;
|
QWidget* buttons;
|
||||||
|
@ -116,6 +118,23 @@ DialogNoise::DialogNoise(QWidget *parent, NoiseGenerator* value):
|
||||||
form->setLayout(new QVBoxLayout());
|
form->setLayout(new QVBoxLayout());
|
||||||
layout()->addWidget(form);
|
layout()->addWidget(form);
|
||||||
|
|
||||||
|
function = new QWidget(form);
|
||||||
|
function->setLayout(new QHBoxLayout());
|
||||||
|
form->layout()->addWidget(function);
|
||||||
|
|
||||||
|
function->layout()->addWidget(new QLabel(tr("Noise function")));
|
||||||
|
function_algo = new QComboBox(function);
|
||||||
|
function_algo->addItems(QStringList(tr("Simplex")) << tr("Perlin") << tr("Naive"));
|
||||||
|
function->layout()->addWidget(function_algo);
|
||||||
|
function->layout()->addWidget(new QLabel(tr("Ridge factor")));
|
||||||
|
function_ridge = new QSlider(Qt::Horizontal, function);
|
||||||
|
function_ridge->setRange(-10, 10);
|
||||||
|
function_ridge->setTickInterval(10);
|
||||||
|
function_ridge->setTickPosition(QSlider::TicksBelow);
|
||||||
|
function->layout()->addWidget(function_ridge);
|
||||||
|
QObject::connect(function_algo, SIGNAL(currentIndexChanged(int)), this, SLOT(functionChanged()));
|
||||||
|
QObject::connect(function_ridge, SIGNAL(valueChanged(int)), this, SLOT(functionChanged()));
|
||||||
|
|
||||||
form->layout()->addWidget(new QLabel(tr("Noise components")));
|
form->layout()->addWidget(new QLabel(tr("Noise components")));
|
||||||
levels = new QListWidget(form);
|
levels = new QListWidget(form);
|
||||||
form->layout()->addWidget(levels);
|
form->layout()->addWidget(levels);
|
||||||
|
@ -223,6 +242,7 @@ void DialogNoise::revertToCurrent()
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
int selected;
|
int selected;
|
||||||
|
NoiseFunction function;
|
||||||
|
|
||||||
selected = levels->currentRow();
|
selected = levels->currentRow();
|
||||||
|
|
||||||
|
@ -246,6 +266,10 @@ void DialogNoise::revertToCurrent()
|
||||||
levels->setCurrentRow(selected);
|
levels->setCurrentRow(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function = noiseGetFunction(_current);
|
||||||
|
function_algo->setCurrentIndex((int)function.algorithm);
|
||||||
|
function_ridge->setValue(round(function.ridge_factor * 20.0));
|
||||||
|
|
||||||
previewLevel->redraw();
|
previewLevel->redraw();
|
||||||
previewTotal->redraw();
|
previewTotal->redraw();
|
||||||
}
|
}
|
||||||
|
@ -283,6 +307,20 @@ void DialogNoise::removeLevel()
|
||||||
levels->setCurrentRow(row);
|
levels->setCurrentRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogNoise::functionChanged()
|
||||||
|
{
|
||||||
|
NoiseFunction function;
|
||||||
|
|
||||||
|
function.algorithm = (NoiseFunctionAlgorithm)function_algo->currentIndex();
|
||||||
|
function.ridge_factor = (double)function_ridge->value() * 0.05;
|
||||||
|
|
||||||
|
noiseSetFunction(_current, &function);
|
||||||
|
noiseValidate(_current);
|
||||||
|
|
||||||
|
previewLevel->redraw();
|
||||||
|
previewTotal->redraw();
|
||||||
|
}
|
||||||
|
|
||||||
void DialogNoise::levelChanged(int row)
|
void DialogNoise::levelChanged(int row)
|
||||||
{
|
{
|
||||||
if (noiseGetLevel(_current, row, &_current_level_params))
|
if (noiseGetLevel(_current, row, &_current_level_params))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _PAYSAGES_QT_DIALOGNOISE_H_
|
#define _PAYSAGES_QT_DIALOGNOISE_H_
|
||||||
|
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
|
#include <QComboBox>
|
||||||
#include "basepreview.h"
|
#include "basepreview.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ private:
|
||||||
private slots:
|
private slots:
|
||||||
void addLevel();
|
void addLevel();
|
||||||
void removeLevel();
|
void removeLevel();
|
||||||
|
void functionChanged();
|
||||||
void levelChanged(int row);
|
void levelChanged(int row);
|
||||||
void heightChanged(int value);
|
void heightChanged(int value);
|
||||||
void scalingChanged(int value);
|
void scalingChanged(int value);
|
||||||
|
@ -40,6 +42,8 @@ private:
|
||||||
NoiseLevel _current_level_params;
|
NoiseLevel _current_level_params;
|
||||||
BasePreview* previewLevel;
|
BasePreview* previewLevel;
|
||||||
BasePreview* previewTotal;
|
BasePreview* previewTotal;
|
||||||
|
QComboBox* function_algo;
|
||||||
|
QSlider* function_ridge;
|
||||||
QListWidget* levels;
|
QListWidget* levels;
|
||||||
QSlider* slider_height;
|
QSlider* slider_height;
|
||||||
QSlider* slider_scaling;
|
QSlider* slider_scaling;
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
PreviewCloudsCoverage(QWidget* parent, CloudsLayerDefinition* layer):BasePreview(parent)
|
PreviewCloudsCoverage(QWidget* parent, CloudsLayerDefinition* layer):BasePreview(parent)
|
||||||
{
|
{
|
||||||
_renderer = rendererCreate();
|
_renderer = rendererCreate();
|
||||||
_renderer.render_quality = 3;
|
_renderer.render_quality = 5;
|
||||||
_renderer.applyLightStatus = _applyLightStatus;
|
_renderer.applyLightStatus = _applyLightStatus;
|
||||||
|
|
||||||
_original_layer = layer;
|
_original_layer = layer;
|
||||||
|
@ -81,7 +81,7 @@ public:
|
||||||
lightingValidateDefinition(&_lighting);
|
lightingValidateDefinition(&_lighting);
|
||||||
|
|
||||||
_renderer = rendererCreate();
|
_renderer = rendererCreate();
|
||||||
_renderer.render_quality = 3;
|
_renderer.render_quality = 8;
|
||||||
_renderer.alterLight = _alterLight;
|
_renderer.alterLight = _alterLight;
|
||||||
_renderer.getLightStatus = _getLightStatus;
|
_renderer.getLightStatus = _getLightStatus;
|
||||||
_renderer.customData[0] = _preview_layer;
|
_renderer.customData[0] = _preview_layer;
|
||||||
|
@ -109,9 +109,9 @@ protected:
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
cloudsLayerCopyDefinition(_original_layer, _preview_layer);
|
cloudsLayerCopyDefinition(_original_layer, _preview_layer);
|
||||||
//noiseForceValue(_preview_layer.shape_noise, 1.0);
|
//noiseForceValue(_preview_layer->shape_noise, 1.0);
|
||||||
_preview_layer->lower_altitude = -_preview_layer->thickness * 0.5;
|
_preview_layer->lower_altitude = -_preview_layer->thickness * 0.5;
|
||||||
//curveClear(_preview_layer.coverage_by_altitude);
|
//curveClear(_preview_layer->coverage_by_altitude);
|
||||||
_preview_layer->base_coverage = 1.0;
|
_preview_layer->base_coverage = 1.0;
|
||||||
_preview_layer->_custom_coverage = _coverageFunc;
|
_preview_layer->_custom_coverage = _coverageFunc;
|
||||||
}
|
}
|
||||||
|
@ -172,8 +172,8 @@ FormClouds::FormClouds(QWidget *parent):
|
||||||
addInputDouble(tr("Edge length"), &_layer->edge_length, 0.0, 1.0, 0.01, 0.1);
|
addInputDouble(tr("Edge length"), &_layer->edge_length, 0.0, 1.0, 0.01, 0.1);
|
||||||
addInputMaterial(tr("Material"), &_layer->material);
|
addInputMaterial(tr("Material"), &_layer->material);
|
||||||
addInputDouble(tr("Hardness to light"), &_layer->hardness, 0.0, 1.0, 0.01, 0.1);
|
addInputDouble(tr("Hardness to light"), &_layer->hardness, 0.0, 1.0, 0.01, 0.1);
|
||||||
addInputDouble(tr("Transparency depth"), &_layer->transparencydepth, 0.0, 100.0, 0.5, 5.0);
|
addInputDouble(tr("Transparency depth"), &_layer->transparencydepth, 0.0, 10.0, 0.1, 1.0);
|
||||||
addInputDouble(tr("Light traversal depth"), &_layer->lighttraversal, 0.0, 100.0, 0.5, 5.0);
|
addInputDouble(tr("Light traversal depth"), &_layer->lighttraversal, 0.0, 10.0, 0.1, 1.0);
|
||||||
addInputDouble(tr("Minimum lighting"), &_layer->minimumlight, 0.0, 1.0, 0.01, 0.1);
|
addInputDouble(tr("Minimum lighting"), &_layer->minimumlight, 0.0, 1.0, 0.01, 0.1);
|
||||||
|
|
||||||
setLayers(_definition.layers);
|
setLayers(_definition.layers);
|
||||||
|
|
|
@ -31,10 +31,10 @@ public:
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
factor = ((double)(height / 2)) / noiseGetMaxValue(noise);
|
factor = ((double)(height / 2)) / noiseGetMaxValue(noise);
|
||||||
value = noiseGet1DTotal(noise, ((double)x) / factor) * factor;
|
value = -noiseGet1DTotal(noise, ((double)x) / factor) * factor;
|
||||||
painter.setPen(QColor(255, 255, 255));
|
painter.setPen(Qt::white);
|
||||||
painter.drawLine(x, 0, x, height / 2 + value);
|
painter.drawLine(x, 0, x, height / 2 + value);
|
||||||
painter.setPen(QColor(0, 0, 0));
|
painter.setPen(Qt::black);
|
||||||
painter.drawLine(x, height / 2 + value + 1, x, height);
|
painter.drawLine(x, height / 2 + value + 1, x, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ void autoGenRealisticLandscape(int seed)
|
||||||
noiseClearLevels(water.waves_noise);
|
noiseClearLevels(water.waves_noise);
|
||||||
noiseAddLevelsSimple(water.waves_noise, 2, 1.0, 1.0);
|
noiseAddLevelsSimple(water.waves_noise, 2, 1.0, 1.0);
|
||||||
noiseAddLevelsSimple(water.waves_noise, 3, 0.15, 0.1);
|
noiseAddLevelsSimple(water.waves_noise, 3, 0.15, 0.1);
|
||||||
|
noiseSetFunctionParams(water.waves_noise, NOISE_FUNCTION_SIMPLEX, -0.3);
|
||||||
scenerySetWater(&water);
|
scenerySetWater(&water);
|
||||||
waterDeleteDefinition(&water);
|
waterDeleteDefinition(&water);
|
||||||
|
|
||||||
|
@ -137,8 +138,9 @@ void autoGenRealisticLandscape(int seed)
|
||||||
terrain = terrainCreateDefinition();
|
terrain = terrainCreateDefinition();
|
||||||
noiseClearLevels(terrain.height_noise);
|
noiseClearLevels(terrain.height_noise);
|
||||||
noiseAddLevelsSimple(terrain.height_noise, 10, 1.0, 1.0);
|
noiseAddLevelsSimple(terrain.height_noise, 10, 1.0, 1.0);
|
||||||
|
noiseSetFunctionParams(terrain.height_noise, NOISE_FUNCTION_SIMPLEX, -0.2);
|
||||||
terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise);
|
terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise);
|
||||||
terrain.scaling = 60.0;
|
terrain.scaling = 80.0;
|
||||||
terrain.shadow_smoothing = 0.03;
|
terrain.shadow_smoothing = 0.03;
|
||||||
scenerySetTerrain(&terrain);
|
scenerySetTerrain(&terrain);
|
||||||
terrainDeleteDefinition(&terrain);
|
terrainDeleteDefinition(&terrain);
|
||||||
|
|
|
@ -89,13 +89,15 @@ CloudsLayerDefinition* cloudsLayerCreateDefinition()
|
||||||
result->lighttraversal = 7.0;
|
result->lighttraversal = 7.0;
|
||||||
result->minimumlight = 0.4;
|
result->minimumlight = 0.4;
|
||||||
result->shape_scaling = 10.0;
|
result->shape_scaling = 10.0;
|
||||||
result->edge_scaling = 0.2;
|
result->edge_scaling = 0.3;
|
||||||
result->edge_length = 0.2;
|
result->edge_length = 0.4;
|
||||||
result->base_coverage = 0.35;
|
result->base_coverage = 0.35;
|
||||||
result->shape_noise = noiseCreateGenerator();
|
result->shape_noise = noiseCreateGenerator();
|
||||||
noiseAddLevelsSimple(result->shape_noise, 5, 1.0, 1.0);
|
noiseAddLevelsSimple(result->shape_noise, 6, 1.0, 1.0);
|
||||||
|
noiseSetFunctionParams(result->shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3);
|
||||||
result->edge_noise = noiseCreateGenerator();
|
result->edge_noise = noiseCreateGenerator();
|
||||||
noiseAddLevelsSimple(result->edge_noise, 8, 1.0, 1.0);
|
noiseAddLevelsSimple(result->edge_noise, 8, 1.0, 1.0);
|
||||||
|
noiseSetFunctionParams(result->edge_noise, NOISE_FUNCTION_SIMPLEX, 0.5);
|
||||||
|
|
||||||
result->_custom_coverage = _standardCoverageFunc;
|
result->_custom_coverage = _standardCoverageFunc;
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,15 @@ struct NoiseLevel;
|
||||||
|
|
||||||
struct NoiseGenerator
|
struct NoiseGenerator
|
||||||
{
|
{
|
||||||
|
NoiseFunction function;
|
||||||
double height_offset;
|
double height_offset;
|
||||||
int level_count;
|
int level_count;
|
||||||
struct NoiseLevel levels[MAX_LEVEL_COUNT];
|
struct NoiseLevel levels[MAX_LEVEL_COUNT];
|
||||||
|
|
||||||
double _max_height;
|
double _max_height;
|
||||||
|
double (*_func_noise_1d)(double x);
|
||||||
|
double (*_func_noise_2d)(double x, double y);
|
||||||
|
double (*_func_noise_3d)(double x, double y, double z);
|
||||||
};
|
};
|
||||||
|
|
||||||
void noiseInit()
|
void noiseInit()
|
||||||
|
@ -45,6 +49,8 @@ NoiseGenerator* noiseCreateGenerator()
|
||||||
|
|
||||||
/* initialize */
|
/* initialize */
|
||||||
result = malloc(sizeof(NoiseGenerator));
|
result = malloc(sizeof(NoiseGenerator));
|
||||||
|
result->function.algorithm = NOISE_FUNCTION_SIMPLEX;
|
||||||
|
result->function.ridge_factor = 0.0;
|
||||||
result->level_count = 0;
|
result->level_count = 0;
|
||||||
result->height_offset = 0.0;
|
result->height_offset = 0.0;
|
||||||
|
|
||||||
|
@ -62,6 +68,10 @@ void noiseSaveGenerator(PackStream* stream, NoiseGenerator* generator)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
x = (int)generator->function.algorithm;
|
||||||
|
packWriteInt(stream, &x);
|
||||||
|
packWriteDouble(stream, &generator->function.ridge_factor);
|
||||||
|
|
||||||
packWriteDouble(stream, &generator->height_offset);
|
packWriteDouble(stream, &generator->height_offset);
|
||||||
packWriteInt(stream, &generator->level_count);
|
packWriteInt(stream, &generator->level_count);
|
||||||
|
|
||||||
|
@ -81,6 +91,10 @@ void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
packReadInt(stream, &x);
|
||||||
|
generator->function.algorithm = (NoiseFunctionAlgorithm)x;
|
||||||
|
packReadDouble(stream, &generator->function.ridge_factor);
|
||||||
|
|
||||||
packReadDouble(stream, &generator->height_offset);
|
packReadDouble(stream, &generator->height_offset);
|
||||||
packReadInt(stream, &generator->level_count);
|
packReadInt(stream, &generator->level_count);
|
||||||
|
|
||||||
|
@ -100,6 +114,7 @@ void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator)
|
||||||
|
|
||||||
void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination)
|
void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination)
|
||||||
{
|
{
|
||||||
|
destination->function = source->function;
|
||||||
destination->height_offset = source->height_offset;
|
destination->height_offset = source->height_offset;
|
||||||
destination->level_count = source->level_count;
|
destination->level_count = source->level_count;
|
||||||
|
|
||||||
|
@ -113,6 +128,34 @@ void noiseValidate(NoiseGenerator* generator)
|
||||||
int x;
|
int x;
|
||||||
double max_height = generator->height_offset;
|
double max_height = generator->height_offset;
|
||||||
|
|
||||||
|
if (generator->function.algorithm < 0 || generator->function.algorithm > NOISE_FUNCTION_NAIVE)
|
||||||
|
{
|
||||||
|
generator->function.algorithm = NOISE_FUNCTION_SIMPLEX;
|
||||||
|
}
|
||||||
|
switch (generator->function.algorithm)
|
||||||
|
{
|
||||||
|
case NOISE_FUNCTION_SIMPLEX:
|
||||||
|
generator->_func_noise_1d = noiseSimplexGet1DValue;
|
||||||
|
generator->_func_noise_2d = noiseSimplexGet2DValue;
|
||||||
|
generator->_func_noise_3d = noiseSimplexGet3DValue;
|
||||||
|
break;
|
||||||
|
case NOISE_FUNCTION_PERLIN:
|
||||||
|
/*TODO*/
|
||||||
|
break;
|
||||||
|
case NOISE_FUNCTION_NAIVE:
|
||||||
|
/* TODO */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (generator->function.ridge_factor > 0.5)
|
||||||
|
{
|
||||||
|
generator->function.ridge_factor = 0.5;
|
||||||
|
}
|
||||||
|
if (generator->function.ridge_factor < -0.5)
|
||||||
|
{
|
||||||
|
generator->function.ridge_factor = -0.5;
|
||||||
|
}
|
||||||
|
|
||||||
for (x = 0; x < generator->level_count; x++)
|
for (x = 0; x < generator->level_count; x++)
|
||||||
{
|
{
|
||||||
max_height += generator->levels[x].height / 2.0;
|
max_height += generator->levels[x].height / 2.0;
|
||||||
|
@ -121,6 +164,23 @@ void noiseValidate(NoiseGenerator* generator)
|
||||||
generator->_max_height = max_height;
|
generator->_max_height = max_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NoiseFunction noiseGetFunction(NoiseGenerator* generator)
|
||||||
|
{
|
||||||
|
return generator->function;
|
||||||
|
}
|
||||||
|
|
||||||
|
void noiseSetFunction(NoiseGenerator* generator, NoiseFunction* function)
|
||||||
|
{
|
||||||
|
generator->function = *function;
|
||||||
|
noiseValidate(generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void noiseSetFunctionParams(NoiseGenerator* generator, NoiseFunctionAlgorithm algorithm, double ridge_factor)
|
||||||
|
{
|
||||||
|
NoiseFunction function = {algorithm, ridge_factor};
|
||||||
|
noiseSetFunction(generator, &function);
|
||||||
|
}
|
||||||
|
|
||||||
void noiseForceValue(NoiseGenerator* generator, double value)
|
void noiseForceValue(NoiseGenerator* generator, double value)
|
||||||
{
|
{
|
||||||
noiseClearLevels(generator);
|
noiseClearLevels(generator);
|
||||||
|
@ -269,17 +329,28 @@ void noiseNormalizeHeight(NoiseGenerator* generator, double min_height, double m
|
||||||
noiseValidate(generator);
|
noiseValidate(generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double _applyRidge(double value, double ridge)
|
||||||
|
|
||||||
|
|
||||||
static inline double _get1DRawNoiseValue(NoiseGenerator* generator, double x)
|
|
||||||
{
|
{
|
||||||
return noiseSimplexGet2DValue(x, 0.0) * 0.5;
|
if (ridge > 0.0)
|
||||||
|
{
|
||||||
|
return fabs(value + 0.5 - ridge) - 0.5 + ridge;
|
||||||
}
|
}
|
||||||
|
else if (ridge < 0.0)
|
||||||
|
{
|
||||||
|
return -fabs(value - 0.5 - ridge) + 0.5 + ridge;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline double _get1DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x)
|
static inline double _get1DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x)
|
||||||
{
|
{
|
||||||
return _get1DRawNoiseValue(generator, x / level->scaling + level->xoffset) * level->height;
|
return _applyRidge(generator->_func_noise_1d(x / level->scaling + level->xoffset) * level->height, generator->function.ridge_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
double noiseGet1DLevel(NoiseGenerator* generator, int level, double x)
|
double noiseGet1DLevel(NoiseGenerator* generator, int level, double x)
|
||||||
|
@ -334,14 +405,9 @@ double noiseGet1DDetail(NoiseGenerator* generator, double x, double detail)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline double _get2DRawNoiseValue(NoiseGenerator* generator, double x, double y)
|
|
||||||
{
|
|
||||||
return noiseSimplexGet2DValue(x, y) * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double _get2DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x, double y)
|
static inline double _get2DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x, double y)
|
||||||
{
|
{
|
||||||
return _get2DRawNoiseValue(generator, x / level->scaling + level->xoffset, y / level->scaling + level->yoffset) * level->height;
|
return _applyRidge(generator->_func_noise_2d(x / level->scaling + level->xoffset, y / level->scaling + level->yoffset) * level->height, generator->function.ridge_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
double noiseGet2DLevel(NoiseGenerator* generator, int level, double x, double y)
|
double noiseGet2DLevel(NoiseGenerator* generator, int level, double x, double y)
|
||||||
|
@ -396,14 +462,9 @@ double noiseGet2DDetail(NoiseGenerator* generator, double x, double y, double de
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline double _get3DRawNoiseValue(NoiseGenerator* generator, double x, double y, double z)
|
|
||||||
{
|
|
||||||
return noiseSimplexGet3DValue(x, y, z) * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double _get3DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x, double y, double z)
|
static inline double _get3DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x, double y, double z)
|
||||||
{
|
{
|
||||||
return _get3DRawNoiseValue(generator, x / level->scaling + level->xoffset, y / level->scaling + level->yoffset, z / level->scaling + level->zoffset) * level->height;
|
return _applyRidge(generator->_func_noise_3d(x / level->scaling + level->xoffset, y / level->scaling + level->yoffset, z / level->scaling + level->zoffset) * level->height, generator->function.ridge_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
double noiseGet3DLevel(NoiseGenerator* generator, int level, double x, double y, double z)
|
double noiseGet3DLevel(NoiseGenerator* generator, int level, double x, double y, double z)
|
||||||
|
|
|
@ -7,6 +7,19 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NOISE_FUNCTION_SIMPLEX,
|
||||||
|
NOISE_FUNCTION_PERLIN,
|
||||||
|
NOISE_FUNCTION_NAIVE
|
||||||
|
} NoiseFunctionAlgorithm;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
NoiseFunctionAlgorithm algorithm;
|
||||||
|
double ridge_factor;
|
||||||
|
} NoiseFunction;
|
||||||
|
|
||||||
struct NoiseLevel
|
struct NoiseLevel
|
||||||
{
|
{
|
||||||
double scaling;
|
double scaling;
|
||||||
|
@ -29,6 +42,9 @@ void noiseSaveGenerator(PackStream* stream, NoiseGenerator* generator);
|
||||||
void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator);
|
void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator);
|
||||||
void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination);
|
void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination);
|
||||||
void noiseValidate(NoiseGenerator* generator);
|
void noiseValidate(NoiseGenerator* generator);
|
||||||
|
NoiseFunction noiseGetFunction(NoiseGenerator* generator);
|
||||||
|
void noiseSetFunction(NoiseGenerator* generator, NoiseFunction* function);
|
||||||
|
void noiseSetFunctionParams(NoiseGenerator* generator, NoiseFunctionAlgorithm algorithm, double ridge_factor);
|
||||||
void noiseForceValue(NoiseGenerator* generator, double value);
|
void noiseForceValue(NoiseGenerator* generator, double value);
|
||||||
double noiseGetMaxValue(NoiseGenerator* generator);
|
double noiseGetMaxValue(NoiseGenerator* generator);
|
||||||
int noiseGetLevelCount(NoiseGenerator* generator);
|
int noiseGetLevelCount(NoiseGenerator* generator);
|
||||||
|
|
|
@ -139,6 +139,12 @@ void noiseSimplexInit()
|
||||||
_G4 = (5.0 - sqrt(5.0)) / 20.0;
|
_G4 = (5.0 - sqrt(5.0)) / 20.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double noiseSimplexGet1DValue(double xin)
|
||||||
|
{
|
||||||
|
/* TODO Find custom function */
|
||||||
|
return noiseSimplexGet2DValue(xin, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
double noiseSimplexGet2DValue(double xin, double yin)
|
double noiseSimplexGet2DValue(double xin, double yin)
|
||||||
{
|
{
|
||||||
double n0, n1, n2; /* Noise contributions from the three corners */
|
double n0, n1, n2; /* Noise contributions from the three corners */
|
||||||
|
@ -200,8 +206,8 @@ double noiseSimplexGet2DValue(double xin, double yin)
|
||||||
n2 = t2 * t2 * _dot2(_grad3[gi2], x2, y2);
|
n2 = t2 * t2 * _dot2(_grad3[gi2], x2, y2);
|
||||||
}
|
}
|
||||||
/* Add contributions from each corner to get the final noise value.
|
/* Add contributions from each corner to get the final noise value.
|
||||||
The result is scaled to return values in the interval [-1,1]. */
|
The result is scaled to return values in the interval [-0.5,0.5]. */
|
||||||
return 70.0 * (n0 + n1 + n2);
|
return 35.0 * (n0 + n1 + n2);
|
||||||
}
|
}
|
||||||
|
|
||||||
double noiseSimplexGet3DValue(double xin, double yin, double zin)
|
double noiseSimplexGet3DValue(double xin, double yin, double zin)
|
||||||
|
@ -334,8 +340,8 @@ double noiseSimplexGet3DValue(double xin, double yin, double zin)
|
||||||
n3 = t3 * t3 * _dot3(_grad3[gi3], x3, y3, z3);
|
n3 = t3 * t3 * _dot3(_grad3[gi3], x3, y3, z3);
|
||||||
}
|
}
|
||||||
/* Add contributions from each corner to get the final noise value.
|
/* Add contributions from each corner to get the final noise value.
|
||||||
The result is scaled to stay just inside [-1,1] */
|
The result is scaled to stay just inside [-0.5,0.5] */
|
||||||
return 32.0 * (n0 + n1 + n2 + n3);
|
return 16.0 * (n0 + n1 + n2 + n3);
|
||||||
}
|
}
|
||||||
|
|
||||||
double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
||||||
|
@ -462,6 +468,6 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
||||||
t4 *= t4;
|
t4 *= t4;
|
||||||
n4 = t4 * t4 * _dot4(_grad4[gi4], x4, y4, z4, w4);
|
n4 = t4 * t4 * _dot4(_grad4[gi4], x4, y4, z4, w4);
|
||||||
}
|
}
|
||||||
/* Sum up and scale the result to cover the range [-1,1] */
|
/* Sum up and scale the result to cover the range [-0.5,0.5] */
|
||||||
return 27.0 * (n0 + n1 + n2 + n3 + n4);
|
return 13.5 * (n0 + n1 + n2 + n3 + n4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void noiseSimplexInit();
|
void noiseSimplexInit();
|
||||||
|
double noiseSimplexGet1DValue(double xin);
|
||||||
double noiseSimplexGet2DValue(double xin, double yin);
|
double noiseSimplexGet2DValue(double xin, double yin);
|
||||||
double noiseSimplexGet3DValue(double xin, double yin, double zin);
|
double noiseSimplexGet3DValue(double xin, double yin, double zin);
|
||||||
double noiseSimplexGet4DValue(double x, double y, double z, double w);
|
double noiseSimplexGet4DValue(double x, double y, double z, double w);
|
||||||
|
|
Loading…
Reference in a new issue