paysages : Clouds refactoring (WIP) + noise settings improvements.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@506 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-01-27 19:57:43 +00:00 committed by ThunderK
parent 5c7ba1d4fc
commit 309450deca
22 changed files with 297 additions and 131 deletions

View file

@ -281,8 +281,8 @@ void DialogNoise::addLevel()
{
NoiseLevel level;
level.height = 0.1;
level.scaling = 0.1;
level.amplitude = 0.1;
level.wavelength = 0.1;
level.xoffset = 0.0;
level.yoffset = 0.0;
level.zoffset = 0.0;
@ -331,15 +331,15 @@ void DialogNoise::levelChanged(int row)
_current_level = row;
((PreviewLevel*)previewLevel)->setLevel(row);
slider_height->setValue(_current_level_params.height * 1000.0);
slider_scaling->setValue(_current_level_params.scaling * 1000.0);
slider_height->setValue(_current_level_params.amplitude * 1000.0);
slider_scaling->setValue(_current_level_params.wavelength * 1000.0);
}
// TODO else ...
}
void DialogNoise::heightChanged(int value)
{
_current_level_params.height = ((double)value) / 1000.0;
_current_level_params.amplitude = ((double)value) / 1000.0;
noiseSetLevel(_current, _current_level, _current_level_params);
previewLevel->redraw();
previewTotal->redraw();
@ -347,7 +347,7 @@ void DialogNoise::heightChanged(int value)
void DialogNoise::scalingChanged(int value)
{
_current_level_params.scaling = ((double)value) / 1000.0;
_current_level_params.wavelength = ((double)value) / 1000.0;
noiseSetLevel(_current, _current_level, _current_level_params);
previewLevel->redraw();
previewTotal->redraw();

View file

@ -24,7 +24,7 @@ public:
protected:
Color getColor(double x, double y)
{
return terrainGetPreviewColor(_renderer, x, -y, scaling);
return terrainGetPreviewColor(_renderer, x, y, scaling);
}
void updateData()
{

View file

@ -35,10 +35,10 @@ protected:
{
double height;
height = _renderer->terrain->getHeight(_renderer, x, -y, 1);
height = _renderer->terrain->getHeight(_renderer, x, y, 1);
if (height > _definition.height)
{
return terrainGetPreviewColor(_renderer, x, -y, scaling);
return terrainGetPreviewColor(_renderer, x, y, scaling);
}
else
{
@ -47,7 +47,7 @@ protected:
location.x = x;
location.y = _water.height;
location.z = -y;
location.z = y;
look.x = 0.0;
look.y = -1.0;

View file

@ -27,10 +27,13 @@ public:
int width = this->width();
int height = this->height();
double value, factor;
double minvalue, maxvalue;
noiseGetRange(noise, &minvalue, &maxvalue);
for (int x = 0; x < width; x++)
{
factor = ((double)(height / 2)) / noiseGetMaxValue(noise);
factor = ((double)(height / 2)) / maxvalue;
value = -noiseGet1DTotal(noise, ((double)x) / factor) * factor;
painter.setPen(Qt::white);
painter.drawLine(x, 0, x, height / 2 + value);

View file

@ -44,7 +44,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain):
_brush_smoothing = 0.5;
_brush_strength = 1.0;
_brush_noise = noiseCreateGenerator();
noiseAddLevelsSimple(_brush_noise, 10, 1.0, 1.0);
noiseAddLevelsSimple(_brush_noise, 10, 1.0, -0.5, 0.5);
}
WidgetHeightMap::~WidgetHeightMap()

View file

@ -192,7 +192,7 @@ static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vect
light.color.b = 0.8;
light.direction.x = -0.7;
light.direction.y = -0.7;
light.direction.z = -0.7;
light.direction.z = 0.7;
light.altered = 0;
light.reflection = 0.0;
lightingPushLight(status, &light);
@ -201,7 +201,7 @@ static void _fakeGetLightingStatus(Renderer* renderer, LightStatus* status, Vect
light.color.b = 0.34;
light.direction.x = 0.7;
light.direction.y = -0.7;
light.direction.z = 0.7;
light.direction.z = -0.7;
light.altered = 0;
light.reflection = 0.0;
lightingPushLight(status, &light);

View file

@ -42,7 +42,7 @@ void autoGenRealisticLandscape(int seed)
layersSetName(textures.layers, layer, "Ground");
texture = layersGetLayer(textures.layers, layer);
noiseClearLevels(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, 1.0);
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, -0.5, 0.5);
texture->bump_height = 0.01;
texture->bump_scaling = 0.045;
texture->material.base.r = 0.6;
@ -59,8 +59,8 @@ void autoGenRealisticLandscape(int seed)
zoneAddHeightRangeQuick(texture->zone, 1.0, -6.0, -5.0, 3.0, 15.0);
zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.05, 0.4);
noiseClearLevels(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, 0.4);
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, 0.08);
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2);
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04);
texture->bump_height = 0.002;
texture->bump_scaling = 0.03;
texture->material.base.r = 0.12;

