Refactored CloudsDefinition

This commit is contained in:
Michaël Lemaire 2013-11-15 23:26:44 +01:00
parent dc679500fa
commit 1cccae90be
47 changed files with 948 additions and 956 deletions

174
src/basics/Curve.cpp Normal file
View file

@ -0,0 +1,174 @@
#include "Curve.h"
const int MAX_NB_POINTS = 30;
#include "PackStream.h"
Curve::Curve()
{
nbpoints = 0;
default_value = 0.0;
points = new CurvePoint[MAX_NB_POINTS];
}
Curve::~Curve()
{
delete[] points;
}
void Curve::copy(Curve* destination) const
{
destination->nbpoints = nbpoints;
destination->default_value = default_value;
for (int i = 0; i < nbpoints; i++)
{
destination->points[i] = points[i];
}
}
void Curve::save(PackStream* stream) const
{
stream->write(&default_value);
stream->write(&nbpoints);
for (int i = 0; i < nbpoints; i++)
{
stream->write(&points[i].position);
stream->write(&points[i].value);
}
}
void Curve::load(PackStream* stream)
{
stream->read(&default_value);
stream->read(&nbpoints);
for (int i = 0; i < nbpoints; i++)
{
stream->read(&points[i].position);
stream->read(&points[i].value);
}
}
void Curve::clear()
{
nbpoints = 0;
}
void Curve::setDefault(double value)
{
default_value = value;
}
int Curve::addPoint(const CurvePoint &point)
{
if (nbpoints < MAX_NB_POINTS)
{
points[nbpoints] = point;
return nbpoints++;
}
else
{
return -1;
}
}
int Curve::addPoint(double position, double value)
{
CurvePoint point = {position, value};
return addPoint(point);
}
CurvePoint Curve::getPoint(int number) const
{
if (number >= 0 && number < nbpoints)
{
return points[number];
}
else
{
return {0.0, 0.0};
}
}
bool Curve::getPoint(int number, CurvePoint *point) const
{
if (number >= 0 && number < nbpoints)
{
*point = points[number];
return true;
}
else
{
return false;
}
}
void Curve::setPoint(int number, const CurvePoint &point)
{
if (number >= 0 && number < nbpoints)
{
points[number] = point;
}
}
void Curve::removePoint(int number)
{
if (number >= 0 && number < nbpoints)
{
if (nbpoints > 0 && number < nbpoints - 1)
{
memmove(points + number, points + number + 1, sizeof(CurvePoint) * (nbpoints - number - 1));
}
nbpoints--;
}
}
int _point_compare(const void* part1, const void* part2)
{
if (((CurvePoint*)part1)->position > ((CurvePoint*)part2)->position)
{
return 1;
}
else
{
return -1;
}
}
void Curve::validate()
{
if (nbpoints > 1)
{
qsort(points, nbpoints, sizeof(CurvePoint), _point_compare);
}
}
double Curve::getValue(double position) const
{
int i;
double fact;
if (nbpoints == 0)
{
return default_value;
}
else if (nbpoints == 1 || position <= points[0].position)
{
return points[0].value;
}
else if (position >= points[nbpoints - 1].position)
{
return points[nbpoints - 1].value;
}
else
{
for (i = 1; i < nbpoints; i++)
{
if (position < points[i].position)
{
fact = (position - points[i - 1].position) / (points[i].position - points[i - 1].position);
return points[i - 1].value + (points[i].value - points[i - 1].value) * fact;
}
}
return points[nbpoints - 1].value;
}
}

47
src/basics/Curve.h Normal file
View file

@ -0,0 +1,47 @@
#ifndef CURVE_H
#define CURVE_H
#include "basics_global.h"
namespace paysages {
namespace basics {
typedef struct {
double position;
double value;
} CurvePoint;
class BASICSSHARED_EXPORT Curve
{
public:
Curve();
~Curve();
void copy(Curve* destination) const;
void save(PackStream* stream) const;
void load(PackStream* stream);
void validate();
inline int getPointCount() const {return nbpoints;}
CurvePoint getPoint(int number) const;
bool getPoint(int number, CurvePoint *point) const;
double getValue(double position) const;
void clear();
void setDefault(double value);
int addPoint(const CurvePoint &point);
int addPoint(double position, double value);
void setPoint(int number, const CurvePoint &point);
void removePoint(int number);
private:
double default_value;
int nbpoints;
CurvePoint* points;
};
}
}
#endif // CURVE_H

View file

@ -26,7 +26,8 @@ SOURCES += \
Color.inline.cpp \
ColorHSL.cpp \
BoundingBox.cpp \
Matrix4.cpp
Matrix4.cpp \
Curve.cpp
HEADERS +=\
basics_global.h \
@ -40,7 +41,8 @@ HEADERS +=\
Color.h \
ColorHSL.h \
BoundingBox.h \
Matrix4.h
Matrix4.h \
Curve.h
unix:!symbian {
maemo5 {

View file

@ -18,6 +18,7 @@ namespace basics {
class SpaceSegment;
class Color;
class NoiseGenerator;
class Curve;
}
}
using namespace paysages::basics;

View file

@ -0,0 +1,257 @@
#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();
}

View file

@ -0,0 +1,67 @@
#ifndef CLOUDLAYERDEFINITION_H
#define CLOUDLAYERDEFINITION_H
#include "definition_global.h"
#include "BaseDefinition.h"
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public BaseDefinition
{
public:
CloudLayerDefinition(BaseDefinition* parent);
virtual ~CloudLayerDefinition();
static CloudLayerDefinition* newCopy(const CloudLayerDefinition& other, BaseDefinition* parent);
CloudLayerDefinition* newCopy(BaseDefinition* parent) const;
virtual void save(PackStream* pack) const override;
virtual void load(PackStream* pack) override;
virtual void copy(BaseDefinition* destination) const override;
virtual void validate() override;
public:
typedef enum
{
CLOUDS_TYPE_CIRRUS,
CLOUDS_TYPE_CUMULUS,
CLOUDS_TYPE_STRATOCUMULUS,
CLOUDS_TYPE_STRATUS
} CloudsType;
typedef enum
{
CLOUDS_LAYER_PRESET_CIRRUS,
CLOUDS_LAYER_PRESET_CUMULUS,
CLOUDS_LAYER_PRESET_STRATOCUMULUS,
CLOUDS_LAYER_PRESET_STRATUS
} CloudsLayerPreset;
void applyPreset(CloudsLayerPreset preset);
public:
CloudsType type;
double lower_altitude;
double thickness;
double base_coverage;
double shape_scaling;
double edge_scaling;
double edge_length;
SurfaceMaterial* material;
double hardness;
double transparencydepth;
double lighttraversal;
double minimumlight;
Curve* _coverage_by_altitude;
NoiseGenerator* _coverage_noise;
NoiseGenerator* _shape_noise;
NoiseGenerator* _edge_noise;
};
}
}
#endif // CLOUDLAYERDEFINITION_H

View file

@ -0,0 +1,25 @@
#include "CloudsDefinition.h"
#include "CloudLayerDefinition.h"
static BaseDefinition* _layerConstructor(Layers* parent)
{
return new CloudLayerDefinition(parent);
}
CloudsDefinition::CloudsDefinition(BaseDefinition* parent):
Layers(parent, _layerConstructor)
{
}
void CloudsDefinition::applyPreset(CloudsPreset preset)
{
clear();
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY)
{
CloudLayerDefinition* layer = new CloudLayerDefinition(this);
layer->applyPreset(CloudLayerDefinition::CLOUDS_LAYER_PRESET_CIRRUS);
addLayer(layer);
}
}

View file

@ -0,0 +1,28 @@
#ifndef CLOUDSDEFINITION_H
#define CLOUDSDEFINITION_H
#include "definition_global.h"
#include "Layers.h"
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers
{
public:
CloudsDefinition(BaseDefinition* parent);
inline CloudLayerDefinition* getCloudLayer(int position) const {return (CloudLayerDefinition*)getLayer(position);}
typedef enum
{
CLOUDS_PRESET_PARTLY_CLOUDY
} CloudsPreset;
void applyPreset(CloudsPreset preset);
};
}
}
#endif // CLOUDSDEFINITION_H

View file

