paysages : Clouds refactoring (WIP) + explorer improvements.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@511 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
620877bf64
commit
c0f945fb27
13 changed files with 111 additions and 122 deletions
3
TODO
3
TODO
|
@ -23,6 +23,9 @@ Technology Preview 2 :
|
||||||
- Clouds should keep distance to ground.
|
- Clouds should keep distance to ground.
|
||||||
- Fix rendering when inside a cloud layer, with other upper or lower layers.
|
- Fix rendering when inside a cloud layer, with other upper or lower layers.
|
||||||
- Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)).
|
- Improve cloud rendering precision (and beware of precision discontinuity when rendering clouds in front of ground (shorter distance)).
|
||||||
|
- Top-down previews and explorer renderings should be camera independant.
|
||||||
|
- Explorer should have a waiting message while init.
|
||||||
|
- Sun radius is too small.
|
||||||
|
|
||||||
Technlogy Preview 3 :
|
Technlogy Preview 3 :
|
||||||
- Fully move layer management from BaseForm to BaseFormLayer.
|
- Fully move layer management from BaseForm to BaseFormLayer.
|
||||||
|
|
|
@ -64,6 +64,11 @@ bool BaseExplorerChunk::maintain()
|
||||||
_texture_changed = true;
|
_texture_changed = true;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
|
if (_texture_current_size < 8 && _texture_current_size < _texture_max_size)
|
||||||
|
{
|
||||||
|
maintain();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -113,7 +118,10 @@ void BaseExplorerChunk::render(QGLWidget* widget)
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
// Delegate poly rendering to subclass
|
// Delegate poly rendering to subclass
|
||||||
onRenderEvent(widget);
|
if (!_reset_needed)
|
||||||
|
{
|
||||||
|
onRenderEvent(widget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseExplorerChunk::askReset()
|
void BaseExplorerChunk::askReset()
|
||||||
|
|
|
@ -59,6 +59,11 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
_tessellation_current_size = new_tessellation_size;
|
_tessellation_current_size = new_tessellation_size;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
|
if (_tessellation_current_size < 8 && _tessellation_current_size < _tessellation_max_size)
|
||||||
|
{
|
||||||
|
onMaintainEvent();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -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, -0.5, 0.5);
|
noiseAddLevelsSimple(_brush_noise, 10, 1.0, -0.5, 0.5, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetHeightMap::~WidgetHeightMap()
|
WidgetHeightMap::~WidgetHeightMap()
|
||||||
|
|
|
@ -39,7 +39,7 @@ void autoGenRealisticLandscape(int seed)
|
||||||
texture = layersGetLayer(textures.layers, layer);
|
texture = layersGetLayer(textures.layers, layer);
|
||||||
noiseClearLevels(texture->bump_noise);
|
noiseClearLevels(texture->bump_noise);
|
||||||
noiseRandomizeOffsets(texture->bump_noise);
|
noiseRandomizeOffsets(texture->bump_noise);
|
||||||
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(texture->bump_noise, 8, 1.0, -0.5, 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;
|
||||||
|
@ -57,8 +57,8 @@ void autoGenRealisticLandscape(int seed)
|
||||||
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);
|
||||||
noiseRandomizeOffsets(texture->bump_noise);
|
noiseRandomizeOffsets(texture->bump_noise);
|
||||||
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2);
|
noiseAddLevelsSimple(texture->bump_noise, 5, 1.0, -0.2, 0.2, 0.5);
|
||||||
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04);
|
noiseAddLevelsSimple(texture->bump_noise, 2, 0.03, -0.04, 0.04, 0.5);
|
||||||
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;
|
||||||
|
|
|
@ -65,17 +65,17 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
|
||||||
noiseClearLevels(definition->_edge_noise);
|
noiseClearLevels(definition->_edge_noise);
|
||||||
noiseClearLevels(definition->_coverage_noise);
|
noiseClearLevels(definition->_coverage_noise);
|
||||||
|
|
||||||
|
noiseAddLevelsSimple(definition->_coverage_noise, 3, 1.0, 0.0, 1.0, 0.0);
|
||||||
|
noiseSetFunctionParams(definition->_coverage_noise, NOISE_FUNCTION_NAIVE, 0.0, 0.0);
|
||||||
switch (definition->type)
|
switch (definition->type)
|
||||||
{
|
{
|
||||||
case CLOUDS_TYPE_CIRRUS:
|
case CLOUDS_TYPE_CIRRUS:
|
||||||
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->_coverage_noise, 3, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 0.0, 1.0, 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);
|
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
|
||||||
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 0.5, 0.5);
|
||||||
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.2, 0.0);
|
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.2, 0.0);
|
||||||
break;
|
break;
|
||||||
case CLOUDS_TYPE_CUMULUS:
|
case CLOUDS_TYPE_CUMULUS:
|
||||||
|
@ -84,9 +84,7 @@ 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->_coverage_noise, 3, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(definition->_shape_noise, 7, 1.0, 0.0, 1.0, 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);
|
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.4, 0.0);
|
||||||
break;
|
break;
|
||||||
case CLOUDS_TYPE_STRATOCUMULUS:
|
case CLOUDS_TYPE_STRATOCUMULUS:
|
||||||
|
@ -94,11 +92,9 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
|
||||||
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->_coverage_noise, 2, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(definition->_shape_noise, 2, 1.0, 0.0, 1.0, 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);
|
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3, 0.0);
|
||||||
noiseAddLevelsSimple(definition->_edge_noise, 8, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(definition->_edge_noise, 8, 1.0, -0.5, 0.5, 0.5);
|
||||||
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, 0.5, 0.0);
|
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, 0.5, 0.0);
|
||||||
break;
|
break;
|
||||||
case CLOUDS_TYPE_STRATUS:
|
case CLOUDS_TYPE_STRATUS:
|
||||||
|
@ -106,16 +102,17 @@ void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
|
||||||
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->_coverage_noise, 3, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(definition->_shape_noise, 3, 1.0, 0.0, 1.0, 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);
|
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, -0.3, 0.0);
|
||||||
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 0.5);
|
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 0.5, 0.5);
|
||||||
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.5, 0.0);
|
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.5, 0.0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noiseNormalizeAmplitude(definition->_coverage_noise, 0.0, 1.0, 0);
|
||||||
|
noiseNormalizeAmplitude(definition->_shape_noise, -0.5, 0.5, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CloudsLayerDefinition* cloudsLayerCreateDefinition()
|
CloudsLayerDefinition* cloudsLayerCreateDefinition()
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "public.h"
|
#include "public.h"
|
||||||
|
|
||||||
#define CLOUDS_MAX_LAYERS 6
|
#define CLOUDS_MAX_LAYERS 6
|
||||||
#define MAX_SEGMENT_COUNT 30
|
#define MAX_SEGMENT_COUNT 100
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,55 +7,10 @@
|
||||||
#include "../renderer.h"
|
#include "../renderer.h"
|
||||||
#include "../tools.h"
|
#include "../tools.h"
|
||||||
|
|
||||||
static double _standardCoverageFunc(CloudsLayerDefinition* layer, Vector3 position)
|
|
||||||
{
|
|
||||||
if (position.y < layer->lower_altitude || position.y >= layer->lower_altitude + layer->thickness)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return layer->base_coverage * curveGetValue(layer->_coverage_by_altitude, (position.y - layer->lower_altitude) / layer->thickness);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3 position)
|
|
||||||
{
|
|
||||||
double density, coverage, val;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (density <= 0.0)
|
|
||||||
{
|
|
||||||
/* outside the main shape */
|
|
||||||
return density * layer->shape_scaling;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* inside the main shape, using edge noise */
|
|
||||||
density /= coverage;
|
|
||||||
if (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) / 0.5;
|
|
||||||
val = val - 0.5 + density;
|
|
||||||
|
|
||||||
return val * (density * coverage * layer->shape_scaling + (1.0 - density) * layer->edge_scaling);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return density * coverage * layer->shape_scaling;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Vector3 _getNormal(CloudsLayerDefinition* layer, Vector3 position, double detail)
|
static inline Vector3 _getNormal(CloudsLayerDefinition* layer, Vector3 position, double detail)
|
||||||
{
|
{
|
||||||
Vector3 result = {0.0, 0.0, 0.0};
|
Vector3 result = {0.0, 0.0, 0.0};
|
||||||
Vector3 dposition;
|
/*Vector3 dposition;
|
||||||
double val, dval;
|
double val, dval;
|
||||||
|
|
||||||
val = _getDistanceToBorder(layer, position);
|
val = _getDistanceToBorder(layer, position);
|
||||||
|
@ -86,7 +41,7 @@ static inline Vector3 _getNormal(CloudsLayerDefinition* layer, Vector3 position,
|
||||||
|
|
||||||
dposition.z = position.z - detail;
|
dposition.z = position.z - detail;
|
||||||
dval = val - _getDistanceToBorder(layer, dposition);
|
dval = val - _getDistanceToBorder(layer, dposition);
|
||||||
result.z -= dval;
|
result.z -= dval;*/
|
||||||
|
|
||||||
return v3Normalize(result);
|
return v3Normalize(result);
|
||||||
}
|
}
|
||||||
|
@ -153,13 +108,12 @@ static int _optimizeSearchLimits(CloudsLayerDefinition* layer, Vector3* start, V
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Go through the cloud layer to find segments (parts of the lookup that are inside the cloud).
|
* Go through the cloud layer to find segments (parts of the lookup that are likely to contain cloud).
|
||||||
*
|
*
|
||||||
* @param definition The cloud layer
|
* @param definition The cloud layer
|
||||||
* @param renderer The renderer environment
|
* @param renderer The renderer environment
|
||||||
* @param start Start position of the lookup (already optimized)
|
* @param start Start position of the lookup (already optimized)
|
||||||
* @param direction Normalized direction of the lookup
|
* @param direction Normalized direction of the lookup
|
||||||
* @param detail Level of noise detail required
|
|
||||||
* @param max_segments Maximum number of segments to collect
|
* @param max_segments Maximum number of segments to collect
|
||||||
* @param max_inside_length Maximum length to spend inside the cloud
|
* @param max_inside_length Maximum length to spend inside the cloud
|
||||||
* @param max_total_length Maximum lookup length
|
* @param max_total_length Maximum lookup length
|
||||||
|
@ -168,13 +122,13 @@ static int _optimizeSearchLimits(CloudsLayerDefinition* layer, Vector3* start, V
|
||||||
* @param out_segments Allocated space to fill found segments
|
* @param out_segments Allocated space to fill found segments
|
||||||
* @return Number of segments found
|
* @return Number of segments found
|
||||||
*/
|
*/
|
||||||
static int _findSegments(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, double detail, int max_segments, double max_inside_length, double max_total_length, double* inside_length, double* total_length, CloudSegment* out_segments)
|
static int _getPrimarySegments(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, int max_segments, double max_inside_length, double max_total_length, double* inside_length, double* total_length, CloudSegment* out_segments)
|
||||||
{
|
{
|
||||||
int inside, segment_count;
|
int inside, segment_count;
|
||||||
double current_total_length, current_inside_length;
|
double current_total_length, current_inside_length;
|
||||||
double step_length, segment_length, remaining_length;
|
double step_length, segment_length;
|
||||||
double noise_distance, last_noise_distance;
|
|
||||||
Vector3 walker, step, segment_start;
|
Vector3 walker, step, segment_start;
|
||||||
|
CloudsInfo info;
|
||||||
double render_precision;
|
double render_precision;
|
||||||
|
|
||||||
if (max_segments <= 0)
|
if (max_segments <= 0)
|
||||||
|
@ -197,69 +151,67 @@ static int _findSegments(CloudsLayerDefinition* definition, Renderer* renderer,
|
||||||
current_inside_length = 0.0;
|
current_inside_length = 0.0;
|
||||||
segment_length = 0.0;
|
segment_length = 0.0;
|
||||||
walker = start;
|
walker = start;
|
||||||
noise_distance = _getDistanceToBorder(definition, start) * render_precision;
|
info = renderer->clouds->getLayerInfo(renderer, definition, start);
|
||||||
inside = (noise_distance > 0.0) ? 1 : 0;
|
inside = info.inside;
|
||||||
step = v3Scale(direction, render_precision);
|
step = v3Scale(direction, render_precision);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
walker = v3Add(walker, step);
|
walker = v3Add(walker, step);
|
||||||
step_length = v3Norm(step);
|
step_length = v3Norm(step);
|
||||||
last_noise_distance = noise_distance;
|
|
||||||
noise_distance = _getDistanceToBorder(definition, walker) * render_precision;
|
|
||||||
current_total_length += step_length;
|
current_total_length += step_length;
|
||||||
|
|
||||||
if (current_total_length >= max_total_length || current_inside_length > max_inside_length)
|
if (current_total_length >= max_total_length || current_inside_length > max_inside_length)
|
||||||
{
|
{
|
||||||
noise_distance = 0.0;
|
info.distance_to_edge = 0.0;
|
||||||
|
info.inside = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info = renderer->clouds->getLayerInfo(renderer, definition, walker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noise_distance > 0.0)
|
if (info.inside)
|
||||||
{
|
{
|
||||||
if (inside)
|
if (inside)
|
||||||
{
|
{
|
||||||
// inside the cloud
|
/* inside the cloud */
|
||||||
segment_length += step_length;
|
segment_length += step_length;
|
||||||
current_inside_length += step_length;
|
current_inside_length += step_length;
|
||||||
step = v3Scale(direction, (noise_distance < render_precision) ? render_precision : noise_distance);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// entering the cloud
|
/* entering the cloud */
|
||||||
inside = 1;
|
segment_length = step_length;
|
||||||
segment_length = step_length * noise_distance / (noise_distance - last_noise_distance);
|
segment_start = walker;
|
||||||
segment_start = v3Add(walker, v3Scale(direction, -segment_length));
|
|
||||||
current_inside_length += segment_length;
|
current_inside_length += segment_length;
|
||||||
step = v3Scale(direction, render_precision);
|
/* TODO Refine entry position */
|
||||||
|
|
||||||
|
inside = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (inside)
|
if (inside)
|
||||||
{
|
{
|
||||||
// exiting the cloud
|
/* exiting the cloud */
|
||||||
remaining_length = step_length * last_noise_distance / (last_noise_distance - noise_distance);
|
segment_length += step_length;
|
||||||
segment_length += remaining_length;
|
current_inside_length += step_length;
|
||||||
current_inside_length += remaining_length;
|
|
||||||
|
|
||||||
out_segments->start = segment_start;
|
out_segments->start = segment_start;
|
||||||
out_segments->end = v3Add(walker, v3Scale(direction, remaining_length - step_length));
|
out_segments->end = walker;
|
||||||
out_segments->length = segment_length;
|
out_segments->length = segment_length;
|
||||||
out_segments++;
|
out_segments++;
|
||||||
if (++segment_count >= max_segments)
|
if (++segment_count >= max_segments)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* TODO Refine exit position */
|
||||||
|
|
||||||
inside = 0;
|
inside = 0;
|
||||||
step = v3Scale(direction, render_precision);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// searching for a cloud
|
|
||||||
step = v3Scale(direction, (noise_distance > -render_precision) ? render_precision : -noise_distance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
step = v3Scale(direction, (info.distance_to_edge < render_precision) ? render_precision : info.distance_to_edge);
|
||||||
} while (inside || (walker.y <= definition->lower_altitude + definition->thickness + 0.001 && walker.y >= definition->lower_altitude - 0.001 && current_total_length < max_total_length && current_inside_length < max_inside_length));
|
} while (inside || (walker.y <= definition->lower_altitude + definition->thickness + 0.001 && walker.y >= definition->lower_altitude - 0.001 && current_total_length < max_total_length && current_inside_length < max_inside_length));
|
||||||
|
|
||||||
*total_length = current_total_length;
|
*total_length = current_total_length;
|
||||||
|
@ -309,8 +261,8 @@ static Color _applyLayerLighting(CloudsLayerDefinition* definition, Renderer* re
|
||||||
|
|
||||||
Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer* renderer, Vector3 start, Vector3 end)
|
Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer* renderer, Vector3 start, Vector3 end)
|
||||||
{
|
{
|
||||||
int i, segment_count;
|
int segment_count;
|
||||||
double max_length, detail, total_length, inside_length;
|
double max_length, total_length, inside_length;
|
||||||
Vector3 direction;
|
Vector3 direction;
|
||||||
Color col;
|
Color col;
|
||||||
CloudSegment segments[MAX_SEGMENT_COUNT];
|
CloudSegment segments[MAX_SEGMENT_COUNT];
|
||||||
|
@ -324,21 +276,20 @@ Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer*
|
||||||
max_length = v3Norm(direction);
|
max_length = v3Norm(direction);
|
||||||
direction = v3Normalize(direction);
|
direction = v3Normalize(direction);
|
||||||
|
|
||||||
detail = renderer->getPrecision(renderer, start) / definition->shape_scaling;
|
segment_count = _getPrimarySegments(definition, renderer, start, direction, MAX_SEGMENT_COUNT, definition->transparencydepth * (double)renderer->render_quality, max_length, &inside_length, &total_length, segments);
|
||||||
|
/* TODO Crawl in segments for render */
|
||||||
|
|
||||||
segment_count = _findSegments(definition, renderer, start, direction, detail, MAX_SEGMENT_COUNT, definition->transparencydepth * (double)renderer->render_quality, max_length, &inside_length, &total_length, segments);
|
col = definition->material.base;
|
||||||
for (i = segment_count - 1; i >= 0; i--)
|
if (definition->transparencydepth == 0 || inside_length >= definition->transparencydepth)
|
||||||
{
|
|
||||||
col = _applyLayerLighting(definition, renderer, segments[i].start, detail);
|
|
||||||
col.a = 1.0;
|
|
||||||
col = renderer->atmosphere->applyAerialPerspective(renderer, start, col);
|
|
||||||
col.a = (segments[i].length >= definition->transparencydepth) ? 1.0 : (segments[i].length / definition->transparencydepth);
|
|
||||||
colorMask(&base, &col);
|
|
||||||
}
|
|
||||||
if (inside_length >= definition->transparencydepth)
|
|
||||||
{
|
{
|
||||||
col.a = 1.0;
|
col.a = 1.0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
col.a = inside_length / definition->transparencydepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
colorMask(&base, &col);
|
||||||
|
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
@ -348,9 +299,12 @@ Color cloudsLayerFilterLight(CloudsLayerDefinition* definition, Renderer* render
|
||||||
double inside_depth, total_depth, factor;
|
double inside_depth, total_depth, factor;
|
||||||
CloudSegment segments[MAX_SEGMENT_COUNT];
|
CloudSegment segments[MAX_SEGMENT_COUNT];
|
||||||
|
|
||||||
_optimizeSearchLimits(definition, &location, &light_location);
|
if (!_optimizeSearchLimits(definition, &location, &light_location))
|
||||||
|
{
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
|
||||||
_findSegments(definition, renderer, location, direction_to_light, 0.1, MAX_SEGMENT_COUNT, definition->lighttraversal, v3Norm(v3Sub(light_location, location)), &inside_depth, &total_depth, segments);
|
_getPrimarySegments(definition, renderer, location, direction_to_light, MAX_SEGMENT_COUNT, definition->lighttraversal, v3Norm(v3Sub(light_location, location)), &inside_depth, &total_depth, segments);
|
||||||
|
|
||||||
if (definition->lighttraversal < 0.0001)
|
if (definition->lighttraversal < 0.0001)
|
||||||
{
|
{
|
||||||
|
@ -381,7 +335,16 @@ Color cloudsLayerFilterLight(CloudsLayerDefinition* definition, Renderer* render
|
||||||
*/
|
*/
|
||||||
static inline double _getLayerCoverage(CloudsLayerDefinition* layer, double x, double z)
|
static inline double _getLayerCoverage(CloudsLayerDefinition* layer, double x, double z)
|
||||||
{
|
{
|
||||||
return sin(x) * cos(z);
|
if (layer->base_coverage == 0.0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double coverage = noiseGet2DTotal(layer->_coverage_noise, x / layer->shape_scaling, z / layer->shape_scaling);
|
||||||
|
coverage -= (1.0 - layer->base_coverage);
|
||||||
|
return (coverage <= 0.0) ? 0.0 : coverage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -391,7 +354,20 @@ static inline double _getLayerCoverage(CloudsLayerDefinition* layer, double x, d
|
||||||
*/
|
*/
|
||||||
static inline double _getLayerDensity(CloudsLayerDefinition* layer, Vector3 location, double coverage)
|
static inline double _getLayerDensity(CloudsLayerDefinition* layer, Vector3 location, double coverage)
|
||||||
{
|
{
|
||||||
return 1.0;
|
if (coverage == 0.0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else if (coverage == 1.0)
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double density = noiseGet3DTotal(layer->_shape_noise, location.x / layer->shape_scaling, location.y / layer->shape_scaling, location.z / layer->shape_scaling);
|
||||||
|
density -= (0.5 - coverage);
|
||||||
|
return (density <= 0.0) ? 0.0 : density;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CloudsInfo cloudsGetLayerInfo(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
|
CloudsInfo cloudsGetLayerInfo(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
|
||||||
|
@ -401,7 +377,7 @@ CloudsInfo cloudsGetLayerInfo(Renderer* renderer, CloudsLayerDefinition* layer,
|
||||||
UNUSED(renderer);
|
UNUSED(renderer);
|
||||||
|
|
||||||
result.density = 0.0;
|
result.density = 0.0;
|
||||||
result.distance_to_edge = 1.0;
|
result.distance_to_edge = 0.1;
|
||||||
|
|
||||||
/* Get coverage info */
|
/* Get coverage info */
|
||||||
double coverage = _getLayerCoverage(layer, location.x, location.z);
|
double coverage = _getLayerCoverage(layer, location.x, location.z);
|
||||||
|
|
|
@ -311,14 +311,14 @@ void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double minvalue, double maxvalue)
|
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double minvalue, double maxvalue, double center_factor)
|
||||||
{
|
{
|
||||||
NoiseLevel level;
|
NoiseLevel level;
|
||||||
|
|
||||||
level.wavelength = scaling;
|
level.wavelength = scaling;
|
||||||
level.minvalue = minvalue;
|
level.minvalue = minvalue;
|
||||||
level.amplitude = maxvalue - minvalue;
|
level.amplitude = maxvalue - minvalue;
|
||||||
noiseAddLevels(generator, level_count, level, 0.5, 0.5, 0.5);
|
noiseAddLevels(generator, level_count, level, 0.5, 0.5, center_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void noiseRemoveLevel(NoiseGenerator* generator, int level)
|
void noiseRemoveLevel(NoiseGenerator* generator, int level)
|
||||||
|
|
|
@ -55,7 +55,7 @@ void noiseClearLevels(NoiseGenerator* generator);
|
||||||
void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level, int protect_offsets);
|
void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level, int protect_offsets);
|
||||||
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double minvalue, double maxvalue);
|
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);
|
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor, double center_factor);
|
||||||
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double minvalue, double maxvalue);
|
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double minvalue, double maxvalue, double center_factor);
|
||||||
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 index, NoiseLevel level, int protect_offsets);
|
void noiseSetLevel(NoiseGenerator* generator, int index, NoiseLevel level, int protect_offsets);
|
||||||
|
|
|
@ -14,7 +14,7 @@ void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset)
|
||||||
case TERRAIN_PRESET_STANDARD:
|
case TERRAIN_PRESET_STANDARD:
|
||||||
noiseRandomizeOffsets(definition->_height_noise);
|
noiseRandomizeOffsets(definition->_height_noise);
|
||||||
noiseClearLevels(definition->_height_noise);
|
noiseClearLevels(definition->_height_noise);
|
||||||
noiseAddLevelsSimple(definition->_height_noise, resolution, pow(2.0, resolution - 1), -12.5, 12.5);
|
noiseAddLevelsSimple(definition->_height_noise, resolution, pow(2.0, resolution - 1), -12.5, 12.5, 0.5);
|
||||||
noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 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;
|
||||||
|
|
|
@ -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, -0.5, 0.5);
|
noiseAddLevelsSimple(result->bump_noise, 8, 1.0, -0.5, 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;
|
||||||
|
|
|
@ -138,11 +138,11 @@ 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.015, definition->waves_height * scaling * 0.015);
|
noiseAddLevelsSimple(definition->_waves_noise, 2, scaling, -definition->waves_height * scaling * 0.015, definition->waves_height * scaling * 0.015, 0.5);
|
||||||
}
|
}
|
||||||
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.015, definition->detail_height * scaling * 0.015);
|
noiseAddLevelsSimple(definition->_waves_noise, 3, scaling * 0.1, -definition->detail_height * scaling * 0.015, definition->detail_height * scaling * 0.015, 0.5);
|
||||||
}
|
}
|
||||||
noiseSetFunctionParams(definition->_waves_noise, NOISE_FUNCTION_SIMPLEX, -definition->turbulence, 0.0);
|
noiseSetFunctionParams(definition->_waves_noise, NOISE_FUNCTION_SIMPLEX, -definition->turbulence, 0.0);
|
||||||
noiseValidate(definition->_waves_noise);
|
noiseValidate(definition->_waves_noise);
|
||||||
|
|
Loading…
Reference in a new issue