View file

@ -63,6 +63,7 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
curveClear(definition->_coverage_by_altitude);
noiseClearLevels(definition->_shape_noise);
noiseClearLevels(definition->_edge_noise);
noiseClearLevels(definition->_coverage_noise);
switch (definition->type)
{
@ -70,10 +71,12 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, 1.0);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.2);
noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.2, 0.0);
break;
case CLOUDS_TYPE_CUMULUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
@ -81,28 +84,34 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
curveQuickAddPoint(definition->_coverage_by_altitude, 0.4, 0.8);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.7, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 7, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.4);
noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_SIMPLEX, 0.4, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 7, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.4, 0.0);
break;
case CLOUDS_TYPE_STRATOCUMULUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 2, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3);
noiseAddLevelsSimple(definition->_edge_noise, 8, 1.0, 1.0);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, 0.5);
noiseAddLevelsSimple(definition->_coverage_noise, 2, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_SIMPLEX, 0.3, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 2, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 8, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, 0.5, 0.0);
break;
case CLOUDS_TYPE_STRATUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.8, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 1.0);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, -0.3);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, 1.0);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.5);
noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_SIMPLEX, -0.3, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, -0.3, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.5, 0.0);
break;
default:
break;
@ -115,6 +124,7 @@ CloudsLayerDefinition* cloudsLayerCreateDefinition()
result = malloc(sizeof(CloudsLayerDefinition));
result->_coverage_by_altitude = curveCreate();
result->_coverage_noise = noiseCreateGenerator();
result->_shape_noise = noiseCreateGenerator();
result->_edge_noise = noiseCreateGenerator();
@ -126,6 +136,7 @@ CloudsLayerDefinition* cloudsLayerCreateDefinition()
void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition)
{
curveDelete(definition->_coverage_by_altitude);
noiseDeleteGenerator(definition->_coverage_noise);
noiseDeleteGenerator(definition->_shape_noise);
noiseDeleteGenerator(definition->_edge_noise);
free(definition);
@ -138,14 +149,17 @@ void cloudsLayerCopyDefinition(CloudsLayerDefinition* source, CloudsLayerDefinit
temp = *destination;
*destination = *source;
destination->_coverage_by_altitude = temp._coverage_by_altitude;
curveCopy(source->_coverage_by_altitude, destination->_coverage_by_altitude);
destination->_coverage_noise = temp._coverage_noise;
noiseCopy(source->_coverage_noise, destination->_coverage_noise);
destination->_shape_noise = temp._shape_noise;
noiseCopy(source->_shape_noise, destination->_shape_noise);
destination->_edge_noise = temp._edge_noise;
noiseCopy(source->_edge_noise, destination->_edge_noise);
destination->_coverage_by_altitude = temp._coverage_by_altitude;
curveCopy(source->_coverage_by_altitude, destination->_coverage_by_altitude);
}
void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
@ -156,6 +170,7 @@ void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
packWriteDouble(stream, &layer->lower_altitude);
packWriteDouble(stream, &layer->thickness);
curveSave(stream, layer->_coverage_by_altitude);
noiseSaveGenerator(stream, layer->_coverage_noise);
noiseSaveGenerator(stream, layer->_shape_noise);
noiseSaveGenerator(stream, layer->_edge_noise);
materialSave(stream, &layer->material);
@ -176,6 +191,10 @@ void _cloudsLayerLoad(PackStream* stream, CloudsLayerDefinition* layer)
packReadInt(stream, &clouds_type);
layer->type = (CloudsType)clouds_type;
packReadDouble(stream, &layer->lower_altitude);
curveLoad(stream, layer->_coverage_by_altitude);
noiseLoadGenerator(stream, layer->_coverage_noise);
noiseLoadGenerator(stream, layer->_shape_noise);
noiseLoadGenerator(stream, layer->_edge_noise);
packReadDouble(stream, &layer->thickness);
materialLoad(stream, &layer->material);
packReadDouble(stream, &layer->hardness);

View file

@ -18,4 +18,6 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition);
Color cloudsLayerFilterLight(CloudsLayerDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light);
Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer* renderer, Vector3 start, Vector3 end);
CloudsInfo cloudsGetLayerInfo(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location);
#endif

View file

@ -44,6 +44,7 @@ typedef struct
double minimumlight;
Curve* _coverage_by_altitude;
NoiseGenerator* _coverage_noise;
NoiseGenerator* _shape_noise;
NoiseGenerator* _edge_noise;
} CloudsLayerDefinition;
@ -53,8 +54,15 @@ typedef struct
Layers* layers;
} CloudsDefinition;
typedef struct
{
int inside;
double density;
double distance_to_edge;
} CloudsInfo;
typedef Color (*FuncCloudsGetColor)(Renderer* renderer, Color base, Vector3 start, Vector3 end);
typedef CloudsInfo (*FuncCloudsGetLayerInfo)(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location);
typedef struct
{
@ -62,6 +70,7 @@ typedef struct
FuncCloudsGetColor getColor;
FuncLightingAlterLight alterLight;
FuncCloudsGetLayerInfo getLayerInfo;
} CloudsRenderer;