@ -7,6 +7,10 @@ Layers::Layers(BaseDefinition* parent, LayerConstructor layer_constructor, Layer
{
this->legacy_type = *legacy_type;
}
else
{
this->legacy_type.callback_create = NULL;
}
max_layer_count = 100;
null_layer = layer_constructor(this);
}
@ -46,12 +50,12 @@ void Layers::setMaxLayerCount(int max_layer_count)
// TODO Delete overlimit layers ?
}
int Layers::count()
int Layers::count() const
{
return layers.count();
}
BaseDefinition* Layers::getLayer(int position)
BaseDefinition* Layers::getLayer(int position) const
{
if (position >= 0 and position < layers.size())
{
@ -64,7 +68,7 @@ BaseDefinition* Layers::getLayer(int position)
}
}
int Layers::findLayer(BaseDefinition* layer)
int Layers::findLayer(BaseDefinition* layer) const
{
int result = layers.indexOf(layer);
if (result < 0)
@ -146,9 +150,18 @@ Layers* layersCreate(LayerType type, int max_layer_count)
Layers* layersCreateCopy(Layers* original)
{
Layers* result = new Layers(NULL, _legacyLayerConstructor, &original->legacy_type);
original->copy(result);
return result;
if (original->legacy_type.callback_create)
{
Layers* result = new Layers(NULL, _legacyLayerConstructor, &original->legacy_type);
original->copy(result);
return result;
}
else
{
Layers* result = new Layers(NULL, original->layer_constructor, NULL);
original->copy(result);
return result;
}
}
void layersDelete(Layers* layers)
@ -178,7 +191,14 @@ void layersLoad(PackStream* stream, Layers* layers)
const char* layersGetName(Layers* layers, int layer)
{
return ((LegacyLayer*)(layers->getLayer(layer)))->getLegacyName();
if (layers->legacy_type.callback_create)
{
return ((LegacyLayer*)(layers->getLayer(layer)))->getLegacyName();
}
else
{
return "";
}
}
void layersSetName(Layers* layers, int layer, const char* name)
@ -198,20 +218,36 @@ int layersCount(Layers* layers)
void* layersGetLayer(Layers* layers, int layer)
{
LegacyLayer* legacy = (LegacyLayer*)(layers->getLayer(layer));
return legacy->getLegacyDefinition();
if (layers->legacy_type.callback_create)
{
LegacyLayer* legacy = (LegacyLayer*)(layers->getLayer(layer));
return legacy->getLegacyDefinition();
}
else
{
return layers->getLayer(layer);
}
}
int layersAddLayer(Layers* layers, void* definition)
{
int position;
LegacyLayer* legacy = new LegacyLayer(layers, &layers->legacy_type);
if (definition)
if (layers->legacy_type.callback_create)
{
layers->legacy_type.callback_copy(definition, legacy->getLegacyDefinition());
int position;
LegacyLayer* legacy = new LegacyLayer(layers, &layers->legacy_type);
if (definition)
{
layers->legacy_type.callback_copy(definition, legacy->getLegacyDefinition());
}
position = layers->addLayer(legacy);
return position;
}
else
{
BaseDefinition* copied = layers->layer_constructor(layers);
((BaseDefinition*)definition)->copy(copied);
return layers->addLayer(copied);
}
position = layers->addLayer(legacy);
return position;
}
void layersDeleteLayer(Layers* layers, int layer)

View file

@ -26,9 +26,9 @@ public:
void setMaxLayerCount(int max_layer_count);
int count();
BaseDefinition* getLayer(int position);
int findLayer(BaseDefinition* layer);
int count() const;
BaseDefinition* getLayer(int position) const;
int findLayer(BaseDefinition* layer) const;
/**
* @brief Add a new layer
@ -47,9 +47,10 @@ public:
// Transitional data storage
LayerType legacy_type;
private:
// TODO make private when there is no more legacy layer
LayerConstructor layer_constructor;
public:
int max_layer_count;
QList<BaseDefinition*> layers;
BaseDefinition* null_layer;

View file

@ -19,7 +19,9 @@ SOURCES += \
LegacyLayer.cpp \
WaterDefinition.cpp \
SurfaceMaterial.cpp \
CameraDefinition.cpp
CameraDefinition.cpp \
CloudsDefinition.cpp \
CloudLayerDefinition.cpp
HEADERS +=\
definition_global.h \
@ -28,7 +30,9 @@ HEADERS +=\
LegacyLayer.h \
WaterDefinition.h \
SurfaceMaterial.h \
CameraDefinition.h
CameraDefinition.h \
CloudsDefinition.h \
CloudLayerDefinition.h
unix:!symbian {
maemo5 {

View file

@ -17,6 +17,8 @@ namespace definition {
class SurfaceMaterial;
class WaterDefinition;
class Layers;
class CloudsDefinition;
class CloudLayerDefinition;
}
}
using namespace paysages::definition;

View file

@ -9,7 +9,6 @@
class QPushButton;
class QComboBox;
class ColorGradation;
class Curve;
namespace paysages {
namespace desktop {

View file

@ -10,7 +10,9 @@
#include <QSlider>
#include <QScrollArea>
#include <QPushButton>
#include "Curve.h"
#include "tools.h"
#include "previewcolorgradation.h"
#include "widgetcurveeditor.h"
/**************** Dialog ****************/
@ -111,7 +113,7 @@ DialogColorGradation::DialogColorGradation(QWidget *parent, ColorGradation* grad
buttons->layout()->addWidget(_button_cancel);
QObject::connect(_button_cancel, SIGNAL(clicked()), this, SLOT(reject()));
_curve = curveCreate();
_curve = new Curve;
setWindowTitle(tr("Paysages 3D - Color gradation editor"));
resize(900, 600);
@ -122,7 +124,7 @@ DialogColorGradation::DialogColorGradation(QWidget *parent, ColorGradation* grad
DialogColorGradation::~DialogColorGradation()
{
colorGradationDelete(_current);
curveDelete(_curve);
delete _curve;
}
bool DialogColorGradation::getGradation(QWidget* parent, ColorGradation* gradation)
@ -181,10 +183,9 @@ void DialogColorGradation::selectBlue()
void DialogColorGradation::updateColors()
{
Curve* curve;
Curve curve;
curve = curveCreate();
_curve_editor->getCurve(curve);
_curve_editor->getCurve(&curve);
switch (_selected)
{
@ -194,23 +195,21 @@ void DialogColorGradation::updateColors()
_preview_blue->update();
break;
case 1:
colorGradationSetRedCurve(_current, curve);
colorGradationSetRedCurve(_current, &curve);
_preview_red->update();
break;
case 2:
colorGradationSetGreenCurve(_current, curve);
colorGradationSetGreenCurve(_current, &curve);
_preview_green->update();
break;
case 3:
colorGradationSetBlueCurve(_current, curve);
colorGradationSetBlueCurve(_current, &curve);
_preview_blue->update();
break;
default:
;
}
_preview_final->update();
curveDelete(curve);
}
void DialogColorGradation::revertToCurrent()

View file

@ -1,14 +1,15 @@
#ifndef _PAYSAGES_QT_DIALOGCOLORGRADATION_H_
#define _PAYSAGES_QT_DIALOGCOLORGRADATION_H_
#include "desktop_global.h"
#include <QDialog>
#include "widgetcurveeditor.h"
#include "previewcolorgradation.h"
#include "tools/color.h"
#include "tools/curve.h"
class QPushButton;
class WidgetCurveEditor;
class PreviewColorGradation;
class DialogColorGradation : public QDialog
{

View file

@ -1,15 +1,9 @@
#include "dialogcurve.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QImage>
#include <QLabel>
#include <QColor>
#include <QPainter>
#include <QSlider>
#include <QScrollArea>
#include <QPushButton>
#include "Curve.h"
#include "baseform.h"
#include "tools.h"
#include "widgetcurveeditor.h"
@ -23,8 +17,8 @@ DialogCurve::DialogCurve(QWidget *parent, Curve* curve, double xmin, double xmax
QLabel* label;
_base = curve;
_current = curveCreate();
curveCopy(_base, _current);
_current = new Curve;
_base->copy(_current);
setLayout(new QVBoxLayout());
@ -71,7 +65,7 @@ DialogCurve::DialogCurve(QWidget *parent, Curve* curve, double xmin, double xmax
DialogCurve::~DialogCurve()
{
curveDelete(_current);
delete _current;
}
bool DialogCurve::getCurve(QWidget* parent, Curve* curve, double xmin, double xmax, double ymin, double ymax, QString xlabel, QString ylabel)
@ -94,13 +88,13 @@ void DialogCurve::closeEvent(QCloseEvent*)
void DialogCurve::accept()
{
_curve_editor->getCurve(_current);
curveCopy(_current, _base);
_current->copy(_base);
QDialog::accept();
}
void DialogCurve::revert()
{
curveCopy(_base, _current);
_base->copy(_current);
revertToCurrent();
}

View file

@ -1,11 +1,12 @@
#ifndef _PAYSAGES_QT_DIALOGCURVE_H_
#define _PAYSAGES_QT_DIALOGCURVE_H_
#include <QDialog>
#include <QPushButton>
#include "widgetcurveeditor.h"
#include "desktop_global.h"
#include "tools/curve.h"
#include <QDialog>
class QPushButton;
class WidgetCurveEditor;
class DialogCurve : public QDialog
{

View file

@ -6,6 +6,8 @@
#include "Scenery.h"
#include "BasePreview.h"
#include "renderer.h"
#include "CloudsDefinition.h"
#include "CloudLayerDefinition.h"
#include "tools.h"
@ -13,7 +15,7 @@
class PreviewCloudsCoverage:public BasePreview
{
public:
PreviewCloudsCoverage(QWidget* parent, CloudsLayerDefinition* layer):BasePreview(parent)
PreviewCloudsCoverage(QWidget* parent, CloudLayerDefinition* layer):BasePreview(parent)
{
_renderer = cloudsPreviewCoverageCreateRenderer();
_3d = true;
@ -47,14 +49,14 @@ protected:
private:
Renderer* _renderer;
CloudsLayerDefinition* _original_layer;
CloudLayerDefinition* _original_layer;
bool _3d;
};
class PreviewCloudsColor:public BasePreview
{
public:
PreviewCloudsColor(QWidget* parent, CloudsLayerDefinition* layer):BasePreview(parent)
PreviewCloudsColor(QWidget* parent, CloudLayerDefinition* layer):BasePreview(parent)
{
_original_layer = layer;
@ -78,7 +80,7 @@ protected:
}
private:
Renderer* _renderer;
CloudsLayerDefinition* _original_layer;
CloudLayerDefinition* _original_layer;
};
/**************** Form ****************/
@ -90,8 +92,8 @@ FormClouds::FormClouds(QWidget *parent):
addAutoPreset(tr("Stratocumulus"));
addAutoPreset(tr("Stratus"));
_definition = (CloudsDefinition*)CloudsDefinitionClass.create();
_layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
_definition = new CloudsDefinition(NULL);
_layer = new CloudLayerDefinition(NULL);
_previewCoverage = new PreviewCloudsCoverage(parent, _layer);
_previewColor = new PreviewCloudsColor(parent, _layer);
@ -105,19 +107,19 @@ FormClouds::FormClouds(QWidget *parent):
addInputDouble(tr("Shape scaling"), &_layer->shape_scaling, 3.0, 30.0, 0.3, 3.0);
addInputDouble(tr("Edge scaling"), &_layer->edge_scaling, 0.5, 5.0, 0.05, 0.5);
addInputDouble(tr("Edge length"), &_layer->edge_length, 0.0, 1.0, 0.01, 0.1);
addInputMaterial(tr("Material"), &_layer->material);
addInputMaterial(tr("Material"), _layer->material);
addInputDouble(tr("Hardness to light"), &_layer->hardness, 0.0, 1.0, 0.01, 0.1);
addInputDouble(tr("Transparency depth"), &_layer->transparencydepth, 0.0, 10.0, 0.1, 1.0);
addInputDouble(tr("Light traversal depth"), &_layer->lighttraversal, 0.0, 10.0, 0.1, 1.0);
addInputDouble(tr("Minimum lighting"), &_layer->minimumlight, 0.0, 1.0, 0.01, 0.1);
setLayers(_definition->layers);
setLayers(_definition);
}
FormClouds::~FormClouds()
{
CloudsDefinitionClass.destroy(_definition);
cloudsGetLayerType().callback_delete(_layer);
delete _layer;
delete _definition;
delete _previewCoverage;
delete _previewColor;
@ -137,16 +139,16 @@ void FormClouds::applyConfig()
void FormClouds::layerReadCurrentFrom(void* layer_definition)
{
cloudsGetLayerType().callback_copy((CloudsLayerDefinition*)layer_definition, _layer);
((CloudLayerDefinition*)layer_definition)->copy(_layer);
}
void FormClouds::layerWriteCurrentTo(void* layer_definition)
{
cloudsGetLayerType().callback_copy(_layer, (CloudsLayerDefinition*)layer_definition);
_layer->copy((CloudLayerDefinition*)layer_definition);
}
void FormClouds::autoPresetSelected(int preset)
{
cloudsLayerAutoPreset(_layer, (CloudsLayerPreset)preset);
_layer->applyPreset((CloudLayerDefinition::CloudsLayerPreset)preset);
BaseForm::autoPresetSelected(preset);
}

View file

@ -26,7 +26,7 @@ protected:
private:
CloudsDefinition* _definition;
CloudsLayerDefinition* _layer;
CloudLayerDefinition* _layer;
BasePreview* _previewCoverage;
BasePreview* _previewColor;
};

View file

@ -14,20 +14,20 @@
#include "PackStream.h"
#include "SoftwareRenderer.h"
#include "BasePreview.h"
#include "CloudsDefinition.h"
#include "CameraDefinition.h"
/**************** Previews ****************/
class PreviewRenderLandscape : public BasePreview
{
public:
PreviewRenderLandscape(QWidget* parent) : BasePreview(parent)
{
_renderer = new SoftwareRenderer();
_renderer->getCameraLocation = _getCameraLocation;
lightingManagerDisableSpecularity(_renderer->lighting);
_no_clouds = (CloudsDefinition*) CloudsDefinitionClass.create();
_no_clouds = new CloudsDefinition(NULL);
_clouds_enabled = true;
addOsd(QString("geolocation"));
@ -40,11 +40,10 @@ public:
~PreviewRenderLandscape()
{
delete _renderer;
CloudsDefinitionClass.destroy(_no_clouds);
delete _no_clouds;
}
protected:
Color getColor(double x, double y)
{
Vector3 location;
@ -84,6 +83,7 @@ protected:
redraw();
}
}
private:
Renderer* _renderer;
bool _clouds_enabled;

View file

@ -3,8 +3,8 @@
#include <QLabel>
#include <QPushButton>
#include <QPainter>
#include "Curve.h"
#include "dialogcurve.h"
#include "tools.h"
class CurveSmallPreview:public QWidget
{
@ -35,9 +35,9 @@ public:
{
painter.setPen(QColor(0, 0, 0));
position = _xmin + (_xmax - _xmin) * (double)x / (double)(width - 1);
value = (curveGetValue(_curve, position) - _ymin) * (_ymax - _ymin);
prev_value = (curveGetValue(_curve, position - (_xmax - _xmin) / (double)(width - 1)) - _ymin) * (_ymax - _ymin);
next_value = (curveGetValue(_curve, position + (_xmax - _xmin) / (double)(width - 1)) - _ymin) * (_ymax - _ymin);
value = (_curve->getValue(position) - _ymin) * (_ymax - _ymin);
prev_value = (_curve->getValue(position - (_xmax - _xmin) / (double)(width - 1)) - _ymin) * (_ymax - _ymin);
next_value = (_curve->getValue(position + (_xmax - _xmin) / (double)(width - 1)) - _ymin) * (_ymax - _ymin);
painter.drawLine(x, height - 1 - (int)((value + (prev_value - value) / 2.0) * (double)(height - 1)), x, height - 1 - (int)((value + (next_value - value) / 2.0) * (double)(height - 1)));
painter.drawPoint(x, height - 1 - (int)(value * (double)(height - 1)));

View file

@ -1,11 +1,11 @@
#ifndef _PAYSAGES_QT_INPUTCURVE_H_
#define _PAYSAGES_QT_INPUTCURVE_H_
#include "desktop_global.h"
#include <QWidget>
#include "baseinput.h"
#include "tools/curve.h"
class InputCurve:public BaseInput
{
Q_OBJECT

View file

@ -8,6 +8,7 @@
#include <QSlider>
#include <QScrollArea>
#include <QPushButton>
#include "Curve.h"
#include "baseform.h"
#include "tools.h"
#include "widgetcurveeditor.h"
@ -21,24 +22,21 @@ PreviewColorGradation::PreviewColorGradation(QWidget* parent, ColorGradation* gr
void PreviewColorGradation::paintEvent(QPaintEvent*)
{
Curve* curve;
Curve curve;
QPainter painter(this);
int width = this->width();
int height = this->height();
curve = curveCreate();
switch (band)
{
case COLORGRADATIONBAND_RED:
colorGradationGetRedCurve(gradation, curve);
colorGradationGetRedCurve(gradation, &curve);
break;
case COLORGRADATIONBAND_GREEN:
colorGradationGetGreenCurve(gradation, curve);
colorGradationGetGreenCurve(gradation, &curve);
break;
case COLORGRADATIONBAND_BLUE:
colorGradationGetBlueCurve(gradation, curve);
colorGradationGetBlueCurve(gradation, &curve);
break;
default:
break;
@ -49,13 +47,13 @@ void PreviewColorGradation::paintEvent(QPaintEvent*)
switch (band)
{
case COLORGRADATIONBAND_RED:
painter.setPen(QColor::fromRgbF(curveGetValue(curve, (double)x / (double)width), 0.0, 0.0));
painter.setPen(QColor::fromRgbF(curve.getValue((double)x / (double)width), 0.0, 0.0));
break;
case COLORGRADATIONBAND_GREEN:
painter.setPen(QColor::fromRgbF(0.0, curveGetValue(curve, (double)x / (double)width), 0.0));
painter.setPen(QColor::fromRgbF(0.0, curve.getValue((double)x / (double)width), 0.0));
break;
case COLORGRADATIONBAND_BLUE:
painter.setPen(QColor::fromRgbF(0.0, 0.0, curveGetValue(curve, (double)x / (double)width)));
painter.setPen(QColor::fromRgbF(0.0, 0.0, curve.getValue((double)x / (double)width)));
break;
case COLORGRADATIONBAND_FINAL:
painter.setPen(colorToQColor(colorGradationGet(gradation, (double)x / (double)width)));
@ -63,8 +61,6 @@ void PreviewColorGradation::paintEvent(QPaintEvent*)
}
painter.drawLine(x, 0, x, height - 1);
}
curveDelete(curve);
}
void PreviewColorGradation::mouseReleaseEvent(QMouseEvent*)

View file

@ -3,11 +3,12 @@
#include <QPainter>
#include <QPaintEngine>
#include <QMouseEvent>
#include "tools.h"
#include "Curve.h"
#include "tools/euclid.h"
WidgetCurveEditor::WidgetCurveEditor(QWidget *parent, double xmin, double xmax, double ymin, double ymax) : QWidget(parent)
{
_curve = curveCreate();
_curve = new Curve;
_dragged = -1;
_pen = QColor(0, 0, 0);
@ -21,7 +22,7 @@ WidgetCurveEditor::WidgetCurveEditor(QWidget *parent, double xmin, double xmax,
WidgetCurveEditor::~WidgetCurveEditor()
{
curveDelete(_curve);
delete _curve;
}
void WidgetCurveEditor::setAxisLabels(QString xlabel, QString ylabel)
@ -32,13 +33,13 @@ void WidgetCurveEditor::setAxisLabels(QString xlabel, QString ylabel)
void WidgetCurveEditor::setCurve(Curve* curve)
{
curveCopy(curve, _curve);
curve->copy(_curve);
update();
}
void WidgetCurveEditor::getCurve(Curve* curve)
{
curveCopy(_curve, curve);
_curve->copy(curve);
}
void WidgetCurveEditor::setPenColor(QColor color)
@ -94,20 +95,20 @@ void WidgetCurveEditor::paintEvent(QPaintEvent*)
{
position = ((double)x / dwidth) * (_xmax - _xmin) + _xmin;
value = (curveGetValue(_curve, position) - _ymin) / (_ymax - _ymin);
prev_value = curveGetValue(_curve, position - (_xmax - _xmin) / dwidth);
next_value = curveGetValue(_curve, position + (_xmax - _xmin) / dwidth);
value = (_curve->getValue(position) - _ymin) / (_ymax - _ymin);
prev_value = _curve->getValue(position - (_xmax - _xmin) / dwidth);
next_value = _curve->getValue(position + (_xmax - _xmin) / dwidth);
painter.drawLine(x, height - 1 - (int)((value + (prev_value - value) / 2.0) * dheight), x, height - 1 - (int)((value + (next_value - value) / 2.0) * dheight));
painter.drawPoint(x, height - 1 - (int)(value * dheight));
}
// Draw handles
n = curveGetPointCount(_curve);
n = _curve->getPointCount();
painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing, true);
for (i = 0; i < n; i++)
{
curveGetPoint(_curve, i, &point);
_curve->getPoint(i, &point);
painter.drawEllipse(QPointF((int)((point.position - _xmin) / (_xmax - _xmin) * dwidth), height - 1 - (int)((point.value - _ymin) / (_ymax - _ymin) * dheight)), 4.0, 4.0);
}
}
@ -135,7 +136,7 @@ void WidgetCurveEditor::mouseMoveEvent(QMouseEvent* event)
point.value = (point.value < _ymin) ? _ymin : point.value;
point.value = (point.value > _ymax) ? _ymax : point.value;
curveSetPoint(_curve, _dragged, &point);
_curve->setPoint(_dragged, point);
update();
@ -154,7 +155,7 @@ void WidgetCurveEditor::mouseReleaseEvent(QMouseEvent* event)
clicked = getPointAt(event->x(), event->y());
if (clicked >= 0)
{
curveRemovePoint(_curve, clicked);
_curve->removePoint(clicked);
update();
emit liveChanged();
}
@ -162,7 +163,7 @@ void WidgetCurveEditor::mouseReleaseEvent(QMouseEvent* event)
else if (event->button() == Qt::LeftButton && _dragged >= 0)
{
_dragged = -1;
curveValidate(_curve);
_curve->validate();
update();
}
@ -178,8 +179,8 @@ void WidgetCurveEditor::mouseDoubleClickEvent(QMouseEvent* event)
if (getPointAt(event->x(), event->y()) < 0)
{
screenToCurve(event->x(), event->y(), &point.position, &point.value);
curveAddPoint(_curve, &point);
curveValidate(_curve);
_curve->addPoint(point);
_curve->validate();
update();
emit liveChanged();
}
@ -206,7 +207,7 @@ int WidgetCurveEditor::getPointAt(int x, int y)
CurvePoint point;
int dx, dy;
n = curveGetPointCount(_curve);
n = _curve->getPointCount();
if (n < 1)
{
return -1;
@ -217,7 +218,7 @@ int WidgetCurveEditor::getPointAt(int x, int y)
distance = 0.0;
for (int i = 0; i < n; i++)
{
curveGetPoint(_curve, i, &point);
_curve->getPoint(i, &point);
curveToScreen(point.position, point.value, &dx, &dy);
ndistance = euclidGetDistance2D((double)x, (double)y, (double)dx, (double)dy);
if (nearest < 0 || ndistance < distance)

View file

@ -1,9 +1,10 @@
#ifndef _PAYSAGES_QT_WIDGETCURVEEDITOR_H_
#define _PAYSAGES_QT_WIDGETCURVEEDITOR_H_
#include "desktop_global.h"
#include <QWidget>
#include <QColor>
#include "tools/curve.h"
class WidgetCurveEditor : public QWidget
{

View file

@ -6,7 +6,7 @@
#include "PackStream.h"
#include "atmosphere/public.h"
#include "CameraDefinition.h"
#include "clouds/public.h"
#include "CloudsDefinition.h"
#include "terrain/public.h"
#include "textures/public.h"
#include "water/public.h"
@ -21,13 +21,14 @@ Scenery::Scenery():
{
atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
camera = new CameraDefinition;
clouds = (CloudsDefinition*)CloudsDefinitionClass.create();
clouds = new CloudsDefinition(this);
terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
textures = (TexturesDefinition*)TexturesDefinitionClass.create();
water = new WaterDefinition(this);
addChild(camera);
addChild(water);
addChild(clouds);
_custom_load = NULL;
_custom_save = NULL;
@ -37,7 +38,6 @@ Scenery::Scenery():
Scenery::~Scenery()
{
AtmosphereDefinitionClass.destroy(atmosphere);
CloudsDefinitionClass.destroy(clouds);
TerrainDefinitionClass.destroy(terrain);
TexturesDefinitionClass.destroy(textures);
}
@ -61,7 +61,6 @@ void Scenery::save(PackStream* stream) const
noiseSave(stream);
AtmosphereDefinitionClass.save(stream, atmosphere);
CloudsDefinitionClass.save(stream, clouds);
TerrainDefinitionClass.save(stream, terrain);
TexturesDefinitionClass.save(stream, textures);
@ -78,7 +77,6 @@ void Scenery::load(PackStream* stream)
noiseLoad(stream);
AtmosphereDefinitionClass.load(stream, atmosphere);
CloudsDefinitionClass.load(stream, clouds);
TerrainDefinitionClass.load(stream, terrain);
TexturesDefinitionClass.load(stream, textures);
@ -109,7 +107,7 @@ void Scenery::autoPreset(int seed)
texturesAutoPreset(textures, TEXTURES_PRESET_FULL);
atmosphereAutoPreset(atmosphere, ATMOSPHERE_PRESET_CLEAR_DAY);
water->applyPreset(WATER_PRESET_LAKE);
cloudsAutoPreset(clouds, CLOUDS_PRESET_PARTLY_CLOUDY);
clouds->applyPreset(CloudsDefinition::CLOUDS_PRESET_PARTLY_CLOUDY);
camera->setLocation(VECTOR_ZERO);
camera->setTarget(VECTOR_NORTH);
@ -140,12 +138,12 @@ void Scenery::getCamera(CameraDefinition* camera)
void Scenery::setClouds(CloudsDefinition* clouds)
{
CloudsDefinitionClass.copy(clouds, this->clouds);
clouds->copy(this->clouds);
}
void Scenery::getClouds(CloudsDefinition* clouds)
{
CloudsDefinitionClass.copy(this->clouds, clouds);
this->clouds->copy(clouds);
}
void Scenery::setTerrain(TerrainDefinition* terrain)
@ -178,6 +176,11 @@ void Scenery::getWater(WaterDefinition* water)
this->water->copy(water);
}
#include "clouds/public.h"
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int, int, int, int)
{
RayCastingResult result;

View file

@ -6,7 +6,6 @@
#include "BaseDefinition.h"
class AtmosphereDefinition;
class CloudsDefinition;
class TerrainDefinition;
class TexturesDefinition;
class Renderer;

View file

@ -1,229 +0,0 @@
#include "private.h"
#include <stdlib.h>
#include "PackStream.h"
#include "NoiseGenerator.h"
/******************** Global definition ********************/
static void _validateDefinition(CloudsDefinition* definition)
{
layersValidate(definition->layers);
}
static CloudsDefinition* _createDefinition()
{
CloudsDefinition* definition = new CloudsDefinition;
definition->layers = layersCreate(cloudsGetLayerType(), CLOUDS_MAX_LAYERS);
return definition;
}
static void _deleteDefinition(CloudsDefinition* definition)
{
layersDelete(definition->layers);
delete 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);
definition->_shape_noise->clearLevels();
definition->_edge_noise->clearLevels();
definition->_coverage_noise->clearLevels();
definition->_coverage_noise->addLevelsSimple(2, 10.0, 0.0, 1.0, 0.0);
definition->_coverage_noise->addLevelsSimple(2, 1.0, 0.0, 1.0, 0.0);
definition->_coverage_noise->setFunctionParams(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);
definition->_shape_noise->addLevelsSimple(3, 1.0, 0.0, 1.0, 0.5);
definition->_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
definition->_edge_noise->addLevelsSimple(4, 1.0, -0.5, 0.5, 0.5);
definition->_edge_noise->setFunctionParams(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);
definition->_shape_noise->addLevelsSimple(7, 1.0, 0.0, 1.0, 0.5);
definition->_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.4, 0.0);
definition->_edge_noise->addLevelsSimple(4, 1.0, -0.5, 0.5, 0.5);
definition->_edge_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.8, 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);
definition->_shape_noise->addLevelsSimple(4, 1.0, 0.0, 1.0, 0.5);
definition->_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.3, 0.0);
definition->_edge_noise->addLevelsSimple(6, 1.0, -0.5, 0.5, 0.5);
definition->_edge_noise->setFunctionParams(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);
definition->_shape_noise->addLevelsSimple(3, 1.0, 0.0, 1.0, 0.5);
definition->_shape_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, -0.3, 0.0);
definition->_edge_noise->addLevelsSimple(4, 1.0, -0.5, 0.5, 0.5);
definition->_edge_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, -0.5, 0.0);
break;
default:
break;
}
definition->_coverage_noise->normalizeAmplitude(-1.0, 3.0, 0);
definition->_shape_noise->normalizeAmplitude(-0.5, 0.5, 0);
definition->_edge_noise->normalizeAmplitude(-0.5, 0.5, 0);
materialValidate(&definition->material);
}
CloudsLayerDefinition* cloudsLayerCreateDefinition()
{
CloudsLayerDefinition* result;
result = new CloudsLayerDefinition;
result->_coverage_by_altitude = curveCreate();
result->_coverage_noise = new NoiseGenerator();
result->_shape_noise = new NoiseGenerator();
result->_edge_noise = new NoiseGenerator();
cloudsLayerAutoPreset(result, CLOUDS_LAYER_PRESET_CIRRUS);
return result;
}
void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition)
{
curveDelete(definition->_coverage_by_altitude);
delete definition->_coverage_noise;
delete definition->_shape_noise;
delete definition->_edge_noise;
delete 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;
source->_coverage_noise->copy(destination->_coverage_noise);
destination->_shape_noise = temp._shape_noise;
source->_shape_noise->copy(destination->_shape_noise);
destination->_edge_noise = temp._edge_noise;
source->_edge_noise->copy(destination->_edge_noise);
}
void _cloudsLayerSave(PackStream* stream, CloudsLayerDefinition* layer)
{
int clouds_type = (int)layer->type;
stream->write(&clouds_type);
stream->write(&layer->lower_altitude);
stream->write(&layer->thickness);
curveSave(stream, layer->_coverage_by_altitude);
layer->_coverage_noise->save(stream);
layer->_shape_noise->save(stream);
layer->_edge_noise->save(stream);
materialSave(stream, &layer->material);
stream->write(&layer->hardness);
stream->write(&layer->transparencydepth);
stream->write(&layer->lighttraversal);
stream->write(&layer->minimumlight);
stream->write(&layer->shape_scaling);
stream->write(&layer->edge_scaling);
stream->write(&layer->edge_length);
stream->write(&layer->base_coverage);
}
void _cloudsLayerLoad(PackStream* stream, CloudsLayerDefinition* layer)
{
int clouds_type;
stream->read(&clouds_type);
layer->type = (CloudsType)clouds_type;
stream->read(&layer->lower_altitude);
stream->read(&layer->thickness);
curveLoad(stream, layer->_coverage_by_altitude);
layer->_coverage_noise->load(stream);
layer->_shape_noise->load(stream);
layer->_edge_noise->load(stream);
materialLoad(stream, &layer->material);
stream->read(&layer->hardness);
stream->read(&layer->transparencydepth);
stream->read(&layer->lighttraversal);
stream->read(&layer->minimumlight);
stream->read(&layer->shape_scaling);
stream->read(&layer->edge_scaling);
stream->read(&layer->edge_length);
stream->read(&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;
}

View file

@ -1,9 +1,10 @@
#include "clo_density.h"
#include "../tools.h"
#include "NoiseGenerator.h"
#include "CloudLayerDefinition.h"
#include "Curve.h"
double cloudsGetLayerCoverage(CloudsLayerDefinition* layer, Vector3 location)
double cloudsGetLayerCoverage(CloudLayerDefinition* layer, Vector3 location)
{
if (layer->base_coverage <= 0.0)
{
@ -14,7 +15,7 @@ double cloudsGetLayerCoverage(CloudsLayerDefinition* layer, Vector3 location)
double coverage = 0.5 + layer->_coverage_noise->get2DTotal(location.x / layer->shape_scaling, location.z / layer->shape_scaling);
coverage -= (1.0 - layer->base_coverage);
coverage *= curveGetValue(layer->_coverage_by_altitude, (location.y - layer->lower_altitude) / layer->thickness);
coverage *= layer->_coverage_by_altitude->getValue((location.y - layer->lower_altitude) / layer->thickness);
if (coverage < 0.0)
{
@ -31,7 +32,7 @@ double cloudsGetLayerCoverage(CloudsLayerDefinition* layer, Vector3 location)
}
}
double cloudsGetLayerDensity(CloudsLayerDefinition* layer, Vector3 location, double coverage)
double cloudsGetLayerDensity(CloudLayerDefinition* layer, Vector3 location, double coverage)
{
if (coverage <= 0.0)
{
@ -49,7 +50,7 @@ double cloudsGetLayerDensity(CloudsLayerDefinition* layer, Vector3 location, dou
}
}
double cloudsGetEdgeDensity(CloudsLayerDefinition* layer, Vector3 location, double layer_density)
double cloudsGetEdgeDensity(CloudLayerDefinition* layer, Vector3 location, double layer_density)
{
if (layer_density <= 0.0)
{
@ -67,22 +68,13 @@ double cloudsGetEdgeDensity(CloudsLayerDefinition* layer, Vector3 location, doub
}
}
static double _fakeGetDensity(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
static double _fakeGetDensity(Renderer*, CloudLayerDefinition*, Vector3)
{
UNUSED(layer);
UNUSED(renderer);
UNUSED(location);
return 0.0;
}
static double _fakeGetEdgeDensity(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location, double layer_density)
static double _fakeGetEdgeDensity(Renderer*, CloudLayerDefinition*, Vector3, double)
{
UNUSED(layer);
UNUSED(renderer);
UNUSED(location);
UNUSED(layer_density);
return 0.0;
}
@ -92,19 +84,15 @@ void cloudsBindFakeDensityToRenderer(CloudsRenderer* renderer)
renderer->getEdgeDensity = _fakeGetEdgeDensity;
}
static double _realGetDensity(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
static double _realGetDensity(Renderer*, CloudLayerDefinition* layer, Vector3 location)
{
UNUSED(renderer);
double coverage = cloudsGetLayerCoverage(layer, location);
return cloudsGetLayerDensity(layer, location, coverage);
}
static double _realGetEdgeDensity(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location, double layer_density)
static double _realGetEdgeDensity(Renderer*, CloudLayerDefinition* layer, Vector3 location, double layer_density)
{
UNUSED(renderer);
return cloudsGetEdgeDensity(layer, location, layer_density);
}

View file

@ -13,7 +13,7 @@
* 0.0 means no cloud is present.
* 1.0 means full layer.
*/
RENDERINGSHARED_EXPORT double cloudsGetLayerCoverage(CloudsLayerDefinition* layer, Vector3 location);
RENDERINGSHARED_EXPORT double cloudsGetLayerCoverage(CloudLayerDefinition* layer, Vector3 location);
/**
* Get the global density of a cloud layer at a given point [0.0;1.0].
@ -21,12 +21,12 @@ RENDERINGSHARED_EXPORT double cloudsGetLayerCoverage(CloudsLayerDefinition* laye
* 0.0 means no cloud is present.
* 1.0 means full density (deep inside cloud).
*/
RENDERINGSHARED_EXPORT double cloudsGetLayerDensity(CloudsLayerDefinition* layer, Vector3 location, double coverage);
RENDERINGSHARED_EXPORT double cloudsGetLayerDensity(CloudLayerDefinition* layer, Vector3 location, double coverage);
/**
* Get the local density of a cloud layer at a given point inside an edge [0.0;1.0].
*/
RENDERINGSHARED_EXPORT double cloudsGetEdgeDensity(CloudsLayerDefinition* layer, Vector3 location, double layer_density);
RENDERINGSHARED_EXPORT double cloudsGetEdgeDensity(CloudLayerDefinition* layer, Vector3 location, double layer_density);
/*
* Bind fake density functions to a renderer.

View file

@ -1,99 +0,0 @@
#include "private.h"
#include <cmath>
#include <cstdlib>
#include "NoiseGenerator.h"
/*
* Clouds presets.
*/
void cloudsAutoPreset(CloudsDefinition* definition, CloudsPreset preset)
{
int layer;
layersClear(definition->layers);
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY)
{
layer = layersAddLayer(definition->layers, NULL);
cloudsLayerAutoPreset((CloudsLayerDefinition*)layersGetLayer(definition->layers, layer), CLOUDS_LAYER_PRESET_CIRRUS);
}
}
void cloudsLayerAutoPreset(CloudsLayerDefinition* definition, CloudsLayerPreset preset)
{
definition->_coverage_noise->randomizeOffsets();
definition->_edge_noise->randomizeOffsets();
definition->_shape_noise->randomizeOffsets();
definition->material.base = colorToHSL(colorFromValues(0.7, 0.7, 0.7, 1.0));
switch (preset)
{
case CLOUDS_LAYER_PRESET_CIRRUS:
definition->type = CLOUDS_TYPE_CIRRUS;
definition->lower_altitude = 25.0;
definition->thickness = 2.0;
definition->material.reflection = 0.4;
definition->material.shininess = 0.5;
definition->hardness = 0.0;
definition->transparencydepth = 3.0;
definition->lighttraversal = 10.0;
definition->minimumlight = 0.6;
definition->shape_scaling = 8.0;
definition->edge_scaling = 2.0;
definition->edge_length = 0.8;
definition->base_coverage = 0.6;
break;
case CLOUDS_LAYER_PRESET_CUMULUS:
definition->type = CLOUDS_TYPE_CUMULUS;
definition->lower_altitude = 15.0;
definition->thickness = 15.0;
definition->material.reflection = 0.5;
definition->material.shininess = 1.2;
definition->hardness = 0.25;
definition->transparencydepth = 1.5;
definition->lighttraversal = 8.0;
definition->minimumlight = 0.4;
definition->shape_scaling = 20.0;
definition->edge_scaling = 2.0;
definition->edge_length = 0.0;
definition->base_coverage = 0.7;
break;
case CLOUDS_LAYER_PRESET_STRATOCUMULUS:
definition->type = CLOUDS_TYPE_STRATOCUMULUS;
definition->lower_altitude = 5.0;
definition->thickness = 6.0;
definition->material.reflection = 0.3;
definition->material.shininess = 0.8;
definition->hardness = 0.25;
definition->transparencydepth = 1.5;
definition->lighttraversal = 7.0;
definition->minimumlight = 0.4;
definition->shape_scaling = 10.0;
definition->edge_scaling = 0.8;
definition->edge_length = 0.3;
definition->base_coverage = 0.4;
break;
case CLOUDS_LAYER_PRESET_STRATUS:
definition->type = CLOUDS_TYPE_STRATUS;
definition->lower_altitude = 3.0;
definition->thickness = 4.0;
definition->material.reflection = 0.1;
definition->material.shininess = 0.8;
definition->hardness = 0.1;
definition->transparencydepth = 3.0;
definition->lighttraversal = 10.0;
definition->minimumlight = 0.6;
definition->shape_scaling = 8.0;
definition->edge_scaling = 2.0;
definition->edge_length = 1.0;
definition->base_coverage = 0.4;
break;
default:
break;
}
cloudsLayerValidateDefinition(definition);
}

View file

@ -3,20 +3,16 @@
#include "../tools/euclid.h"
#include "../renderer.h"
#include "../tools.h"
#include "atmosphere/public.h"
#include "CloudsDefinition.h"
#include "CloudLayerDefinition.h"
/*
* Clouds previews.
*/
Color _fakeApplyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial* material)
Color _fakeApplyLightingToSurface(Renderer*, Vector3, Vector3, SurfaceMaterial*)
{
UNUSED(renderer);
UNUSED(location);
UNUSED(normal);
UNUSED(material);
return COLOR_WHITE;
}
@ -28,12 +24,11 @@ Renderer* cloudsPreviewCoverageCreateRenderer()
return result;
}
void cloudsPreviewCoverageBindLayer(Renderer* renderer, CloudsLayerDefinition* layer)
void cloudsPreviewCoverageBindLayer(Renderer* renderer, CloudLayerDefinition* layer)
{
CloudsDefinition* definition = (CloudsDefinition*)CloudsDefinitionClass.create();
layersAddLayer(definition->layers, layer);
CloudsRendererClass.bind(renderer, definition);
CloudsDefinitionClass.destroy(definition);
CloudsDefinition clouds(NULL);
clouds.addLayer(layer->newCopy(&clouds));
CloudsRendererClass.bind(renderer, &clouds);
}
Color cloudsPreviewCoverageGetPixel(Renderer* renderer, double x, double y, double scaling, int perspective)
@ -65,14 +60,10 @@ Color cloudsPreviewCoverageGetPixel(Renderer* renderer, double x, double y, doub
}
}
static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3 normal, int opaque)
static void _getLightingStatus(Renderer*, LightStatus* status, Vector3, int)
{
LightDefinition light;
UNUSED(renderer);
UNUSED(normal);
UNUSED(opaque);
light.color.r = 0.5;
light.color.g = 0.5;
light.color.b = 0.5;
@ -104,11 +95,8 @@ Renderer* cloudsPreviewMaterialCreateRenderer()
return result;
}
static double _getDensity(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
static double _getDensity(Renderer*, CloudLayerDefinition* layer, Vector3 location)
{
UNUSED(renderer);
UNUSED(layer);
double distance = 2.0 * v3Norm(location) / layer->thickness;
if (distance > 1.0)
{
@ -124,14 +112,13 @@ static double _getDensity(Renderer* renderer, CloudsLayerDefinition* layer, Vect
}
}
void cloudsPreviewMaterialBindLayer(Renderer* renderer, CloudsLayerDefinition* layer)
void cloudsPreviewMaterialBindLayer(Renderer* renderer, CloudLayerDefinition* layer)
{
CloudsDefinition* definition = (CloudsDefinition*)CloudsDefinitionClass.create();
layersAddLayer(definition->layers, layer);
CloudsRendererClass.bind(renderer, definition);
CloudsDefinitionClass.destroy(definition);
CloudsDefinition clouds(NULL);
clouds.addLayer(layer->newCopy(&clouds));
CloudsRendererClass.bind(renderer, &clouds);
layer = (CloudsLayerDefinition*)layersGetLayer(renderer->clouds->definition->layers, 0);
layer = renderer->clouds->definition->getCloudLayer(0);
layer->thickness = layer->shape_scaling;
layer->lower_altitude = -layer->thickness / 2.0;
@ -141,7 +128,7 @@ void cloudsPreviewMaterialBindLayer(Renderer* renderer, CloudsLayerDefinition* l
Color cloudsPreviewMaterialGetPixel(Renderer* renderer, double x, double y)
{
Vector3 start, end;
CloudsLayerDefinition* layer = (CloudsLayerDefinition*)layersGetLayer(renderer->clouds->definition->layers, 0);
CloudLayerDefinition* layer = renderer->clouds->definition->getCloudLayer(0);
double thickness = layer->thickness;
start.x = x * thickness * 0.5;

View file

@ -2,18 +2,17 @@
#define _PAYSAGES_CLOUDS_PREVIEW_H_
#include "public.h"
#include "../tools/euclid.h"
/**
* Cloud preview helpers.
*/
RENDERINGSHARED_EXPORT Renderer* cloudsPreviewCoverageCreateRenderer();
RENDERINGSHARED_EXPORT void cloudsPreviewCoverageBindLayer(Renderer* renderer, CloudsLayerDefinition* layer);
RENDERINGSHARED_EXPORT void cloudsPreviewCoverageBindLayer(Renderer* renderer, CloudLayerDefinition* layer);
RENDERINGSHARED_EXPORT Color cloudsPreviewCoverageGetPixel(Renderer* renderer, double x, double y, double scaling, int perspective);
RENDERINGSHARED_EXPORT Renderer* cloudsPreviewMaterialCreateRenderer();
RENDERINGSHARED_EXPORT void cloudsPreviewMaterialBindLayer(Renderer* renderer, CloudsLayerDefinition* layer);
RENDERINGSHARED_EXPORT void cloudsPreviewMaterialBindLayer(Renderer* renderer, CloudLayerDefinition* layer);
RENDERINGSHARED_EXPORT Color cloudsPreviewMaterialGetPixel(Renderer* renderer, double x, double y);
#endif

View file

@ -7,6 +7,8 @@
#include "clo_density.h"
#include "clo_walking.h"
#include "atmosphere/public.h"
#include "CloudsDefinition.h"
#include "CloudLayerDefinition.h"
/******************** Fake ********************/
static int _fakeAlterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
@ -80,10 +82,10 @@ static int _alterLight(Renderer* renderer, LightDefinition* light, Vector3 locat
data.light_power = colorGetPower(&light->color);
/* TODO Iter layers in sorted order */
n = layersCount(definition->layers);
n = definition->count();
for (i = 0; i < n; i++)
{
CloudsLayerDefinition* layer = (CloudsLayerDefinition*)layersGetLayer(renderer->clouds->definition->layers, i);
CloudLayerDefinition* layer = definition->getCloudLayer(i);
Vector3 ostart, oend;
ostart = location;
@ -144,7 +146,7 @@ static void _walkerMaterialCallback(CloudsWalker* walker)
CloudWalkerStepInfo* segment = cloudsWalkerGetLastSegment(walker);
AccumulatedMaterialData* data = (AccumulatedMaterialData*)segment->data;
Renderer* renderer = segment->renderer;
CloudsLayerDefinition* layer = segment->layer;
CloudLayerDefinition* layer = segment->layer;
assert(data != NULL);
@ -172,7 +174,7 @@ static void _walkerMaterialCallback(CloudsWalker* walker)
{
data->out_scattering += 0.3 * density_integral;
Color in_scattering = renderer->applyLightingToSurface(renderer, segment->start.location, VECTOR_ZERO, &layer->material);
Color in_scattering = renderer->applyLightingToSurface(renderer, segment->start.location, VECTOR_ZERO, layer->material);
in_scattering.r *= density_integral * 5.0;
in_scattering.g *= density_integral * 5.0;
in_scattering.b *= density_integral * 5.0;
@ -195,7 +197,7 @@ static Color _getColor(Renderer* renderer, Color base, Vector3 start, Vector3 en
CloudsDefinition* definition = renderer->clouds->definition;
int i, n;
n = layersCount(definition->layers);
n = definition->count();
if (n < 1)
{
return base;
@ -204,7 +206,7 @@ static Color _getColor(Renderer* renderer, Color base, Vector3 start, Vector3 en
/* TODO Iter layers in sorted order */
for (i = 0; i < n; i++)
{
CloudsLayerDefinition* layer = (CloudsLayerDefinition*)layersGetLayer(renderer->clouds->definition->layers, i);
CloudLayerDefinition* layer = definition->getCloudLayer(i);
Vector3 ostart, oend;
ostart = start;
@ -250,7 +252,7 @@ static CloudsRenderer* _createRenderer()
CloudsRenderer* result;
result = new CloudsRenderer;
result->definition = (CloudsDefinition*)CloudsDefinitionClass.create();
result->definition = new CloudsDefinition(NULL);
result->getColor = _fakeGetColor;
result->alterLight = (FuncLightingAlterLight)_fakeAlterLight;
@ -262,13 +264,13 @@ static CloudsRenderer* _createRenderer()
static void _deleteRenderer(CloudsRenderer* renderer)
{
CloudsDefinitionClass.destroy(renderer->definition);
delete renderer->definition;
delete renderer;
}
static void _bindRenderer(Renderer* renderer, CloudsDefinition* definition)
{
CloudsDefinitionClass.copy(definition, renderer->clouds->definition);
definition->copy(renderer->clouds->definition);
renderer->clouds->getColor = _getColor;
renderer->clouds->alterLight = (FuncLightingAlterLight)_alterLight;

View file

@ -1,6 +1,7 @@
#include "clo_walking.h"
#include "../renderer.h"
#include "CloudLayerDefinition.h"
/**
* Control of the next walking order.
@ -49,7 +50,7 @@ struct CloudsWalker
};
int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Vector3* end)
int cloudsOptimizeWalkingBounds(CloudLayerDefinition* layer, Vector3* start, Vector3* end)
{
Vector3 diff;
@ -101,7 +102,7 @@ int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Ve
return 1;
}
CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 start, Vector3 end)
CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudLayerDefinition* layer, Vector3 start, Vector3 end)
{
CloudsWalker* result;
@ -160,7 +161,7 @@ static void _getPoint(CloudsWalker* walker, double cursor, CloudWalkerPoint* out
out_point->location = v3Add(walker->start, v3Scale(walker->diff, out_point->distance_from_start / walker->max_length));
Renderer* renderer = walker->last_segment.renderer;
CloudsLayerDefinition* layer = walker->last_segment.layer;
CloudLayerDefinition* layer = walker->last_segment.layer;
out_point->global_density = renderer->clouds->getLayerDensity(renderer, layer, out_point->location);
if (walker->local_density > 0 || (walker->local_density < 0 && walker->subdivision_count > 0))

View file

@ -22,7 +22,7 @@ typedef struct
typedef struct
{
Renderer* renderer;
CloudsLayerDefinition* layer;
CloudLayerDefinition* layer;
CloudWalkerPoint start;
CloudWalkerPoint end;
@ -46,7 +46,7 @@ typedef void (*FuncCloudsWalkingCallback)(CloudsWalker* walker);
* @param end End of the search to optimize
* @return 0 if the search is useless
*/
RENDERINGSHARED_EXPORT int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Vector3* end);
RENDERINGSHARED_EXPORT int cloudsOptimizeWalkingBounds(CloudLayerDefinition* layer, Vector3* start, Vector3* end);
/**
* Create a cloud walker.
@ -57,7 +57,7 @@ RENDERINGSHARED_EXPORT int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* la
* @param start Start of the walk
* @param end End of the walk
*/
RENDERINGSHARED_EXPORT CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 start, Vector3 end);
RENDERINGSHARED_EXPORT CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudLayerDefinition* layer, Vector3 start, Vector3 end);
/**
* Delete a cloud walker.

View file

@ -6,9 +6,9 @@
#define CLOUDS_MAX_LAYERS 6
#define MAX_SEGMENT_COUNT 100
void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition);
void cloudsLayerValidateDefinition(CloudLayerDefinition* definition);
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 cloudsLayerFilterLight(CloudLayerDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light);
Color cloudsApplyLayer(CloudLayerDefinition* definition, Color base, Renderer* renderer, Vector3 start, Vector3 end);
#endif

View file

@ -2,70 +2,15 @@
#define _PAYSAGES_CLOUDS_PUBLIC_H_
#include "../rendering_global.h"
#include "../shared/types.h"
#include "../tools/lighting.h"
#include "../tools/curve.h"
#include "../tools/euclid.h"
#include "Layers.h"
#include "SurfaceMaterial.h"
namespace paysages {
namespace basics {
class NoiseGenerator;
}
}
typedef enum
{
CLOUDS_TYPE_CIRRUS,
CLOUDS_TYPE_CUMULUS,
CLOUDS_TYPE_STRATOCUMULUS,
CLOUDS_TYPE_STRATUS
} CloudsType;
typedef enum
{
CLOUDS_PRESET_PARTLY_CLOUDY,
} CloudsPreset;
typedef enum
{
CLOUDS_LAYER_PRESET_CIRRUS,
CLOUDS_LAYER_PRESET_CUMULUS,
CLOUDS_LAYER_PRESET_STRATOCUMULUS,
CLOUDS_LAYER_PRESET_STRATUS
} CloudsLayerPreset;
typedef struct
{
CloudsType type;
double lower_altitude;
double thickness;
double base_coverage;
double shape_scaling;
double edge_scaling;
double edge_length;
SurfaceMaterial material;
double hardness;
double transparencydepth;
double lighttraversal;
double minimumlight;
Curve* _coverage_by_altitude;
NoiseGenerator* _coverage_noise;
NoiseGenerator* _shape_noise;
NoiseGenerator* _edge_noise;
} CloudsLayerDefinition;
class CloudsDefinition
{
public:
Layers* layers;
};
typedef Color (*FuncCloudsGetColor)(Renderer* renderer, Color base, Vector3 start, Vector3 end);
typedef double (*FuncCloudsGetLayerDensity)(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location);
typedef double (*FuncCloudsGetEdgeDensity)(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location, double layer_density);
typedef double (*FuncCloudsGetLayerDensity)(Renderer* renderer, CloudLayerDefinition* layer, Vector3 location);
typedef double (*FuncCloudsGetEdgeDensity)(Renderer* renderer, CloudLayerDefinition* layer, Vector3 location, double layer_density);
class CloudsRenderer
{
@ -79,11 +24,6 @@ public:
};
RENDERINGSHARED_EXPORT extern StandardDefinition CloudsDefinitionClass;
RENDERINGSHARED_EXPORT extern StandardRenderer CloudsRendererClass;
RENDERINGSHARED_EXPORT LayerType cloudsGetLayerType();
RENDERINGSHARED_EXPORT void cloudsAutoPreset(CloudsDefinition* definition, CloudsPreset preset);
RENDERINGSHARED_EXPORT void cloudsLayerAutoPreset(CloudsLayerDefinition* definition, CloudsLayerPreset preset);
#endif

View file

@ -22,9 +22,7 @@ SOURCES += main.cpp \
clouds/clo_walking.cpp \
clouds/clo_rendering.cpp \
clouds/clo_preview.cpp \
clouds/clo_presets.cpp \
clouds/clo_density.cpp \
clouds/clo_definition.cpp \
terrain/ter_render.cpp \
terrain/ter_raster.cpp \
terrain/ter_preview.cpp \
@ -43,7 +41,6 @@ SOURCES += main.cpp \
tools/lighting.cpp \
tools/euclid.cpp \
tools/data.cpp \
tools/curve.cpp \
tools/color.cpp \
tools/cache.cpp \
water/wat_render.cpp \
@ -80,7 +77,6 @@ HEADERS += \
tools/lighting.h \
tools/euclid.h \
tools/data.h \
tools/curve.h \
tools/color.h \
tools/cache.h \
water/public.h \

View file

@ -1,11 +1,11 @@
#include "color.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include "../tools.h"
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cmath>
#include "PackStream.h"
#include "Curve.h"
/******************************** ColorProfile ********************************/
class ColorProfile
@ -67,10 +67,8 @@ static Color _toneMappingReinhard(Color pixel, double exposure)
return pixel;
}
static Color _toneMappingClamp(Color pixel, double exposure)
static Color _toneMappingClamp(Color pixel, double)
{
UNUSED(exposure);
pixel.r = pixel.r > 1.0 ? 1.0 : pixel.r;
pixel.g = pixel.g > 1.0 ? 1.0 : pixel.g;
pixel.b = pixel.b > 1.0 ? 1.0 : pixel.b;
@ -146,80 +144,80 @@ ColorGradation* colorGradationCreate()
ColorGradation* result;
result = new ColorGradation;
result->red = curveCreate();
result->green = curveCreate();
result->blue = curveCreate();
result->red = new Curve;
result->green = new Curve;
result->blue = new Curve;
return result;
}
void colorGradationDelete(ColorGradation* gradation)
{
curveDelete(gradation->red);
curveDelete(gradation->green);
curveDelete(gradation->blue);
delete gradation->red;
delete gradation->green;
delete gradation->blue;
delete gradation;
}
void colorGradationCopy(ColorGradation* source, ColorGradation* destination)
{
curveCopy(source->red, destination->red);
curveCopy(source->green, destination->green);
curveCopy(source->blue, destination->blue);
source->red->copy(destination->red);
source->green->copy(destination->green);
source->blue->copy(destination->blue);
}
void colorGradationClear(ColorGradation* gradation)
{
curveClear(gradation->red);
curveClear(gradation->green);
curveClear(gradation->blue);
gradation->red->clear();
gradation->green->clear();
gradation->blue->clear();
}
void colorGradationSave(PackStream* stream, ColorGradation* gradation)
{
curveSave(stream, gradation->red);
curveSave(stream, gradation->green);
curveSave(stream, gradation->blue);
gradation->red->save(stream);
gradation->green->save(stream);
gradation->blue->save(stream);
}
void colorGradationLoad(PackStream* stream, ColorGradation* gradation)
{
curveLoad(stream, gradation->red);
curveLoad(stream, gradation->green);
curveLoad(stream, gradation->blue);
gradation->red->load(stream);
gradation->green->load(stream);
gradation->blue->load(stream);
}
void colorGradationGetRedCurve(ColorGradation* gradation, Curve* curve)
{
curveCopy(gradation->red, curve);
gradation->red->copy(curve);
}
void colorGradationGetGreenCurve(ColorGradation* gradation, Curve* curve)
{
curveCopy(gradation->green, curve);
gradation->green->copy(curve);
}
void colorGradationGetBlueCurve(ColorGradation* gradation, Curve* curve)
{
curveCopy(gradation->blue, curve);
gradation->blue->copy(curve);
}
void colorGradationSetRedCurve(ColorGradation* gradation, Curve* curve)
{
curveCopy(curve, gradation->red);
curveValidate(gradation->red);
curve->copy(gradation->red);
gradation->red->validate();
}
void colorGradationSetGreenCurve(ColorGradation* gradation, Curve* curve)
{
curveCopy(curve, gradation->green);
curveValidate(gradation->green);
curve->copy(gradation->green);
gradation->green->validate();
}
void colorGradationSetBlueCurve(ColorGradation* gradation, Curve* curve)
{
curveCopy(curve, gradation->blue);
curveValidate(gradation->blue);
curve->copy(gradation->blue);
gradation->blue->validate();
}
void colorGradationQuickAdd(ColorGradation* gradation, double value, Color* col)
@ -229,23 +227,23 @@ void colorGradationQuickAdd(ColorGradation* gradation, double value, Color* col)
void colorGradationQuickAddRgb(ColorGradation* gradation, double value, double r, double g, double b)
{
curveQuickAddPoint(gradation->red, value, r);
curveValidate(gradation->red);
gradation->red->addPoint(value, r);
gradation->red->validate();
curveQuickAddPoint(gradation->green, value, g);
curveValidate(gradation->green);
gradation->green->addPoint(value, g);
gradation->green->validate();
curveQuickAddPoint(gradation->blue, value, b);
curveValidate(gradation->blue);
gradation->blue->addPoint(value, b);
gradation->blue->validate();
}
Color colorGradationGet(ColorGradation* gradation, double value)
{
Color result;
result.r = curveGetValue(gradation->red, value);
result.g = curveGetValue(gradation->green, value);
result.b = curveGetValue(gradation->blue, value);
result.r = gradation->red->getValue(value);
result.g = gradation->green->getValue(value);
result.b = gradation->blue->getValue(value);
result.a = 1.0;
return result;

View file

@ -2,7 +2,6 @@
#define _PAYSAGES_TOOLS_COLOR_H_
#include "../rendering_global.h"
#include "curve.h"
/* HDR profile for tone-mapping */
class ColorProfile;

View file

@ -1,179 +0,0 @@
#include "curve.h"
#include <stdlib.h>
#include <string.h>
#include "../tools.h"
#include "PackStream.h"
#define MAX_NB_POINTS 40
struct Curve
{
double default_value;
int nbpoints;
CurvePoint points[MAX_NB_POINTS];
};
Curve* curveCreate()
{
Curve* result;
result = new Curve;
result->nbpoints = 0;
result->default_value = 0.0;
return result;
}
void curveDelete(Curve* curve)
{
delete curve;
}
void curveCopy(Curve* source, Curve* destination)
{
*destination = *source;
}
void curveSave(PackStream* stream, Curve* curve)
{
int i;
stream->write(&curve->default_value);
stream->write(&curve->nbpoints);
for (i = 0; i < curve->nbpoints; i++)
{
stream->write(&curve->points[i].position);
stream->write(&curve->points[i].value);
}
}
void curveLoad(PackStream* stream, Curve* curve)
{
int i;
stream->read(&curve->default_value);
stream->read(&curve->nbpoints);
for (i = 0; i < curve->nbpoints; i++)
{
stream->read(&curve->points[i].position);
stream->read(&curve->points[i].value);
}
}
void curveClear(Curve* curve)
{
curve->nbpoints = 0;
}
void curveSetDefault(Curve* curve, double value)
{
curve->default_value = value;
}
int curveAddPoint(Curve* curve, CurvePoint* point)
{
if (curve->nbpoints < MAX_NB_POINTS)
{
curve->points[curve->nbpoints] = *point;
return curve->nbpoints++;
}
else
{
return -1;
}
}
int curveQuickAddPoint(Curve* curve, double position, double value)
{
CurvePoint point;
point.position = position;
point.value = value;
return curveAddPoint(curve, &point);
}
int curveGetPointCount(Curve* curve)
{
return curve->nbpoints;
}
void curveGetPoint(Curve* curve, int number, CurvePoint* point)
{
if (number >= 0 && number < curve->nbpoints)
{
*point = curve->points[number];
}
}
void curveSetPoint(Curve* curve, int number, CurvePoint* point)
{
if (number >= 0 && number < curve->nbpoints)
{
curve->points[number] = *point;
}
}
void curveRemovePoint(Curve* curve, int number)
{
if (number >= 0 && number < curve->nbpoints)
{
if (curve->nbpoints > 0 && number < curve->nbpoints - 1)
{
memmove(curve->points + number, curve->points + number + 1, sizeof(CurvePoint) * (curve->nbpoints - number - 1));
}
curve->nbpoints--;
}
}
int _point_compare(const void* part1, const void* part2)
{
if (((CurvePoint*)part1)->position > ((CurvePoint*)part2)->position)
{
return 1;
}
else
{
return -1;
}
}
void curveValidate(Curve* curve)
{
if (curve->nbpoints > 1)
{
qsort(curve->points, curve->nbpoints, sizeof(CurvePoint), _point_compare);
}
}
double curveGetValue(Curve* curve, double position)
{
int i;
double fact;
if (curve->nbpoints == 0)
{
return curve->default_value;
}
else if (curve->nbpoints == 1 || position <= curve->points[0].position)
{
return curve->points[0].value;
}
else if (position >= curve->points[curve->nbpoints - 1].position)
{
return curve->points[curve->nbpoints - 1].value;
}
else
{
for (i = 1; i < curve->nbpoints; i++)
{
if (position < curve->points[i].position)
{
fact = (position - curve->points[i - 1].position) / (curve->points[i].position - curve->points[i - 1].position);
return curve->points[i - 1].value + (curve->points[i].value - curve->points[i - 1].value) * fact;
}
}
return curve->points[curve->nbpoints - 1].value;
}
}

View file

@ -1,35 +0,0 @@
#ifndef _PAYSAGES_TOOLS_CURVE_H_
#define _PAYSAGES_TOOLS_CURVE_H_
#include "../rendering_global.h"
namespace paysages {
namespace system {class PackStream;}
}
typedef struct {
double position;
double value;
} CurvePoint;
typedef struct Curve Curve;
RENDERINGSHARED_EXPORT Curve* curveCreate();
RENDERINGSHARED_EXPORT void curveDelete(Curve* curve);
RENDERINGSHARED_EXPORT void curveCopy(Curve* source, Curve* destination);
RENDERINGSHARED_EXPORT void curveSave(PackStream* stream, Curve* curve);
RENDERINGSHARED_EXPORT void curveLoad(PackStream* stream, Curve* curve);
RENDERINGSHARED_EXPORT void curveClear(Curve* curve);
RENDERINGSHARED_EXPORT void curveSetDefault(Curve* curve, double value);
RENDERINGSHARED_EXPORT int curveAddPoint(Curve* curve, CurvePoint* point);
RENDERINGSHARED_EXPORT int curveQuickAddPoint(Curve* curve, double position, double value);
RENDERINGSHARED_EXPORT int curveGetPointCount(Curve* curve);
RENDERINGSHARED_EXPORT void curveGetPoint(Curve* curve, int number, CurvePoint* point);
RENDERINGSHARED_EXPORT void curveSetPoint(Curve* curve, int number, CurvePoint* point);
RENDERINGSHARED_EXPORT void curveRemovePoint(Curve* curve, int number);
RENDERINGSHARED_EXPORT void curveValidate(Curve* curve);
RENDERINGSHARED_EXPORT double curveGetValue(Curve* curve, double position);
#endif

View file

@ -4,6 +4,7 @@
#include <cstdlib>
#include <cmath>
#include "PackStream.h"
#include "Curve.h"
#include "tools.h"
#define MAX_CIRCLES 20
@ -35,11 +36,11 @@ Zone* zoneCreate()
Zone* result;
result = (Zone*)malloc(sizeof(Zone));
result->value_by_height = curveCreate();
result->value_by_height = new Curve;
result->absolute_height = 1;
curveSetDefault(result->value_by_height, 1.0);
result->value_by_slope = curveCreate();
curveSetDefault(result->value_by_slope, 1.0);
result->value_by_height->setDefault(1.0);
result->value_by_slope = new Curve;
result->value_by_slope->setDefault(1.0);
result->circles_included_count = 0;
return result;
@ -47,8 +48,8 @@ Zone* zoneCreate()
void zoneDelete(Zone* zone)
{
curveDelete(zone->value_by_height);
curveDelete(zone->value_by_slope);
delete zone->value_by_height;
delete zone->value_by_slope;
free(zone);
}
@ -61,8 +62,8 @@ void zoneSave(PackStream* stream, Zone* zone)
stream->write(&zone->relative_height_middle);
stream->write(&zone->relative_height_max);
curveSave(stream, zone->value_by_height);
curveSave(stream, zone->value_by_slope);
zone->value_by_height->save(stream);
zone->value_by_slope->save(stream);
stream->write(&zone->circles_included_count);
for (i = 0; i < zone->circles_included_count; i++)
@ -84,8 +85,8 @@ void zoneLoad(PackStream* stream, Zone* zone)
stream->read(&zone->relative_height_middle);
stream->read(&zone->relative_height_max);
curveLoad(stream, zone->value_by_height);
curveLoad(stream, zone->value_by_slope);
zone->value_by_height->load(stream);
zone->value_by_slope->load(stream);
stream->read(&zone->circles_included_count);
for (i = 0; i < zone->circles_included_count; i++)
@ -105,8 +106,8 @@ void zoneCopy(Zone* source, Zone* destination)
destination->relative_height_middle = source->relative_height_middle;
destination->relative_height_max = source->relative_height_max;
curveCopy(source->value_by_height, destination->value_by_height);
curveCopy(source->value_by_slope, destination->value_by_slope);
source->value_by_height->copy(destination->value_by_height);
source->value_by_slope->copy(destination->value_by_slope);
memcpy(destination->circles_included, source->circles_included, sizeof(Circle) * source->circles_included_count);
destination->circles_included_count = source->circles_included_count;
@ -114,8 +115,8 @@ void zoneCopy(Zone* source, Zone* destination)
void zoneClear(Zone* zone)
{
curveClear(zone->value_by_height);
curveClear(zone->value_by_slope);
zone->value_by_height->clear();
zone->value_by_slope->clear();
zone->circles_included_count = 0;
}
@ -157,38 +158,38 @@ void zoneIncludeCircleArea(Zone* zone, double value, double centerx, double cent
void zoneGetHeightCurve(Zone* zone, Curve* curve)
{
curveCopy(zone->value_by_height, curve);
zone->value_by_height->copy(curve);
}
void zoneSetHeightCurve(Zone* zone, Curve* curve)
{
curveCopy(curve, zone->value_by_height);
curve->copy(zone->value_by_height);
}
void zoneAddHeightRangeQuick(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax)
{
curveQuickAddPoint(zone->value_by_height, hardmin, 0.0);
curveQuickAddPoint(zone->value_by_height, softmin, value);
curveQuickAddPoint(zone->value_by_height, softmax, value);
curveQuickAddPoint(zone->value_by_height, hardmax, 0.0);
zone->value_by_height->addPoint(hardmin, 0.0);
zone->value_by_height->addPoint(softmin, value);
zone->value_by_height->addPoint(softmax, value);
zone->value_by_height->addPoint(hardmax, 0.0);
}
void zoneGetSlopeCurve(Zone* zone, Curve* curve)
{
curveCopy(zone->value_by_slope, curve);
zone->value_by_slope->copy(curve);
}
void zoneSetSlopeCurve(Zone* zone, Curve* curve)
{
curveCopy(curve, zone->value_by_slope);
curve->copy(zone->value_by_slope);
}
void zoneAddSlopeRangeQuick(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax)
{
curveQuickAddPoint(zone->value_by_slope, hardmin, 0.0);
curveQuickAddPoint(zone->value_by_slope, softmin, value);
curveQuickAddPoint(zone->value_by_slope, softmax, value);
curveQuickAddPoint(zone->value_by_slope, hardmax, 0.0);
zone->value_by_slope->addPoint(hardmin, 0.0);
zone->value_by_slope->addPoint(softmin, value);
zone->value_by_slope->addPoint(softmax, value);
zone->value_by_slope->addPoint(hardmax, 0.0);
}
static inline double _getCircleInfluence(Circle circle, Vector3 position)
@ -260,8 +261,8 @@ double zoneGetValue(Zone* zone, Vector3 location, Vector3 normal)
}
}
value_height = curveGetValue(zone->value_by_height, final_height);
value_steepness = curveGetValue(zone->value_by_slope, (1.0 - normal.y));
value_height = zone->value_by_height->getValue(final_height);
value_steepness = zone->value_by_slope->getValue(1.0 - normal.y);
if (value_steepness < value_height)
{

View file

@ -7,13 +7,6 @@
#include "../rendering_global.h"
#include "../tools/euclid.h"
#include "../tools/curve.h"
namespace paysages {
namespace system {
class PackStream;
}
}
typedef struct Zone Zone;

View file

@ -4,7 +4,6 @@
#include "../rendering_global.h"
#include "../shared/types.h"
#include "../tools/lighting.h"
#include "../tools/curve.h"
#include "../tools/euclid.h"
typedef struct

View file

@ -5,14 +5,14 @@
#include "clouds/public.h"
#include "clouds/clo_density.h"
#include "clouds/clo_walking.h"
#include "CloudLayerDefinition.h"
#include "NoiseGenerator.h"
TEST(Clouds, Density)
{
/* Setup */
double x, y, z;
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
CloudLayerDefinition layer(NULL);
/* Test default coverage (empty) */
for (x = -10.0; x < 10.0; x += 10.0)
@ -21,109 +21,105 @@ TEST(Clouds, Density)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, y, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, y, z)), 0.0);
}
}
}
/* Test coverage by altitude */
layer->base_coverage = 1.0;
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
layer->base_coverage = 1.0;
layer->_coverage_noise->forceValue(1.0);
layer.base_coverage = 1.0;
layer.lower_altitude = -1.0;
layer.thickness = 2.0;
layer.validate();
layer.base_coverage = 1.0;
layer._coverage_noise->forceValue(1.0);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 1.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 0.0, z)), 1.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 0.5, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -0.5, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -1.5, z)), 0.0);
}
}
layer->base_coverage = 0.5;
layer->_coverage_noise->forceValue(1.0);
layer.base_coverage = 0.5;
layer._coverage_noise->forceValue(1.0);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 0.0, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -1.5, z)), 0.0);
}
}
layer->base_coverage = 1.0;
layer->_coverage_noise->forceValue(0.5);
layer.base_coverage = 1.0;
layer._coverage_noise->forceValue(0.5);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 0.0, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(&layer, v3(x, -1.5, z)), 0.0);
}
}
/* TODO Test fake renderer */
/* TODO Test real renderer */
/* Teardown */
cloudsGetLayerType().callback_delete(layer);
}
TEST(Clouds, WalkingBoundaries)
{
Vector3 start, end;
int result;
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
layer->base_coverage = 1.0;
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
CloudLayerDefinition layer(NULL);
layer.base_coverage = 1.0;
layer.lower_altitude = -1.0;
layer.thickness = 2.0;
layer.validate();
/* Basic cases */
start = v3(0.0, -3.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, 3.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, -1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 1.0, 0.0);
start = v3(0.0, 0.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 0.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 1.0, 0.0);
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, -1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 0.0, 0.0);
@ -131,31 +127,31 @@ TEST(Clouds, WalkingBoundaries)
/* Basic cases (inverted) */
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, -3.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 3.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, -1.0, 0.0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 0.0, 0.0);
start = v3(0.0, 0.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 0.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, -1.0, 0.0);
@ -163,41 +159,39 @@ TEST(Clouds, WalkingBoundaries)
/* Horizontal cases */
start = v3(0.0, 2.0, 0.0);
end = v3(10.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 1.00001, 0.0);
end = v3(10.0, 1.00001, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, -1.00001, 0.0);
end = v3(10.0, -1.00001, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, -2.0, 0.0);
end = v3(10.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 0.0, 0.0);
end = v3(10.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
result = cloudsOptimizeWalkingBounds(&layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 0.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 10.0, 0.0, 0.0);
cloudsGetLayerType().callback_delete(layer);
}
static double _getLayerDensitySinX(Renderer*, CloudsLayerDefinition*, Vector3 location)
static double _getLayerDensitySinX(Renderer*, CloudLayerDefinition*, Vector3 location)
{
double density = sin(location.x * (2.0 * M_PI));
return (density > 0.0) ? density : 0.0;
}
static double _getEdgeDensitySquared(Renderer*, CloudsLayerDefinition*, Vector3, double edge_density)
static double _getEdgeDensitySquared(Renderer*, CloudLayerDefinition*, Vector3, double edge_density)
{
return edge_density * edge_density;
}
@ -205,11 +199,10 @@ static double _getEdgeDensitySquared(Renderer*, CloudsLayerDefinition*, Vector3,
TEST(Clouds, Walking)
{
/* Init */
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
CloudLayerDefinition layer(NULL);
layer.lower_altitude = -1.0;
layer.thickness = 2.0;
layer.validate();
Renderer* renderer;
renderer = rendererCreate();
@ -217,7 +210,7 @@ TEST(Clouds, Walking)
renderer->render_quality = 8;
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(-0.4, 0.0, 0.0), v3(1.75, 0.0, 0.0));
CloudsWalker* walker = cloudsCreateWalker(renderer, &layer, v3(-0.4, 0.0, 0.0), v3(1.75, 0.0, 0.0));
CloudWalkerStepInfo* segment;
int result;
@ -411,18 +404,16 @@ TEST(Clouds, Walking)
/* Clean up */
cloudsDeleteWalker(walker);
cloudsGetLayerType().callback_delete(layer);
rendererDelete(renderer);
}
TEST(Clouds, WalkingLocal)
{
/* Init */
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
CloudLayerDefinition layer(NULL);
layer.lower_altitude = -1.0;
layer.thickness = 2.0;
layer.validate();
Renderer* renderer;
renderer = rendererCreate();
@ -431,7 +422,7 @@ TEST(Clouds, WalkingLocal)
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
renderer->clouds->getEdgeDensity = _getEdgeDensitySquared;
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(0.0, 0.0, 0.0), v3(1.0, 0.0, 0.0));
CloudsWalker* walker = cloudsCreateWalker(renderer, &layer, v3(0.0, 0.0, 0.0), v3(1.0, 0.0, 0.0));
CloudWalkerStepInfo* segment;
int result;