258 lines
8.5 KiB
C++
258 lines
8.5 KiB
C++
|
#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();
|
||
|
}
|