View file

@ -23,6 +23,21 @@ static Color _fakeGetColor(Renderer* renderer, Color base, Vector3 start, Vector
return base;
}
static CloudsInfo _fakeGetLayerInfo(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
{
UNUSED(renderer);
UNUSED(layer);
UNUSED(location);
CloudsInfo result;
result.inside = 0;
result.density = 0.0;
result.distance_to_edge = 1.0;
return result;
}
/******************** Real ********************/
/*static int _cmpLayer(const void* layer1, const void* layer2)
{
@ -73,6 +88,7 @@ static CloudsRenderer* _createRenderer()
result->getColor = _fakeGetColor;
result->alterLight = (FuncLightingAlterLight)_fakeAlterLight;
result->getLayerInfo = _fakeGetLayerInfo;
return result;
}
@ -89,6 +105,7 @@ static void _bindRenderer(Renderer* renderer, CloudsDefinition* definition)
renderer->clouds->getColor = _getColor;
renderer->clouds->alterLight = (FuncLightingAlterLight)_alterLight;
renderer->clouds->getLayerInfo = cloudsGetLayerInfo;
lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer);
}

View file

@ -5,6 +5,7 @@
*/
#include "../renderer.h"
#include "../tools.h"
static double _standardCoverageFunc(CloudsLayerDefinition* layer, Vector3 position)
{
@ -22,7 +23,7 @@ static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3
{
double density, coverage, val;
val = noiseGet3DTotal(layer->_shape_noise, position.x / layer->shape_scaling, position.y / layer->shape_scaling, position.z / layer->shape_scaling) / noiseGetMaxValue(layer->_shape_noise);
val = noiseGet3DTotal(layer->_shape_noise, position.x / layer->shape_scaling, position.y / layer->shape_scaling, position.z / layer->shape_scaling) / 0.5;
coverage = _standardCoverageFunc(layer, position);
density = 0.5 * val - 0.5 + coverage;
@ -39,7 +40,7 @@ static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3
{
density /= layer->edge_length;
val = 0.5 * noiseGet3DTotal(layer->_edge_noise, position.x / layer->edge_scaling, position.y / layer->edge_scaling, position.z / layer->edge_scaling) / noiseGetMaxValue(layer->_edge_noise);
val = 0.5 * noiseGet3DTotal(layer->_edge_noise, position.x / layer->edge_scaling, position.y / layer->edge_scaling, position.z / layer->edge_scaling) / 0.5;
val = val - 0.5 + density;
return val * (density * coverage * layer->shape_scaling + (1.0 - density) * layer->edge_scaling);
@ -372,3 +373,67 @@ Color cloudsLayerFilterLight(CloudsLayerDefinition* definition, Renderer* render
return light;
}
/*
* Get the coverage factor at the given location [0.0;1.0].
* 0.0 means no cloud is present.
* 1.0 means full layer.
*/
static inline double _getLayerCoverage(CloudsLayerDefinition* layer, double x, double z)
{
return sin(x) * cos(z);
}
/*
* Get the local density factor at the given location [0.0;1.0].
* 0.0 means no cloud is present.
* 1.0 means full density (deep inside cloud).
*/
static inline double _getLayerDensity(CloudsLayerDefinition* layer, Vector3 location, double coverage)
{
return 1.0;
}
CloudsInfo cloudsGetLayerInfo(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
{
CloudsInfo result;
UNUSED(renderer);
result.density = 0.0;
result.distance_to_edge = 1.0;
/* Get coverage info */
double coverage = _getLayerCoverage(layer, location.x, location.z);
if (coverage <= 0.0)
{
/* TODO Distance to edge */
}
else
{
/* Apply altitude to coverage */
coverage *= curveGetValue(layer->_coverage_by_altitude, (location.y - layer->lower_altitude) / layer->thickness);
if (coverage <= 0.0)
{
/* TODO Distance to edge */
}
else
{
/* Get local density */
result.density = _getLayerDensity(layer, location, coverage);
if (result.density <= 0)
{
/* TODO Distance to edge */
}
else
{
/* TODO Distance to edge */
}
}
}
result.inside = (result.density > 0.0);
return result;
}

View file

@ -12,16 +12,15 @@
#define MAX_LEVEL_COUNT 30
struct NoiseLevel;
struct NoiseGenerator
{
NoiseFunction function;
double height_offset;
int level_count;
struct NoiseLevel levels[MAX_LEVEL_COUNT];
NoiseLevel levels[MAX_LEVEL_COUNT];
double _max_height;
double _min_value;
double _max_value;
double (*_func_noise_1d)(double x);
double (*_func_noise_2d)(double x, double y);
double (*_func_noise_3d)(double x, double y, double z);
@ -39,7 +38,7 @@ void noiseInit()
double min, max, value;
noise = noiseCreateGenerator();
noiseSetFunctionParams(noise, NOISE_FUNCTION_NAIVE, 0.0);
noiseAddLevelSimple(noise, 1.0, 1.0);
noiseAddLevelSimple(noise, 1.0, 0.0, 1.0);
min = 100000.0;
max = -100000.0;
for (x = 0; x < 1000000; x++)
@ -77,6 +76,7 @@ NoiseGenerator* noiseCreateGenerator()
result = malloc(sizeof(NoiseGenerator));
result->function.algorithm = NOISE_FUNCTION_SIMPLEX;
result->function.ridge_factor = 0.0;
result->function.curve_factor = 0.0;
result->level_count = 0;
result->height_offset = 0.0;
@ -97,6 +97,7 @@ void noiseSaveGenerator(PackStream* stream, NoiseGenerator* generator)
x = (int)generator->function.algorithm;
packWriteInt(stream, &x);
packWriteDouble(stream, &generator->function.ridge_factor);
packWriteDouble(stream, &generator->function.curve_factor);
packWriteDouble(stream, &generator->height_offset);
packWriteInt(stream, &generator->level_count);
@ -105,8 +106,9 @@ void noiseSaveGenerator(PackStream* stream, NoiseGenerator* generator)
{
NoiseLevel* level = generator->levels + x;
packWriteDouble(stream, &level->scaling);
packWriteDouble(stream, &level->height);
packWriteDouble(stream, &level->wavelength);
packWriteDouble(stream, &level->amplitude);
packWriteDouble(stream, &level->minvalue);
packWriteDouble(stream, &level->xoffset);
packWriteDouble(stream, &level->yoffset);
packWriteDouble(stream, &level->zoffset);
@ -120,6 +122,7 @@ void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator)
packReadInt(stream, &x);
generator->function.algorithm = (NoiseFunctionAlgorithm)x;
packReadDouble(stream, &generator->function.ridge_factor);
packReadDouble(stream, &generator->function.curve_factor);
packReadDouble(stream, &generator->height_offset);
packReadInt(stream, &generator->level_count);
@ -128,8 +131,9 @@ void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator)
{
NoiseLevel* level = generator->levels + x;
packReadDouble(stream, &level->scaling);
packReadDouble(stream, &level->height);
packReadDouble(stream, &level->wavelength);
packReadDouble(stream, &level->amplitude);
packReadDouble(stream, &level->minvalue);
packReadDouble(stream, &level->xoffset);
packReadDouble(stream, &level->yoffset);
packReadDouble(stream, &level->zoffset);
@ -152,7 +156,6 @@ void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination)
void noiseValidate(NoiseGenerator* generator)
{
int x;
double max_height = generator->height_offset;
if (generator->function.algorithm < 0 || generator->function.algorithm > NOISE_FUNCTION_NAIVE)
{
@ -185,13 +188,31 @@ void noiseValidate(NoiseGenerator* generator)
{
generator->function.ridge_factor = -0.5;
}
for (x = 0; x < generator->level_count; x++)
if (generator->function.curve_factor > 1.0)
{
max_height += generator->levels[x].height / 2.0;
generator->function.curve_factor = 1.0;
}
if (generator->function.curve_factor < -1.0)
{
generator->function.curve_factor = -1.0;
}
generator->_max_height = max_height;
generator->_min_value = generator->height_offset;
generator->_max_value = generator->height_offset;
for (x = 0; x < generator->level_count; x++)
{
double min_value = generator->levels[x].minvalue;
double max_value = min_value + generator->levels[x].amplitude;
if (min_value < generator->_min_value)
{
generator->_min_value = min_value;
}
if (max_value > generator->_max_value)
{
generator->_max_value = max_value;
}
}
}
NoiseFunction noiseGetFunction(NoiseGenerator* generator)
@ -205,9 +226,9 @@ void noiseSetFunction(NoiseGenerator* generator, NoiseFunction* function)
noiseValidate(generator);
}
void noiseSetFunctionParams(NoiseGenerator* generator, NoiseFunctionAlgorithm algorithm, double ridge_factor)
void noiseSetFunctionParams(NoiseGenerator* generator, NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor)
{
NoiseFunction function = {algorithm, ridge_factor};
NoiseFunction function = {algorithm, ridge_factor, curve_factor};
noiseSetFunction(generator, &function);
}
@ -215,12 +236,13 @@ void noiseForceValue(NoiseGenerator* generator, double value)
{
noiseClearLevels(generator);
generator->height_offset = value;
noiseAddLevelSimple(generator, 1.0, 0.0); /* FIXME Should not be needed */
noiseAddLevelSimple(generator, 1.0, 0.0, 0.0); /* FIXME Should not be needed */
}
double noiseGetMaxValue(NoiseGenerator* generator)
void noiseGetRange(NoiseGenerator* generator, double* minvalue, double* maxvalue)
{
return generator->_max_height;
*minvalue = generator->_min_value;
*maxvalue = generator->_max_value;
}
int noiseGetLevelCount(NoiseGenerator* generator)
@ -244,12 +266,13 @@ void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level)
}
}
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double height)
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double minvalue, double maxvalue)
{
NoiseLevel level;
level.scaling = scaling;
level.height = height;
level.wavelength = scaling;
level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue;
level.xoffset = toolsRandom();
level.yoffset = toolsRandom();
level.zoffset = toolsRandom();
@ -257,7 +280,7 @@ void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double heigh
noiseAddLevel(generator, level);
}
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double height_factor, int randomize_offset)
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor, double center_factor, int randomize_offset)
{
int i;
@ -270,18 +293,20 @@ void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start
start_level.zoffset = toolsRandom();
}
noiseAddLevel(generator, start_level);
start_level.scaling *= scaling_factor;
start_level.height *= height_factor;
start_level.minvalue += start_level.amplitude * (1.0 - amplitude_factor) * center_factor;
start_level.wavelength *= scaling_factor;
start_level.amplitude *= amplitude_factor;
}
}
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double height)
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double minvalue, double maxvalue)
{
NoiseLevel level;
level.scaling = scaling;
level.height = height;
noiseAddLevels(generator, level_count, level, 0.5, 0.5, 1);
level.wavelength = scaling;
level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue;
noiseAddLevels(generator, level_count, level, 0.5, 0.5, 0.5, 1);
}
void noiseRemoveLevel(NoiseGenerator* generator, int level)
@ -319,12 +344,13 @@ void noiseSetLevel(NoiseGenerator* generator, int level, NoiseLevel params)
}
}
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double height)
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double minvalue, double maxvalue)
{
NoiseLevel params;
params.scaling = scaling;
params.height = height;
params.wavelength = scaling;
params.minvalue = minvalue;
params.amplitude = maxvalue - minvalue;
params.xoffset = toolsRandom();
params.yoffset = toolsRandom();
params.zoffset = toolsRandom();
@ -332,42 +358,62 @@ void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, d
noiseSetLevel(generator, level, params);
}
void noiseNormalizeHeight(NoiseGenerator* generator, double min_height, double max_height, int adjust_scaling)
void noiseNormalizeAmplitude(NoiseGenerator* generator, double minvalue, double maxvalue, int adjust_scaling)
{
int level;
double height = 0.0;
double target_height = max_height - min_height;
double current_minvalue, current_maxvalue, current_amplitude;
double target_amplitude, factor;
if (generator->level_count == 0)
{
return;
}
target_amplitude = maxvalue - minvalue;
noiseGetRange(generator, &current_minvalue, &current_maxvalue);
current_amplitude = current_maxvalue - current_minvalue;
factor = target_amplitude / current_amplitude;
for (level = 0; level < generator->level_count; level++)
{
height += generator->levels[level].height;
}
for (level = 0; level < generator->level_count; level++)
{
generator->levels[level].height *= target_height / height;
generator->levels[level].minvalue = minvalue + (generator->levels[level].minvalue - current_minvalue) * factor;
generator->levels[level].amplitude *= factor;
if (adjust_scaling)
{
generator->levels[level].scaling *= target_height / height;
generator->levels[level].wavelength *= factor;
}
}
generator->height_offset = min_height + target_height / 2.0;
/*generator->height_offset = minvalue + (generator->height_offset - current_minvalue) * factor;*/
noiseValidate(generator);
}
static inline double _applyRidge(double value, double ridge)
static inline double _fixValue(double value, double ridge, double curve)
{
if (value < 0.0)
{
value = 0.0;
}
else if (value > 1.0)
{
value = 1.0;
}
if (curve > 0.0)
{
value = value * (1.0 - curve) + sqrt(value) * curve;
}
else if (curve < 0.0)
{
value = value * (1.0 - curve) + value * value * curve;
}
if (ridge > 0.0)
{
return fabs(value + 0.5 - ridge) / (1.0 - ridge) - 0.5;
return fabs(value - ridge) / (1.0 - ridge);
}
else if (ridge < 0.0)
{
return -fabs(value - 0.5 - ridge) / (1.0 + ridge) + 0.5;
return 1.0 - fabs(value - 1.0 - ridge) / (1.0 + ridge);
}
else
{
@ -392,7 +438,7 @@ static inline double _applyRidge(double value, double ridge)
static inline double _get1DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x)
{
return _applyRidge(generator->_func_noise_1d(x / level->scaling + level->xoffset), generator->function.ridge_factor) * level->height;
return level->minvalue + _fixValue(generator->_func_noise_1d(x / level->wavelength + level->xoffset), generator->function.ridge_factor, generator->function.curve_factor) * level->amplitude;
}
double noiseGet1DLevel(NoiseGenerator* generator, int level, double x)
@ -428,7 +474,7 @@ double noiseGet1DDetail(NoiseGenerator* generator, double x, double detail)
result = 0.0;
for (level = 0; level < generator->level_count; level++)
{
height = generator->levels[level].height;
height = generator->levels[level].amplitude;
factor = 1.0;
if (height < detail * 0.25)
{
@ -449,7 +495,7 @@ double noiseGet1DDetail(NoiseGenerator* generator, double x, double detail)
static inline double _get2DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x, double y)
{
return _applyRidge(generator->_func_noise_2d(x / level->scaling + level->xoffset, y / level->scaling + level->yoffset), generator->function.ridge_factor) * level->height;
return level->minvalue + _fixValue(generator->_func_noise_2d(x / level->wavelength + level->xoffset, y / level->wavelength + level->yoffset), generator->function.ridge_factor, generator->function.curve_factor) * level->amplitude;
}
double noiseGet2DLevel(NoiseGenerator* generator, int level, double x, double y)
@ -485,7 +531,7 @@ double noiseGet2DDetail(NoiseGenerator* generator, double x, double y, double de
result = 0.0;
for (level = 0; level < generator->level_count; level++)
{
height = generator->levels[level].height;
height = generator->levels[level].amplitude;
factor = 1.0;
if (height < detail * 0.25)
{
@ -506,7 +552,7 @@ double noiseGet2DDetail(NoiseGenerator* generator, double x, double y, double de
static inline double _get3DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x, double y, double z)
{
return _applyRidge(generator->_func_noise_3d(x / level->scaling + level->xoffset, y / level->scaling + level->yoffset, z / level->scaling + level->zoffset), generator->function.ridge_factor) * level->height;
return level->minvalue + _fixValue(generator->_func_noise_3d(x / level->wavelength + level->xoffset, y / level->wavelength + level->yoffset, z / level->wavelength + level->zoffset), generator->function.ridge_factor, generator->function.curve_factor) * level->amplitude;
}
double noiseGet3DLevel(NoiseGenerator* generator, int level, double x, double y, double z)
@ -542,7 +588,7 @@ double noiseGet3DDetail(NoiseGenerator* generator, double x, double y, double z,
result = 0.0;
for (level = 0; level < generator->level_count; level++)
{
height = generator->levels[level].height;
height = generator->levels[level].amplitude;
factor = 1.0;
if (height < detail * 0.25)
{

View file

@ -17,18 +17,20 @@ typedef enum
typedef struct
{
NoiseFunctionAlgorithm algorithm;
double ridge_factor;
double ridge_factor; /* -0.5;0.5 */
double curve_factor; /* -1.0;1.0 */
} NoiseFunction;
struct NoiseLevel
typedef struct
{
double scaling;
double height;
double wavelength;
double amplitude;
double minvalue;
double xoffset;
double yoffset;
double zoffset;
};
typedef struct NoiseLevel NoiseLevel;
} NoiseLevel;
typedef struct NoiseGenerator NoiseGenerator;
void noiseInit();
@ -44,20 +46,20 @@ void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination);
void noiseValidate(NoiseGenerator* generator);
NoiseFunction noiseGetFunction(NoiseGenerator* generator);
void noiseSetFunction(NoiseGenerator* generator, NoiseFunction* function);
void noiseSetFunctionParams(NoiseGenerator* generator, NoiseFunctionAlgorithm algorithm, double ridge_factor);
void noiseSetFunctionParams(NoiseGenerator* generator, NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor);
void noiseForceValue(NoiseGenerator* generator, double value);
double noiseGetMaxValue(NoiseGenerator* generator);
void noiseGetRange(NoiseGenerator* generator, double* minvalue, double* maxvalue);
int noiseGetLevelCount(NoiseGenerator* generator);
void noiseClearLevels(NoiseGenerator* generator);
void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level);
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double height);
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double height_factor, int randomize_offset);
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double height);
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double minvalue, double maxvalue);
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor, double center_factor, int randomize_offset);
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double minvalue, double maxvalue);
void noiseRemoveLevel(NoiseGenerator* generator, int level);
int noiseGetLevel(NoiseGenerator* generator, int level, NoiseLevel* params);
void noiseSetLevel(NoiseGenerator* generator, int level, NoiseLevel params);
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double height);
void noiseNormalizeHeight(NoiseGenerator* generator, double min_height, double max_height, int adjust_scaling);
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double minvalue, double maxvalue);
void noiseNormalizeAmplitude(NoiseGenerator* generator, double minvalue, double maxvalue, int adjust_scaling);
double noiseGet1DLevel(NoiseGenerator* generator, int level, double x);
double noiseGet1DTotal(NoiseGenerator* generator, double x);
double noiseGet1DDetail(NoiseGenerator* generator, double x, double detail);

