paysages3d/src/definition/CloudLayerDefinition.cpp

258 lines
8.5 KiB
C++
Raw Normal View History

2013-11-15 22:26:44 +00:00
#include "CloudLayerDefinition.h"
#include "Curve.h"
#include "NoiseGenerator.h"
#include "SurfaceMaterial.h"
#include "PackStream.h"
CloudLayerDefinition::CloudLayerDefinition(BaseDefinition* parent):
BaseDefinition(parent)
{
_coverage_by_altitude = new Curve;
_coverage_noise = new NoiseGenerator();
_shape_noise = new NoiseGenerator();
_edge_noise = new NoiseGenerator();
material = new SurfaceMaterial;
}
CloudLayerDefinition::~CloudLayerDefinition()
{
delete _coverage_by_altitude;
delete _coverage_noise;
delete _shape_noise;
delete _edge_noise;
delete material;
}
CloudLayerDefinition* CloudLayerDefinition::newCopy(const CloudLayerDefinition& other, BaseDefinition* parent)
{
CloudLayerDefinition* layer = new CloudLayerDefinition(parent);
other.copy(layer);
return layer;
}
CloudLayerDefinition* CloudLayerDefinition::newCopy(BaseDefinition* parent) const
{
CloudLayerDefinition* layer = new CloudLayerDefinition(parent);
copy(layer);
return layer;
}
void CloudLayerDefinition::save(PackStream* stream) const
{
int clouds_type = (int)type;
stream->write(&clouds_type);
stream->write(&lower_altitude);
stream->write(&thickness);
_coverage_by_altitude->save(stream);
_coverage_noise->save(stream);
_shape_noise->save(stream);
_edge_noise->save(stream);
materialSave(stream, material);
stream->write(&hardness);
stream->write(&transparencydepth);
stream->write(&lighttraversal);
stream->write(&minimumlight);
stream->write(&shape_scaling);
stream->write(&edge_scaling);
stream->write(&edge_length);
stream->write(&base_coverage);
}
void CloudLayerDefinition::load(PackStream* stream)
{
int clouds_type;
stream->read(&clouds_type);
type = (CloudsType)clouds_type;
stream->read(&lower_altitude);
stream->read(&thickness);
_coverage_by_altitude->load(stream);
_coverage_noise->load(stream);
_shape_noise->load(stream);
_edge_noise->load(stream);
materialLoad(stream, material);
stream->read(&hardness);
stream->read(&transparencydepth);
stream->read(&lighttraversal);
stream->read(&minimumlight);
stream->read(&shape_scaling);
stream->read(&edge_scaling);
stream->read(&edge_length);
stream->read(&base_coverage);
validate();
}
void CloudLayerDefinition::copy(BaseDefinition* _destination) const
{
CloudLayerDefinition* destination = (CloudLayerDefinition*)_destination;
destination->type = type;
destination->lower_altitude = lower_altitude;
destination->thickness = thickness;
_coverage_by_altitude->copy(destination->_coverage_by_altitude);
_coverage_noise->copy(destination->_coverage_noise);
_shape_noise->copy(destination->_shape_noise);
_edge_noise->copy(destination->_edge_noise);
*destination->material = *material;
destination->hardness = hardness;
destination->transparencydepth = transparencydepth;
destination->lighttraversal = lighttraversal;
destination->minimumlight = minimumlight;
destination->shape_scaling = shape_scaling;
destination->edge_scaling = edge_scaling;
destination->edge_length = edge_length;
destination->base_coverage = base_coverage;
}
void CloudLayerDefinition::validate()
{
if (shape_scaling < 0.0001)
{
shape_scaling = 0.00001;
}
if (edge_scaling < 0.0001)
{
edge_scaling = 0.00001;
}
_coverage_by_altitude->clear();
_shape_noise->clearLevels();
_edge_noise->clearLevels();
_coverage_noise->clearLevels();
_coverage_noise->addLevelsSimple(2, 10.0, 0.0, 1.0, 0.0);
_coverage_noise->addLevelsSimple(2, 1.0, 0.0, 1.0, 0.0);
_coverage_noise->setFunctionParams(NOISE_FUNCTION_NAIVE, 0.0, 0.0);
switch (type)
{
case CLOUDS_TYPE_CIRRUS:
_coverage_by_altitude->addPoint(0.0, 0.0);
_coverage_by_altitude->addPoint(0.5, 1.0);
_coverage_by_altitude->addPoint(1.0, 0.0);
_shape_noise->addLevelsSimple(3, 1.0, 0.0, 1.0, 0.5);
_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
_edge_noise->addLevelsSimple(4, 1.0, -0.5, 0.5, 0.5);
_edge_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, -0.2, 0.0);
break;
case CLOUDS_TYPE_CUMULUS:
_coverage_by_altitude->addPoint(0.0, 0.0);
_coverage_by_altitude->addPoint(0.1, 1.0);
_coverage_by_altitude->addPoint(0.4, 0.8);
_coverage_by_altitude->addPoint(0.7, 1.0);
_coverage_by_altitude->addPoint(1.0, 0.0);
_shape_noise->addLevelsSimple(7, 1.0, 0.0, 1.0, 0.5);
_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.4, 0.0);
_edge_noise->addLevelsSimple(4, 1.0, -0.5, 0.5, 0.5);
_edge_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.8, 0.0);
break;
case CLOUDS_TYPE_STRATOCUMULUS:
_coverage_by_altitude->addPoint(0.0, 0.0);
_coverage_by_altitude->addPoint(0.2, 1.0);
_coverage_by_altitude->addPoint(0.5, 1.0);
_coverage_by_altitude->addPoint(1.0, 0.0);
_shape_noise->addLevelsSimple(4, 1.0, 0.0, 1.0, 0.5);
_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.3, 0.0);
_edge_noise->addLevelsSimple(6, 1.0, -0.5, 0.5, 0.5);
_edge_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.5, 0.0);
break;
case CLOUDS_TYPE_STRATUS:
_coverage_by_altitude->addPoint(0.0, 0.0);
_coverage_by_altitude->addPoint(0.2, 1.0);
_coverage_by_altitude->addPoint(0.8, 1.0);
_coverage_by_altitude->addPoint(1.0, 0.0);
_shape_noise->addLevelsSimple(3, 1.0, 0.0, 1.0, 0.5);
_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, -0.3, 0.0);
_edge_noise->addLevelsSimple(4, 1.0, -0.5, 0.5, 0.5);
_edge_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, -0.5, 0.0);
break;
default:
break;
}
_coverage_noise->normalizeAmplitude(-1.0, 3.0, 0);
_shape_noise->normalizeAmplitude(-0.5, 0.5, 0);
_edge_noise->normalizeAmplitude(-0.5, 0.5, 0);
materialValidate(material);
}
void CloudLayerDefinition::applyPreset(CloudsLayerPreset preset)
{
_coverage_noise->randomizeOffsets();
_edge_noise->randomizeOffsets();
_shape_noise->randomizeOffsets();
material->base = colorToHSL(colorFromValues(0.7, 0.7, 0.7, 1.0));
switch (preset)
{
case CLOUDS_LAYER_PRESET_CIRRUS:
type = CLOUDS_TYPE_CIRRUS;
lower_altitude = 25.0;
thickness = 2.0;
material->reflection = 0.4;
material->shininess = 0.5;
hardness = 0.0;
transparencydepth = 3.0;
lighttraversal = 10.0;
minimumlight = 0.6;
shape_scaling = 8.0;
edge_scaling = 2.0;
edge_length = 0.8;
base_coverage = 0.6;
break;
case CLOUDS_LAYER_PRESET_CUMULUS:
type = CLOUDS_TYPE_CUMULUS;
lower_altitude = 15.0;
thickness = 15.0;
material->reflection = 0.5;
material->shininess = 1.2;
hardness = 0.25;
transparencydepth = 1.5;
lighttraversal = 8.0;
minimumlight = 0.4;
shape_scaling = 20.0;
edge_scaling = 2.0;
edge_length = 0.0;
base_coverage = 0.7;
break;
case CLOUDS_LAYER_PRESET_STRATOCUMULUS:
type = CLOUDS_TYPE_STRATOCUMULUS;
lower_altitude = 5.0;
thickness = 6.0;
material->reflection = 0.3;
material->shininess = 0.8;
hardness = 0.25;
transparencydepth = 1.5;
lighttraversal = 7.0;
minimumlight = 0.4;
shape_scaling = 10.0;
edge_scaling = 0.8;
edge_length = 0.3;
base_coverage = 0.4;
break;
case CLOUDS_LAYER_PRESET_STRATUS:
type = CLOUDS_TYPE_STRATUS;
lower_altitude = 3.0;
thickness = 4.0;
material->reflection = 0.1;
material->shininess = 0.8;
hardness = 0.1;
transparencydepth = 3.0;
lighttraversal = 10.0;
minimumlight = 0.6;
shape_scaling = 8.0;
edge_scaling = 2.0;
edge_length = 1.0;
base_coverage = 0.4;
break;
default:
break;
}
validate();
}