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

View file

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

View file

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

View file

@ -27,10 +27,13 @@ public:
int width = this->width(); int width = this->width();
int height = this->height(); int height = this->height();
double value, factor; double value, factor;
double minvalue, maxvalue;
noiseGetRange(noise, &minvalue, &maxvalue);
for (int x = 0; x < width; x++) 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; value = -noiseGet1DTotal(noise, ((double)x) / factor) * factor;
painter.setPen(Qt::white); painter.setPen(Qt::white);
painter.drawLine(x, 0, x, height / 2 + value); 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_smoothing = 0.5;
_brush_strength = 1.0; _brush_strength = 1.0;
_brush_noise = noiseCreateGenerator(); _brush_noise = noiseCreateGenerator();
noiseAddLevelsSimple(_brush_noise, 10, 1.0, 1.0); noiseAddLevelsSimple(_brush_noise, 10, 1.0, -0.5, 0.5);
} }
WidgetHeightMap::~WidgetHeightMap() WidgetHeightMap::~WidgetHeightMap()

View file

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

View file

@ -42,7 +42,7 @@ void autoGenRealisticLandscape(int seed)
layersSetName(textures.layers, layer, "Ground"); layersSetName(textures.layers, layer, "Ground");
texture = layersGetLayer(textures.layers, layer); texture = layersGetLayer(textures.layers, layer);
noiseClearLevels(texture->bump_noise); 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_height = 0.01;
texture->bump_scaling = 0.045; texture->bump_scaling = 0.045;
texture->material.base.r = 0.6; 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); 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); zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.05, 0.4);
noiseClearLevels(texture->bump_noise); noiseClearLevels(texture->bump_noise);
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, 0.4); noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2);
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, 0.08); noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04);
texture->bump_height = 0.002; texture->bump_height = 0.002;
texture->bump_scaling = 0.03; texture->bump_scaling = 0.03;
texture->material.base.r = 0.12; texture->material.base.r = 0.12;

View file

@ -63,6 +63,7 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
curveClear(definition->_coverage_by_altitude); curveClear(definition->_coverage_by_altitude);
noiseClearLevels(definition->_shape_noise); noiseClearLevels(definition->_shape_noise);
noiseClearLevels(definition->_edge_noise); noiseClearLevels(definition->_edge_noise);
noiseClearLevels(definition->_coverage_noise);
switch (definition->type) 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.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0); curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 1.0); noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.0); noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, 1.0); noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.2); 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; break;
case CLOUDS_TYPE_CUMULUS: case CLOUDS_TYPE_CUMULUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0); 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.4, 0.8);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.7, 1.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.7, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0); curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 7, 1.0, 1.0); noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.4); 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; break;
case CLOUDS_TYPE_STRATOCUMULUS: case CLOUDS_TYPE_STRATOCUMULUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.5, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0); curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 2, 1.0, 1.0); noiseAddLevelsSimple(definition->_coverage_noise, 2, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3); noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_SIMPLEX, 0.3, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 8, 1.0, 1.0); noiseAddLevelsSimple(definition->_shape_noise, 2, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, 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; break;
case CLOUDS_TYPE_STRATUS: case CLOUDS_TYPE_STRATUS:
curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.0, 0.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.2, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.8, 1.0); curveQuickAddPoint(definition->_coverage_by_altitude, 0.8, 1.0);
curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0); curveQuickAddPoint(definition->_coverage_by_altitude, 1.0, 0.0);
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 1.0); noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, -0.3); noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_SIMPLEX, -0.3, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, 1.0); noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, -0.5, 0.5);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -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; break;
default: default:
break; break;
@ -115,6 +124,7 @@ CloudsLayerDefinition* cloudsLayerCreateDefinition()
result = malloc(sizeof(CloudsLayerDefinition)); result = malloc(sizeof(CloudsLayerDefinition));
result->_coverage_by_altitude = curveCreate(); result->_coverage_by_altitude = curveCreate();
result->_coverage_noise = noiseCreateGenerator();
result->_shape_noise = noiseCreateGenerator(); result->_shape_noise = noiseCreateGenerator();
result->_edge_noise = noiseCreateGenerator(); result->_edge_noise = noiseCreateGenerator();
@ -126,6 +136,7 @@ CloudsLayerDefinition* cloudsLayerCreateDefinition()
void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition) void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition)
{ {
curveDelete(definition->_coverage_by_altitude); curveDelete(definition->_coverage_by_altitude);
noiseDeleteGenerator(definition->_coverage_noise);
noiseDeleteGenerator(definition->_shape_noise); noiseDeleteGenerator(definition->_shape_noise);
noiseDeleteGenerator(definition->_edge_noise); noiseDeleteGenerator(definition->_edge_noise);
free(definition); free(definition);
@ -138,14 +149,17 @@ void cloudsLayerCopyDefinition(CloudsLayerDefinition* source, CloudsLayerDefinit
temp = *destination; temp = *destination;
*destination = *source; *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; destination->_shape_noise = temp._shape_noise;
noiseCopy(source->_shape_noise, destination->_shape_noise); noiseCopy(source->_shape_noise, destination->_shape_noise);
destination->_edge_noise = temp._edge_noise; destination->_edge_noise = temp._edge_noise;
noiseCopy(source->_edge_noise, destination->_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) void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
@ -156,6 +170,7 @@ void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
packWriteDouble(stream, &layer->lower_altitude); packWriteDouble(stream, &layer->lower_altitude);
packWriteDouble(stream, &layer->thickness); packWriteDouble(stream, &layer->thickness);
curveSave(stream, layer->_coverage_by_altitude); curveSave(stream, layer->_coverage_by_altitude);
noiseSaveGenerator(stream, layer->_coverage_noise);
noiseSaveGenerator(stream, layer->_shape_noise); noiseSaveGenerator(stream, layer->_shape_noise);
noiseSaveGenerator(stream, layer->_edge_noise); noiseSaveGenerator(stream, layer->_edge_noise);
materialSave(stream, &layer->material); materialSave(stream, &layer->material);
@ -176,6 +191,10 @@ void _cloudsLayerLoad(PackStream* stream, CloudsLayerDefinition* layer)
packReadInt(stream, &clouds_type); packReadInt(stream, &clouds_type);
layer->type = (CloudsType)clouds_type; layer->type = (CloudsType)clouds_type;
packReadDouble(stream, &layer->lower_altitude); 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); packReadDouble(stream, &layer->thickness);
materialLoad(stream, &layer->material); materialLoad(stream, &layer->material);
packReadDouble(stream, &layer->hardness); 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 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); Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer* renderer, Vector3 start, Vector3 end);
CloudsInfo cloudsGetLayerInfo(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location);
#endif #endif