View file

@ -15,7 +15,7 @@ static double* _noise_pool;
void noiseNaiveInit()
{
int i;
_noise_pool_size = 1048576;
_noise_pool = malloc(sizeof(double) * _noise_pool_size);
@ -33,7 +33,7 @@ void noiseNaiveQuit()
void noiseNaiveSave(PackStream* stream)
{
int i;
packWriteInt(stream, &_noise_pool_size);
for (i = 0; i < _noise_pool_size; i++)
{
@ -44,7 +44,7 @@ void noiseNaiveSave(PackStream* stream)
void noiseNaiveLoad(PackStream* stream)
{
int i;
packReadInt(stream, &_noise_pool_size);
_noise_pool = realloc(_noise_pool, sizeof(double) * _noise_pool_size);
for (i = 0; i < _noise_pool_size; i++)
@ -56,7 +56,7 @@ void noiseNaiveLoad(PackStream* stream)
double noiseNaiveGet1DValue(double x)
{
x *= 3.0;
int size = _noise_pool_size;
int xbase = (int)floor(x);
@ -89,15 +89,15 @@ double noiseNaiveGet1DValue(double x)
buf_cubic_x[1] = _noise_pool[x1 % _noise_pool_size];
buf_cubic_x[2] = _noise_pool[x2 % _noise_pool_size];
buf_cubic_x[3] = _noise_pool[x3 % _noise_pool_size];
return toolsCubicInterpolate(buf_cubic_x, xinternal) * 0.837;
return toolsCubicInterpolate(buf_cubic_x, xinternal) * 0.837 + 0.5;
}
double noiseNaiveGet2DValue(double x, double y)
{
x *= 3.0;
y *= 3.0;
int size = (int)pow(_noise_pool_size, 0.5);
int xbase = (int)floor(x);
@ -175,7 +175,7 @@ double noiseNaiveGet2DValue(double x, double y)
buf_cubic_x[3] = _noise_pool[(y3 * size + x3) % _noise_pool_size];
buf_cubic_y[3] = toolsCubicInterpolate(buf_cubic_x, xinternal);
return toolsCubicInterpolate(buf_cubic_y, yinternal) * 0.723;
return toolsCubicInterpolate(buf_cubic_y, yinternal) * 0.723 + 0.5;
}
double noiseNaiveGet3DValue(double x, double y, double z)
@ -183,7 +183,7 @@ double noiseNaiveGet3DValue(double x, double y, double z)
x *= 3.0;
y *= 3.0;
z *= 3.0;
int size = (int)pow(_noise_pool_size, 0.33333333333333333);
int xbase = (int)floor(x);
@ -365,10 +365,10 @@ double noiseNaiveGet3DValue(double x, double y, double z)
buf_cubic_z[3] = toolsCubicInterpolate(buf_cubic_y, yinternal);
return toolsCubicInterpolate(buf_cubic_z, zinternal) * 0.794;
return toolsCubicInterpolate(buf_cubic_z, zinternal) * 0.794 + 0.5;
}
/*double noiseNaiveGet4DValue(double x, double y, double z, double w)
{
}*/

View file

@ -2,7 +2,7 @@
/*
* Perlin noise implementation.
*
*
* Based on Ken Perlin implementation.
*/
@ -50,7 +50,7 @@ double noisePerlinGet1DValue(double x)
u = rx0 * g1[ p[ bx0 ] ];
v = rx1 * g1[ p[ bx1 ] ];
return lerp(sx, u, v) * 1.068;
return lerp(sx, u, v) * 1.068 + 0.5;
}
double noisePerlinGet2DValue(double x, double y)
@ -84,7 +84,7 @@ double noisePerlinGet2DValue(double x, double y)
q = g2[ b11 ] ; v = at2(rx1,ry1);
b = lerp(sx, u, v);
return lerp(sy, a, b) * 0.709;
return lerp(sy, a, b) * 0.709 + 0.5;
}
double noisePerlinGet3DValue(double x, double y, double z)
@ -132,7 +132,7 @@ double noisePerlinGet3DValue(double x, double y, double z)
d = lerp(sy, a, b);
return lerp(sz, c, d) * 0.661;
return lerp(sz, c, d) * 0.661 + 0.5;
}
static void _normalize2(double v[2])

