paysages3d/lib_paysages/clouds/definition.c

222 lines
8.5 KiB
C

#include "private.h"
#include <stdlib.h>
/******************** Global definition ********************/
static void _validateDefinition(CloudsDefinition* definition)
{
layersValidate(definition->layers);
}
static CloudsDefinition* _createDefinition()
{
CloudsDefinition* definition = malloc(sizeof(CloudsDefinition));
definition->layers = layersCreate(cloudsGetLayerType(), CLOUDS_MAX_LAYERS);
return definition;
}
static void _deleteDefinition(CloudsDefinition* definition)
{
layersDelete(definition->layers);
free(definition);
}
static void _copyDefinition(CloudsDefinition* source, CloudsDefinition* destination)
{
layersCopy(source->layers, destination->layers);
}
static void _saveDefinition(PackStream* stream, CloudsDefinition* definition)
{
layersSave(stream, definition->layers);
}
static void _loadDefinition(PackStream* stream, CloudsDefinition* definition)
{
layersLoad(stream, definition->layers);
}
StandardDefinition CloudsDefinitionClass = {
(FuncObjectCreate)_createDefinition,
(FuncObjectDelete)_deleteDefinition,
(FuncObjectCopy)_copyDefinition,
(FuncObjectValidate)_validateDefinition,
(FuncObjectSave)_saveDefinition,
(FuncObjectLoad)_loadDefinition
};
/*** Layer definition ***/
void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
{
if (definition->shape_scaling < 0.0001)
{
definition->shape_scaling = 0.00001;
}
if (definition->edge_scaling < 0.0001)
{
definition->edge_scaling = 0.00001;
}
curveClear(definition->_coverage_by_altitude);
noiseClearLevels(definition->_shape_noise);
noiseClearLevels(definition->_edge_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)
{
case CLOUDS_TYPE_CIRRUS:
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, 0.0, 1.0, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 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);
curveQuickAddPoint(definition->_coverage_by_altitude, 0.1, 1.0);
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, 0.0, 1.0, 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, 0.0, 1.0, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, 0.3, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 8, 1.0, -0.5, 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, 0.0, 1.0, 0.5);
noiseSetFunctionParams(definition->_shape_noise, NOISE_FUNCTION_SIMPLEX, -0.3, 0.0);
noiseAddLevelsSimple(definition->_edge_noise, 4, 1.0, -0.5, 0.5, 0.5);
noiseSetFunctionParams(definition->_edge_noise, NOISE_FUNCTION_SIMPLEX, -0.5, 0.0);
break;
default:
break;
}
noiseNormalizeAmplitude(definition->_coverage_noise, 0.0, 1.0, 0);
noiseNormalizeAmplitude(definition->_shape_noise, -0.5, 0.5, 0);
}
CloudsLayerDefinition* cloudsLayerCreateDefinition()
{
CloudsLayerDefinition* result;
result = malloc(sizeof(CloudsLayerDefinition));
result->_coverage_by_altitude = curveCreate();
result->_coverage_noise = noiseCreateGenerator();
result->_shape_noise = noiseCreateGenerator();
result->_edge_noise = noiseCreateGenerator();
cloudsLayerAutoPreset(result, CLOUDS_LAYER_PRESET_CIRRUS);
return result;
}
void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition)
{
curveDelete(definition->_coverage_by_altitude);
noiseDeleteGenerator(definition->_coverage_noise);
noiseDeleteGenerator(definition->_shape_noise);
noiseDeleteGenerator(definition->_edge_noise);
free(definition);
}
void cloudsLayerCopyDefinition(CloudsLayerDefinition* source, CloudsLayerDefinition* destination)
{
CloudsLayerDefinition temp;
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);
}
void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
{
int clouds_type = (int)layer->type;
packWriteInt(stream, &clouds_type);
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);
packWriteDouble(stream, &layer->hardness);
packWriteDouble(stream, &layer->transparencydepth);
packWriteDouble(stream, &layer->lighttraversal);
packWriteDouble(stream, &layer->minimumlight);
packWriteDouble(stream, &layer->shape_scaling);
packWriteDouble(stream, &layer->edge_scaling);
packWriteDouble(stream, &layer->edge_length);
packWriteDouble(stream, &layer->base_coverage);
}
void _cloudsLayerLoad(PackStream* stream, CloudsLayerDefinition* layer)
{
int clouds_type;
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);
packReadDouble(stream, &layer->transparencydepth);
packReadDouble(stream, &layer->lighttraversal);
packReadDouble(stream, &layer->minimumlight);
packReadDouble(stream, &layer->shape_scaling);
packReadDouble(stream, &layer->edge_scaling);
packReadDouble(stream, &layer->edge_length);
packReadDouble(stream, &layer->base_coverage);
cloudsLayerValidateDefinition(layer);
}
LayerType cloudsGetLayerType()
{
LayerType result;
result.callback_create = (LayerCallbackCreate)cloudsLayerCreateDefinition;
result.callback_delete = (LayerCallbackDelete)cloudsLayerDeleteDefinition;
result.callback_copy = (LayerCallbackCopy)cloudsLayerCopyDefinition;
result.callback_validate = (LayerCallbackValidate)cloudsLayerValidateDefinition;
result.callback_save = (LayerCallbackSave)_cloudsLayerSave;
result.callback_load = (LayerCallbackLoad)_cloudsLayerLoad;
return result;
}