View file

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

View file

@ -23,6 +23,21 @@ static Color _fakeGetColor(Renderer* renderer, Color base, Vector3 start, Vector
return base; 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 ********************/ /******************** Real ********************/
/*static int _cmpLayer(const void* layer1, const void* layer2) /*static int _cmpLayer(const void* layer1, const void* layer2)
{ {
@ -73,6 +88,7 @@ static CloudsRenderer* _createRenderer()
result->getColor = _fakeGetColor; result->getColor = _fakeGetColor;
result->alterLight = (FuncLightingAlterLight)_fakeAlterLight; result->alterLight = (FuncLightingAlterLight)_fakeAlterLight;
result->getLayerInfo = _fakeGetLayerInfo;
return result; return result;
} }
@ -89,6 +105,7 @@ static void _bindRenderer(Renderer* renderer, CloudsDefinition* definition)
renderer->clouds->getColor = _getColor; renderer->clouds->getColor = _getColor;
renderer->clouds->alterLight = (FuncLightingAlterLight)_alterLight; renderer->clouds->alterLight = (FuncLightingAlterLight)_alterLight;
renderer->clouds->getLayerInfo = cloudsGetLayerInfo;
lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer); lightingManagerRegisterFilter(renderer->lighting, (FuncLightingAlterLight)_alterLight, renderer);
} }

View file

@ -5,6 +5,7 @@
*/ */
#include "../renderer.h" #include "../renderer.h"
#include "../tools.h"
static double _standardCoverageFunc(CloudsLayerDefinition* layer, Vector3 position) static double _standardCoverageFunc(CloudsLayerDefinition* layer, Vector3 position)
{ {
@ -22,7 +23,7 @@ static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3
{ {
double density, coverage, val; 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); coverage = _standardCoverageFunc(layer, position);
density = 0.5 * val - 0.5 + coverage; density = 0.5 * val - 0.5 + coverage;
@ -39,7 +40,7 @@ static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3
{ {
density /= layer->edge_length; 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; val = val - 0.5 + density;
return val * (density * coverage * layer->shape_scaling + (1.0 - density) * layer->edge_scaling); 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; 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 #define MAX_LEVEL_COUNT 30
struct NoiseLevel;
struct NoiseGenerator struct NoiseGenerator
{ {
NoiseFunction function; NoiseFunction function;
double height_offset; double height_offset;
int level_count; 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_1d)(double x);
double (*_func_noise_2d)(double x, double y); double (*_func_noise_2d)(double x, double y);
double (*_func_noise_3d)(double x, double y, double z); double (*_func_noise_3d)(double x, double y, double z);
@ -39,7 +38,7 @@ void noiseInit()
double min, max, value; double min, max, value;
noise = noiseCreateGenerator(); noise = noiseCreateGenerator();
noiseSetFunctionParams(noise, NOISE_FUNCTION_NAIVE, 0.0); noiseSetFunctionParams(noise, NOISE_FUNCTION_NAIVE, 0.0);
noiseAddLevelSimple(noise, 1.0, 1.0); noiseAddLevelSimple(noise, 1.0, 0.0, 1.0);
min = 100000.0; min = 100000.0;
max = -100000.0; max = -100000.0;
for (x = 0; x < 1000000; x++) for (x = 0; x < 1000000; x++)
@ -77,6 +76,7 @@ NoiseGenerator* noiseCreateGenerator()
result = malloc(sizeof(NoiseGenerator)); result = malloc(sizeof(NoiseGenerator));
result->function.algorithm = NOISE_FUNCTION_SIMPLEX; result->function.algorithm = NOISE_FUNCTION_SIMPLEX;
result->function.ridge_factor = 0.0; result->function.ridge_factor = 0.0;
result->function.curve_factor = 0.0;
result->level_count = 0; result->level_count = 0;
result->height_offset = 0.0; result->height_offset = 0.0;
@ -97,6 +97,7 @@ void noiseSaveGenerator(PackStream* stream, NoiseGenerator* generator)
x = (int)generator->function.algorithm; x = (int)generator->function.algorithm;
packWriteInt(stream, &x); packWriteInt(stream, &x);
packWriteDouble(stream, &generator->function.ridge_factor); packWriteDouble(stream, &generator->function.ridge_factor);
packWriteDouble(stream, &generator->function.curve_factor);
packWriteDouble(stream, &generator->height_offset); packWriteDouble(stream, &generator->height_offset);
packWriteInt(stream, &generator->level_count); packWriteInt(stream, &generator->level_count);
@ -105,8 +106,9 @@ void noiseSaveGenerator(PackStream* stream, NoiseGenerator* generator)
{ {
NoiseLevel* level = generator->levels + x; NoiseLevel* level = generator->levels + x;
packWriteDouble(stream, &level->scaling); packWriteDouble(stream, &level->wavelength);
packWriteDouble(stream, &level->height); packWriteDouble(stream, &level->amplitude);
packWriteDouble(stream, &level->minvalue);
packWriteDouble(stream, &level->xoffset); packWriteDouble(stream, &level->xoffset);
packWriteDouble(stream, &level->yoffset); packWriteDouble(stream, &level->yoffset);
packWriteDouble(stream, &level->zoffset); packWriteDouble(stream, &level->zoffset);
@ -120,6 +122,7 @@ void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator)
packReadInt(stream, &x); packReadInt(stream, &x);
generator->function.algorithm = (NoiseFunctionAlgorithm)x; generator->function.algorithm = (NoiseFunctionAlgorithm)x;
packReadDouble(stream, &generator->function.ridge_factor); packReadDouble(stream, &generator->function.ridge_factor);
packReadDouble(stream, &generator->function.curve_factor);
packReadDouble(stream, &generator->height_offset); packReadDouble(stream, &generator->height_offset);
packReadInt(stream, &generator->level_count); packReadInt(stream, &generator->level_count);
@ -128,8 +131,9 @@ void noiseLoadGenerator(PackStream* stream, NoiseGenerator* generator)
{ {
NoiseLevel* level = generator->levels + x; NoiseLevel* level = generator->levels + x;
packReadDouble(stream, &level->scaling); packReadDouble(stream, &level->wavelength);
packReadDouble(stream, &level->height); packReadDouble(stream, &level->amplitude);
packReadDouble(stream, &level->minvalue);
packReadDouble(stream, &level->xoffset); packReadDouble(stream, &level->xoffset);
packReadDouble(stream, &level->yoffset); packReadDouble(stream, &level->yoffset);
packReadDouble(stream, &level->zoffset); packReadDouble(stream, &level->zoffset);
@ -152,7 +156,6 @@ void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination)
void noiseValidate(NoiseGenerator* generator) void noiseValidate(NoiseGenerator* generator)
{ {
int x; int x;
double max_height = generator->height_offset;
if (generator->function.algorithm < 0 || generator->function.algorithm > NOISE_FUNCTION_NAIVE) 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; generator->function.ridge_factor = -0.5;
} }
if (generator->function.curve_factor > 1.0)
for (x = 0; x < generator->level_count; x++)
{ {
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) NoiseFunction noiseGetFunction(NoiseGenerator* generator)
@ -205,9 +226,9 @@ void noiseSetFunction(NoiseGenerator* generator, NoiseFunction* function)
noiseValidate(generator); 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); noiseSetFunction(generator, &function);
} }
@ -215,12 +236,13 @@ void noiseForceValue(NoiseGenerator* generator, double value)
{ {
noiseClearLevels(generator); noiseClearLevels(generator);
generator->height_offset = value; 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) 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; NoiseLevel level;
level.scaling = scaling; level.wavelength = scaling;
level.height = height; level.minvalue = minvalue;
level.amplitude = maxvalue - minvalue;
level.xoffset = toolsRandom(); level.xoffset = toolsRandom();
level.yoffset = toolsRandom(); level.yoffset = toolsRandom();
level.zoffset = toolsRandom(); level.zoffset = toolsRandom();
@ -257,7 +280,7 @@ void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double heigh
noiseAddLevel(generator, level); 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; int i;
@ -270,18 +293,20 @@ void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start
start_level.zoffset = toolsRandom(); start_level.zoffset = toolsRandom();
} }
noiseAddLevel(generator, start_level); noiseAddLevel(generator, start_level);
start_level.scaling *= scaling_factor; start_level.minvalue += start_level.amplitude * (1.0 - amplitude_factor) * center_factor;
start_level.height *= height_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; NoiseLevel level;
level.scaling = scaling; level.wavelength = scaling;
level.height = height; level.minvalue = minvalue;
noiseAddLevels(generator, level_count, level, 0.5, 0.5, 1); level.amplitude = maxvalue - minvalue;
noiseAddLevels(generator, level_count, level, 0.5, 0.5, 0.5, 1);
} }
void noiseRemoveLevel(NoiseGenerator* generator, int level) 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; NoiseLevel params;
params.scaling = scaling; params.wavelength = scaling;
params.height = height; params.minvalue = minvalue;
params.amplitude = maxvalue - minvalue;
params.xoffset = toolsRandom(); params.xoffset = toolsRandom();
params.yoffset = toolsRandom(); params.yoffset = toolsRandom();
params.zoffset = toolsRandom(); params.zoffset = toolsRandom();
@ -332,42 +358,62 @@ void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, d
noiseSetLevel(generator, level, params); 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; int level;
double height = 0.0; double current_minvalue, current_maxvalue, current_amplitude;
double target_height = max_height - min_height; double target_amplitude, factor;
if (generator->level_count == 0) if (generator->level_count == 0)
{ {
return; 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++) for (level = 0; level < generator->level_count; level++)
{ {
height += generator->levels[level].height; generator->levels[level].minvalue = minvalue + (generator->levels[level].minvalue - current_minvalue) * factor;
} generator->levels[level].amplitude *= factor;
for (level = 0; level < generator->level_count; level++)
{
generator->levels[level].height *= target_height / height;
if (adjust_scaling) 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); 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) 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) 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 else
{ {
@ -392,7 +438,7 @@ static inline double _applyRidge(double value, double ridge)
static inline double _get1DLevelValue(NoiseGenerator* generator, NoiseLevel* level, double x) 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) double noiseGet1DLevel(NoiseGenerator* generator, int level, double x)
@ -428,7 +474,7 @@ double noiseGet1DDetail(NoiseGenerator* generator, double x, double detail)
result = 0.0; result = 0.0;
for (level = 0; level < generator->level_count; level++) for (level = 0; level < generator->level_count; level++)
{ {
height = generator->levels[level].height; height = generator->levels[level].amplitude;
factor = 1.0; factor = 1.0;
if (height < detail * 0.25) 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) 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) 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; result = 0.0;
for (level = 0; level < generator->level_count; level++) for (level = 0; level < generator->level_count; level++)
{ {
height = generator->levels[level].height; height = generator->levels[level].amplitude;
factor = 1.0; factor = 1.0;
if (height < detail * 0.25) 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) 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) 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; result = 0.0;
for (level = 0; level < generator->level_count; level++) for (level = 0; level < generator->level_count; level++)
{ {
height = generator->levels[level].height; height = generator->levels[level].amplitude;
factor = 1.0; factor = 1.0;
if (height < detail * 0.25) if (height < detail * 0.25)
{ {

View file

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

View file

@ -15,7 +15,7 @@ static double* _noise_pool;
void noiseNaiveInit() void noiseNaiveInit()
{ {
int i; int i;
_noise_pool_size = 1048576; _noise_pool_size = 1048576;
_noise_pool = malloc(sizeof(double) * _noise_pool_size); _noise_pool = malloc(sizeof(double) * _noise_pool_size);
@ -33,7 +33,7 @@ void noiseNaiveQuit()
void noiseNaiveSave(PackStream* stream) void noiseNaiveSave(PackStream* stream)
{ {
int i; int i;
packWriteInt(stream, &_noise_pool_size); packWriteInt(stream, &_noise_pool_size);
for (i = 0; i < _noise_pool_size; i++) for (i = 0; i < _noise_pool_size; i++)
{ {
@ -44,7 +44,7 @@ void noiseNaiveSave(PackStream* stream)
void noiseNaiveLoad(PackStream* stream) void noiseNaiveLoad(PackStream* stream)
{ {
int i; int i;
packReadInt(stream, &_noise_pool_size); packReadInt(stream, &_noise_pool_size);
_noise_pool = realloc(_noise_pool, sizeof(double) * _noise_pool_size); _noise_pool = realloc(_noise_pool, sizeof(double) * _noise_pool_size);
for (i = 0; i < _noise_pool_size; i++) for (i = 0; i < _noise_pool_size; i++)
@ -56,7 +56,7 @@ void noiseNaiveLoad(PackStream* stream)
double noiseNaiveGet1DValue(double x) double noiseNaiveGet1DValue(double x)
{ {
x *= 3.0; x *= 3.0;
int size = _noise_pool_size; int size = _noise_pool_size;
int xbase = (int)floor(x); 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[1] = _noise_pool[x1 % _noise_pool_size];
buf_cubic_x[2] = _noise_pool[x2 % _noise_pool_size]; buf_cubic_x[2] = _noise_pool[x2 % _noise_pool_size];
buf_cubic_x[3] = _noise_pool[x3 % _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) double noiseNaiveGet2DValue(double x, double y)
{ {
x *= 3.0; x *= 3.0;
y *= 3.0; y *= 3.0;
int size = (int)pow(_noise_pool_size, 0.5); int size = (int)pow(_noise_pool_size, 0.5);
int xbase = (int)floor(x); 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_x[3] = _noise_pool[(y3 * size + x3) % _noise_pool_size];
buf_cubic_y[3] = toolsCubicInterpolate(buf_cubic_x, xinternal); 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) double noiseNaiveGet3DValue(double x, double y, double z)
@ -183,7 +183,7 @@ double noiseNaiveGet3DValue(double x, double y, double z)
x *= 3.0; x *= 3.0;
y *= 3.0; y *= 3.0;
z *= 3.0; z *= 3.0;
int size = (int)pow(_noise_pool_size, 0.33333333333333333); int size = (int)pow(_noise_pool_size, 0.33333333333333333);
int xbase = (int)floor(x); 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); 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) /*double noiseNaiveGet4DValue(double x, double y, double z, double w)
{ {
}*/ }*/

View file

@ -2,7 +2,7 @@
/* /*
* Perlin noise implementation. * Perlin noise implementation.
* *
* Based on Ken Perlin implementation. * Based on Ken Perlin implementation.
*/ */
@ -50,7 +50,7 @@ double noisePerlinGet1DValue(double x)
u = rx0 * g1[ p[ bx0 ] ]; u = rx0 * g1[ p[ bx0 ] ];
v = rx1 * g1[ p[ bx1 ] ]; 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) double noisePerlinGet2DValue(double x, double y)
@ -84,7 +84,7 @@ double noisePerlinGet2DValue(double x, double y)
q = g2[ b11 ] ; v = at2(rx1,ry1); q = g2[ b11 ] ; v = at2(rx1,ry1);
b = lerp(sx, u, v); 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) 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); 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]) static void _normalize2(double v[2])

View file

@ -2,7 +2,7 @@
/* /*
* Simplex noise implementation. * Simplex noise implementation.
* *
* Based on Stefan Gustavson 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. /* 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]. */ 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) 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. /* Add contributions from each corner to get the final noise value.
The result is scaled to stay just inside [-0.5,0.5] */ 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) 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); n4 = t4 * t4 * _dot4(_grad4[gi4], x4, y4, z4, w4);
} }
/* Sum up and scale the result to cover the range [-0.5,0.5] */ /* 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); noiseValidate(definition->_height_noise);
/* Get minimal and maximal height */ /* Get minimal and maximal height */
definition->_min_height = -noiseGetMaxValue(definition->_height_noise) * definition->height; noiseGetRange(definition->_height_noise, &definition->_min_height, &definition->_max_height);
definition->_max_height = noiseGetMaxValue(definition->_height_noise) * definition->height; definition->_min_height *= definition->height;
definition->_max_height *= definition->height;
} }
static TerrainDefinition* _createDefinition() static TerrainDefinition* _createDefinition()

View file

@ -13,8 +13,8 @@ void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset)
{ {
case TERRAIN_PRESET_STANDARD: case TERRAIN_PRESET_STANDARD:
noiseClearLevels(definition->_height_noise); noiseClearLevels(definition->_height_noise);
noiseAddLevelsSimple(definition->_height_noise, resolution, pow(2.0, resolution - 1), 25.0); noiseAddLevelsSimple(definition->_height_noise, resolution, pow(2.0, resolution - 1), -12.5, 12.5);
noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, 0.0); noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
definition->scaling = 1.0; definition->scaling = 1.0;
definition->height = 1.0; definition->height = 1.0;
definition->shadow_smoothing = 0.03; 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.color.b = 0.6;
light.direction.x = -1.0; light.direction.x = -1.0;
light.direction.y = -0.5; light.direction.y = -0.5;
light.direction.z = -1.0; light.direction.z = 1.0;
light.direction = v3Normalize(light.direction); light.direction = v3Normalize(light.direction);
light.altered = 1; light.altered = 1;
light.reflection = 1.0; light.reflection = 1.0;
@ -42,7 +42,7 @@ static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3
light.color.b = 0.2; light.color.b = 0.2;
light.direction.x = 1.0; light.direction.x = 1.0;
light.direction.y = -0.5; light.direction.y = -0.5;
light.direction.z = 1.0; light.direction.z = -1.0;
light.direction = v3Normalize(light.direction); light.direction = v3Normalize(light.direction);
light.altered = 0; light.altered = 0;
light.reflection = 0.0; light.reflection = 0.0;

View file

@ -62,7 +62,7 @@ TextureLayerDefinition* texturesLayerCreateDefinition()
result->zone = zoneCreate(); result->zone = zoneCreate();
result->bump_noise = noiseCreateGenerator(); 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_height = 0.1;
result->bump_scaling = 0.1; result->bump_scaling = 0.1;
result->material.base = COLOR_WHITE; result->material.base = COLOR_WHITE;

View file

@ -136,13 +136,13 @@ void waterValidateDefinition(WaterDefinition* definition)
noiseClearLevels(definition->_waves_noise); noiseClearLevels(definition->_waves_noise);
if (definition->waves_height > 0.0) 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) 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); noiseValidate(definition->_waves_noise);
} }
@ -200,10 +200,12 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal)
HeightInfo waterGetHeightInfo(WaterDefinition* definition) HeightInfo waterGetHeightInfo(WaterDefinition* definition)
{ {
HeightInfo info; HeightInfo info;
double noise_minvalue, noise_maxvalue;
info.base_height = definition->height; info.base_height = definition->height;
info.min_height = definition->height - noiseGetMaxValue(definition->_waves_noise); noiseGetRange(definition->_waves_noise, &noise_minvalue, &noise_maxvalue);
info.max_height = definition->height + noiseGetMaxValue(definition->_waves_noise); info.min_height = definition->height + noise_minvalue;
info.max_height = definition->height + noise_maxvalue;
return info; return info;
} }