View file

@ -2,7 +2,7 @@
/*
* Simplex noise implementation.
*
*
* Based on Stefan Gustavson implementation.
*/
@ -207,7 +207,7 @@ double noiseSimplexGet2DValue(double x, double y)
}
/* Add contributions from each corner to get the final noise value.
The result is scaled to return values in the interval [-0.5,0.5]. */
return 35.0 * (n0 + n1 + n2);
return 35.0 * (n0 + n1 + n2) + 0.5;
}
double noiseSimplexGet3DValue(double x, double y, double z)
@ -341,7 +341,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
}
/* Add contributions from each corner to get the final noise value.
The result is scaled to stay just inside [-0.5,0.5] */
return 16.0 * (n0 + n1 + n2 + n3);
return 16.0 * (n0 + n1 + n2 + n3) + 0.5;
}
double noiseSimplexGet4DValue(double x, double y, double z, double w)
@ -469,5 +469,5 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
n4 = t4 * t4 * _dot4(_grad4[gi4], x4, y4, z4, w4);
}
/* Sum up and scale the result to cover the range [-0.5,0.5] */
return 13.5 * (n0 + n1 + n2 + n3 + n4);
return 13.5 * (n0 + n1 + n2 + n3 + n4) + 0.5;
}

View file

@ -11,8 +11,9 @@ static void _validateDefinition(TerrainDefinition* definition)
noiseValidate(definition->_height_noise);
/* Get minimal and maximal height */
definition->_min_height = -noiseGetMaxValue(definition->_height_noise) * definition->height;
definition->_max_height = noiseGetMaxValue(definition->_height_noise) * definition->height;
noiseGetRange(definition->_height_noise, &definition->_min_height, &definition->_max_height);
definition->_min_height *= definition->height;
definition->_max_height *= definition->height;
}
static TerrainDefinition* _createDefinition()

View file

@ -13,8 +13,8 @@ void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset)
{
case TERRAIN_PRESET_STANDARD:
noiseClearLevels(definition->_height_noise);
noiseAddLevelsSimple(definition->_height_noise, resolution, pow(2.0, resolution - 1), 25.0);
noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, 0.0);
noiseAddLevelsSimple(definition->_height_noise, resolution, pow(2.0, resolution - 1), -12.5, 12.5);
noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
definition->scaling = 1.0;
definition->height = 1.0;
definition->shadow_smoothing = 0.03;

View file

@ -31,7 +31,7 @@ static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3
light.color.b = 0.6;
light.direction.x = -1.0;
light.direction.y = -0.5;
light.direction.z = -1.0;
light.direction.z = 1.0;
light.direction = v3Normalize(light.direction);
light.altered = 1;
light.reflection = 1.0;
@ -42,7 +42,7 @@ static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3
light.color.b = 0.2;
light.direction.x = 1.0;
light.direction.y = -0.5;
light.direction.z = 1.0;
light.direction.z = -1.0;
light.direction = v3Normalize(light.direction);
light.altered = 0;
light.reflection = 0.0;

View file

@ -62,7 +62,7 @@ TextureLayerDefinition* texturesLayerCreateDefinition()
result->zone = zoneCreate();
result->bump_noise = noiseCreateGenerator();
noiseAddLevelsSimple(result->bump_noise, 8, 1.0, 1.0);
noiseAddLevelsSimple(result->bump_noise, 8, 1.0, -0.5, 0.5);
result->bump_height = 0.1;
result->bump_scaling = 0.1;
result->material.base = COLOR_WHITE;

View file

@ -136,13 +136,13 @@ void waterValidateDefinition(WaterDefinition* definition)
noiseClearLevels(definition->_waves_noise);
if (definition->waves_height > 0.0)
{
noiseAddLevelsSimple(definition->_waves_noise, 2, scaling, definition->waves_height * scaling * 0.03);
noiseAddLevelsSimple(definition->_waves_noise, 2, scaling, -definition->waves_height * scaling * 0.015, definition->waves_height * scaling * 0.015);
}
if (definition->detail_height > 0.0)
{
noiseAddLevelsSimple(definition->_waves_noise, 3, scaling * 0.1, definition->detail_height * scaling * 0.03);
noiseAddLevelsSimple(definition->_waves_noise, 3, scaling * 0.1, -definition->detail_height * scaling * 0.015, definition->detail_height * scaling * 0.015);
}
noiseSetFunctionParams(definition->_waves_noise, NOISE_FUNCTION_SIMPLEX, -definition->turbulence);
noiseSetFunctionParams(definition->_waves_noise, NOISE_FUNCTION_SIMPLEX, -definition->turbulence, 0.0);
noiseValidate(definition->_waves_noise);
}
@ -200,10 +200,12 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal)
HeightInfo waterGetHeightInfo(WaterDefinition* definition)
{
HeightInfo info;
double noise_minvalue, noise_maxvalue;
info.base_height = definition->height;
info.min_height = definition->height - noiseGetMaxValue(definition->_waves_noise);
info.max_height = definition->height + noiseGetMaxValue(definition->_waves_noise);
noiseGetRange(definition->_waves_noise, &noise_minvalue, &noise_maxvalue);
info.min_height = definition->height + noise_minvalue;
info.max_height = definition->height + noise_maxvalue;
return info;
}