paysages : Big terrain refactoring for future sculpt mode (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@475 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
de719c62dd
commit
5f22647b1c
44 changed files with 884 additions and 1389 deletions
|
@ -8,7 +8,6 @@
|
||||||
#include "inputnoise.h"
|
#include "inputnoise.h"
|
||||||
#include "inputcurve.h"
|
#include "inputcurve.h"
|
||||||
#include "inputmaterial.h"
|
#include "inputmaterial.h"
|
||||||
#include "inputheightmap.h"
|
|
||||||
#include "inputenum.h"
|
#include "inputenum.h"
|
||||||
#include "inputlayers.h"
|
#include "inputlayers.h"
|
||||||
|
|
||||||
|
@ -28,14 +27,14 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
this->_with_layers = with_layers;
|
this->_with_layers = with_layers;
|
||||||
|
|
||||||
setLayout(new QHBoxLayout());
|
setLayout(new QHBoxLayout());
|
||||||
|
|
||||||
control = new QWidget(this);
|
control = new QWidget(this);
|
||||||
control->setLayout(new QVBoxLayout());
|
control->setLayout(new QVBoxLayout());
|
||||||
control->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
control->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||||
layout()->addWidget(control);
|
layout()->addWidget(control);
|
||||||
|
|
||||||
_layer_count = 0;
|
_layer_count = 0;
|
||||||
|
|
||||||
if (with_layers)
|
if (with_layers)
|
||||||
{
|
{
|
||||||
layers = new QWidget(this);
|
layers = new QWidget(this);
|
||||||
|
@ -45,7 +44,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
label = new QLabel(tr("Layers : "), layers);
|
label = new QLabel(tr("Layers : "), layers);
|
||||||
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
layers->layout()->addWidget(label);
|
layers->layout()->addWidget(label);
|
||||||
|
|
||||||
_layer_list = new QComboBox(layers);
|
_layer_list = new QComboBox(layers);
|
||||||
layers->layout()->addWidget(_layer_list);
|
layers->layout()->addWidget(_layer_list);
|
||||||
QObject::connect(_layer_list, SIGNAL(currentIndexChanged(int)), this, SLOT(layerListChanged()));
|
QObject::connect(_layer_list, SIGNAL(currentIndexChanged(int)), this, SLOT(layerListChanged()));
|
||||||
|
@ -55,7 +54,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
_layer_new->setMaximumSize(30, 30);
|
_layer_new->setMaximumSize(30, 30);
|
||||||
layers->layout()->addWidget(_layer_new);
|
layers->layout()->addWidget(_layer_new);
|
||||||
QObject::connect(_layer_new, SIGNAL(clicked()), this, SLOT(layerAddClicked()));
|
QObject::connect(_layer_new, SIGNAL(clicked()), this, SLOT(layerAddClicked()));
|
||||||
|
|
||||||
_layer_del = new QPushButton(QIcon("images/layer_del.png"), "", layers);
|
_layer_del = new QPushButton(QIcon("images/layer_del.png"), "", layers);
|
||||||
_layer_del->setToolTip(tr("Delete layer"));
|
_layer_del->setToolTip(tr("Delete layer"));
|
||||||
_layer_del->setMaximumSize(30, 30);
|
_layer_del->setMaximumSize(30, 30);
|
||||||
|
@ -67,7 +66,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
_layer_rename->setMaximumSize(30, 30);
|
_layer_rename->setMaximumSize(30, 30);
|
||||||
layers->layout()->addWidget(_layer_rename);
|
layers->layout()->addWidget(_layer_rename);
|
||||||
QObject::connect(_layer_rename, SIGNAL(clicked()), this, SLOT(layerRenameClicked()));
|
QObject::connect(_layer_rename, SIGNAL(clicked()), this, SLOT(layerRenameClicked()));
|
||||||
|
|
||||||
_layer_up = new QPushButton(QIcon("images/layer_up.png"), "", layers);
|
_layer_up = new QPushButton(QIcon("images/layer_up.png"), "", layers);
|
||||||
_layer_up->setToolTip(tr("Move layer upward"));
|
_layer_up->setToolTip(tr("Move layer upward"));
|
||||||
_layer_up->setMaximumSize(30, 30);
|
_layer_up->setMaximumSize(30, 30);
|
||||||
|
@ -79,7 +78,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
_layer_down->setMaximumSize(30, 30);
|
_layer_down->setMaximumSize(30, 30);
|
||||||
layers->layout()->addWidget(_layer_down);
|
layers->layout()->addWidget(_layer_down);
|
||||||
QObject::connect(_layer_down, SIGNAL(clicked()), this, SLOT(layerDownClicked()));
|
QObject::connect(_layer_down, SIGNAL(clicked()), this, SLOT(layerDownClicked()));
|
||||||
|
|
||||||
control->layout()->addWidget(layers);
|
control->layout()->addWidget(layers);
|
||||||
control->layout()->setAlignment(_buttons, Qt::AlignTop);
|
control->layout()->setAlignment(_buttons, Qt::AlignTop);
|
||||||
}
|
}
|
||||||
|
@ -89,12 +88,12 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
_previews->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
_previews->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
layout()->addWidget(_previews);
|
layout()->addWidget(_previews);
|
||||||
layout()->setAlignment(_previews, Qt::AlignTop);
|
layout()->setAlignment(_previews, Qt::AlignTop);
|
||||||
|
|
||||||
_form = new QWidget(this);
|
_form = new QWidget(this);
|
||||||
_form->setLayout(new QHBoxLayout());
|
_form->setLayout(new QHBoxLayout());
|
||||||
control->layout()->addWidget(_form);
|
control->layout()->addWidget(_form);
|
||||||
control->layout()->setAlignment(_form, Qt::AlignTop);
|
control->layout()->setAlignment(_form, Qt::AlignTop);
|
||||||
|
|
||||||
_form_labels = new QWidget(_form);
|
_form_labels = new QWidget(_form);
|
||||||
_form_labels->setLayout(new QVBoxLayout());
|
_form_labels->setLayout(new QVBoxLayout());
|
||||||
_form->layout()->addWidget(_form_labels);
|
_form->layout()->addWidget(_form_labels);
|
||||||
|
@ -106,7 +105,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
_form_controls = new QWidget(_form);
|
_form_controls = new QWidget(_form);
|
||||||
_form_controls->setLayout(new QVBoxLayout());
|
_form_controls->setLayout(new QVBoxLayout());
|
||||||
_form->layout()->addWidget(_form_controls);
|
_form->layout()->addWidget(_form_controls);
|
||||||
|
|
||||||
_buttons = new QWidget(this);
|
_buttons = new QWidget(this);
|
||||||
_buttons->setLayout(new QHBoxLayout());
|
_buttons->setLayout(new QHBoxLayout());
|
||||||
control->layout()->addWidget(_buttons);
|
control->layout()->addWidget(_buttons);
|
||||||
|
@ -124,7 +123,7 @@ BaseForm::BaseForm(QWidget* parent, bool auto_apply, bool with_layers) : QWidget
|
||||||
_button_preset->setIcon(QIcon("images/auto.png"));
|
_button_preset->setIcon(QIcon("images/auto.png"));
|
||||||
_button_preset->hide();
|
_button_preset->hide();
|
||||||
connect(_button_preset, SIGNAL(clicked()), this, SLOT(presetChoiceClicked()));
|
connect(_button_preset, SIGNAL(clicked()), this, SLOT(presetChoiceClicked()));
|
||||||
|
|
||||||
_auto_update_previews = true;
|
_auto_update_previews = true;
|
||||||
|
|
||||||
if (auto_apply)
|
if (auto_apply)
|
||||||
|
@ -180,7 +179,7 @@ void BaseForm::configChangeEvent()
|
||||||
_inputs_list[i]->checkVisibility(true);
|
_inputs_list[i]->checkVisibility(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_auto_update_previews)
|
if (_auto_update_previews)
|
||||||
{
|
{
|
||||||
updatePreviews();
|
updatePreviews();
|
||||||
|
@ -203,7 +202,7 @@ void BaseForm::revertConfig()
|
||||||
{
|
{
|
||||||
_inputs_list[i]->revert();
|
_inputs_list[i]->revert();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_with_layers)
|
if (_with_layers)
|
||||||
{
|
{
|
||||||
rebuildLayerList();
|
rebuildLayerList();
|
||||||
|
@ -234,7 +233,7 @@ void BaseForm::rebuildLayerList()
|
||||||
{
|
{
|
||||||
int selected = _layer_list->currentIndex();
|
int selected = _layer_list->currentIndex();
|
||||||
_layer_list->clear();
|
_layer_list->clear();
|
||||||
|
|
||||||
_layer_names = getLayers();
|
_layer_names = getLayers();
|
||||||
_layer_count = _layer_names.count();
|
_layer_count = _layer_names.count();
|
||||||
|
|
||||||
|
@ -259,10 +258,10 @@ void BaseForm::rebuildLayerList()
|
||||||
void BaseForm::layerAddClicked()
|
void BaseForm::layerAddClicked()
|
||||||
{
|
{
|
||||||
layerAddedEvent();
|
layerAddedEvent();
|
||||||
|
|
||||||
rebuildLayerList();
|
rebuildLayerList();
|
||||||
_layer_list->setCurrentIndex(_layer_list->count() - 1);
|
_layer_list->setCurrentIndex(_layer_list->count() - 1);
|
||||||
|
|
||||||
_button_apply->setEnabled(true);
|
_button_apply->setEnabled(true);
|
||||||
_button_revert->setEnabled(true);
|
_button_revert->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -279,7 +278,7 @@ void BaseForm::layerDelClicked()
|
||||||
_button_revert->setEnabled(true);
|
_button_revert->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseForm::layerUpClicked()
|
void BaseForm::layerUpClicked()
|
||||||
{
|
{
|
||||||
if (_layer_list->currentIndex() < _layer_count - 1)
|
if (_layer_list->currentIndex() < _layer_count - 1)
|
||||||
|
@ -287,9 +286,9 @@ void BaseForm::layerUpClicked()
|
||||||
layerMovedEvent(_layer_list->currentIndex(), _layer_list->currentIndex() + 1);
|
layerMovedEvent(_layer_list->currentIndex(), _layer_list->currentIndex() + 1);
|
||||||
|
|
||||||
rebuildLayerList();
|
rebuildLayerList();
|
||||||
|
|
||||||
_layer_list->setCurrentIndex(_layer_list->currentIndex() + 1);
|
_layer_list->setCurrentIndex(_layer_list->currentIndex() + 1);
|
||||||
|
|
||||||
_button_apply->setEnabled(true);
|
_button_apply->setEnabled(true);
|
||||||
_button_revert->setEnabled(true);
|
_button_revert->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -329,9 +328,9 @@ void BaseForm::layerRenameClicked()
|
||||||
void BaseForm::layerListChanged()
|
void BaseForm::layerListChanged()
|
||||||
{
|
{
|
||||||
bool changed = _button_apply->isEnabled();
|
bool changed = _button_apply->isEnabled();
|
||||||
|
|
||||||
layerSelectedEvent(_layer_list->currentIndex());
|
layerSelectedEvent(_layer_list->currentIndex());
|
||||||
|
|
||||||
_button_apply->setEnabled(changed);
|
_button_apply->setEnabled(changed);
|
||||||
_button_revert->setEnabled(changed);
|
_button_revert->setEnabled(changed);
|
||||||
}
|
}
|
||||||
|
@ -340,7 +339,7 @@ void BaseForm::presetChoiceClicked()
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
QString item = QInputDialog::getItem(this, tr("Choose a preset"), tr("Preset settings : "), _preset_list, 0, false, &ok);
|
QString item = QInputDialog::getItem(this, tr("Choose a preset"), tr("Preset settings : "), _preset_list, 0, false, &ok);
|
||||||
|
|
||||||
if (ok && !item.isEmpty())
|
if (ok && !item.isEmpty())
|
||||||
{
|
{
|
||||||
int preset = _preset_list.indexOf(item);
|
int preset = _preset_list.indexOf(item);
|
||||||
|
@ -354,13 +353,13 @@ void BaseForm::presetChoiceClicked()
|
||||||
void BaseForm::addPreview(BasePreview* preview, QString label)
|
void BaseForm::addPreview(BasePreview* preview, QString label)
|
||||||
{
|
{
|
||||||
QLabel* label_widget;
|
QLabel* label_widget;
|
||||||
|
|
||||||
label_widget = new QLabel(label, _previews);
|
label_widget = new QLabel(label, _previews);
|
||||||
label_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
label_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
|
|
||||||
_previews->layout()->addWidget(label_widget);
|
_previews->layout()->addWidget(label_widget);
|
||||||
_previews->layout()->addWidget(preview);
|
_previews->layout()->addWidget(preview);
|
||||||
|
|
||||||
_previews_list.append(preview);
|
_previews_list.append(preview);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,19 +379,19 @@ void BaseForm::addAutoPreset(QString label)
|
||||||
BaseInput* BaseForm::addInput(BaseInput* input)
|
BaseInput* BaseForm::addInput(BaseInput* input)
|
||||||
{
|
{
|
||||||
int row_height = 30;
|
int row_height = 30;
|
||||||
|
|
||||||
_form_labels->layout()->addWidget(input->label());
|
_form_labels->layout()->addWidget(input->label());
|
||||||
_form_previews->layout()->addWidget(input->preview());
|
_form_previews->layout()->addWidget(input->preview());
|
||||||
_form_controls->layout()->addWidget(input->control());
|
_form_controls->layout()->addWidget(input->control());
|
||||||
|
|
||||||
input->label()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
input->label()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||||
input->label()->setMinimumSize(150, row_height);
|
input->label()->setMinimumSize(150, row_height);
|
||||||
input->label()->setMaximumSize(250, row_height);
|
input->label()->setMaximumSize(250, row_height);
|
||||||
|
|
||||||
input->preview()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
input->preview()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
input->preview()->setMinimumSize(100, row_height);
|
input->preview()->setMinimumSize(100, row_height);
|
||||||
input->preview()->setMaximumSize(250, row_height);
|
input->preview()->setMaximumSize(250, row_height);
|
||||||
|
|
||||||
input->control()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
input->control()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||||
input->control()->setMinimumSize(280, row_height);
|
input->control()->setMinimumSize(280, row_height);
|
||||||
input->control()->setMaximumSize(700, row_height);
|
input->control()->setMaximumSize(700, row_height);
|
||||||
|
@ -401,7 +400,7 @@ BaseInput* BaseForm::addInput(BaseInput* input)
|
||||||
|
|
||||||
_inputs_list.append(input);
|
_inputs_list.append(input);
|
||||||
input->revert();
|
input->revert();
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,11 +444,6 @@ BaseInput* BaseForm::addInputMaterial(QString label, SurfaceMaterial* material)
|
||||||
return addInput(new InputMaterial(_form, label, material));
|
return addInput(new InputMaterial(_form, label, material));
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseInput* BaseForm::addInputHeightMap(QString label, HeightMap* heightmap, TerrainCanvas* canvas)
|
|
||||||
{
|
|
||||||
return addInput(new InputHeightMap(_form, label, heightmap, canvas));
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseInput* BaseForm::addInputEnum(QString label, int* value, const QStringList& values)
|
BaseInput* BaseForm::addInputEnum(QString label, int* value, const QStringList& values)
|
||||||
{
|
{
|
||||||
return addInput(new InputEnum(_form, label, value, values));
|
return addInput(new InputEnum(_form, label, value, values));
|
||||||
|
@ -489,7 +483,7 @@ QStringList BaseForm::getLayers()
|
||||||
{
|
{
|
||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseForm::layerAddedEvent()
|
void BaseForm::layerAddedEvent()
|
||||||
{
|
{
|
||||||
rebuildLayerList();
|
rebuildLayerList();
|
||||||
|
@ -522,7 +516,7 @@ void BaseForm::layerSelectedEvent(int layer)
|
||||||
{
|
{
|
||||||
_previews_list[i]->redraw();
|
_previews_list[i]->redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
_layer_del->setEnabled(layer >= 0);
|
_layer_del->setEnabled(layer >= 0);
|
||||||
_layer_rename->setEnabled(layer >= 0);
|
_layer_rename->setEnabled(layer >= 0);
|
||||||
_layer_down->setEnabled(layer > 0);
|
_layer_down->setEnabled(layer > 0);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "../lib_paysages/layers.h"
|
#include "../lib_paysages/layers.h"
|
||||||
#include "../lib_paysages/heightmap.h"
|
#include "../lib_paysages/heightmap.h"
|
||||||
#include "../lib_paysages/pack.h"
|
#include "../lib_paysages/pack.h"
|
||||||
#include "../lib_paysages/terraincanvas.h"
|
|
||||||
|
|
||||||
class BaseForm:public QWidget
|
class BaseForm:public QWidget
|
||||||
{
|
{
|
||||||
|
@ -37,7 +36,7 @@ public slots:
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void configChangeEvent();
|
virtual void configChangeEvent();
|
||||||
virtual void autoPresetSelected(int preset);
|
virtual void autoPresetSelected(int preset);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void rebuildLayerList();
|
void rebuildLayerList();
|
||||||
void layerAddClicked();
|
void layerAddClicked();
|
||||||
|
@ -61,16 +60,15 @@ protected:
|
||||||
BaseInput* addInputNoise(QString label, NoiseGenerator* value);
|
BaseInput* addInputNoise(QString label, NoiseGenerator* value);
|
||||||
BaseInput* addInputCurve(QString label, Curve* value, double xmin, double xmax, double ymin, double ymax, QString xlabel, QString ylabel);
|
BaseInput* addInputCurve(QString label, Curve* value, double xmin, double xmax, double ymin, double ymax, QString xlabel, QString ylabel);
|
||||||
BaseInput* addInputMaterial(QString label, SurfaceMaterial* material);
|
BaseInput* addInputMaterial(QString label, SurfaceMaterial* material);
|
||||||
BaseInput* addInputHeightMap(QString label, HeightMap* heightmap, TerrainCanvas* canvas);
|
|
||||||
BaseInput* addInputEnum(QString label, int* value, const QStringList& values);
|
BaseInput* addInputEnum(QString label, int* value, const QStringList& values);
|
||||||
BaseInput* addInputLayers(QString label, Layers* value, FormLayerBuilder form_builder);
|
BaseInput* addInputLayers(QString label, Layers* value, FormLayerBuilder form_builder);
|
||||||
|
|
||||||
void updatePreviews();
|
void updatePreviews();
|
||||||
void disablePreviewsUpdate();
|
void disablePreviewsUpdate();
|
||||||
|
|
||||||
int currentLayer();
|
int currentLayer();
|
||||||
virtual QStringList getLayers();
|
virtual QStringList getLayers();
|
||||||
|
|
||||||
virtual void layerAddedEvent();
|
virtual void layerAddedEvent();
|
||||||
virtual void layerDeletedEvent(int layer);
|
virtual void layerDeletedEvent(int layer);
|
||||||
virtual void layerMovedEvent(int layer, int new_position);
|
virtual void layerMovedEvent(int layer, int new_position);
|
||||||
|
@ -91,11 +89,11 @@ private:
|
||||||
QWidget* _previews;
|
QWidget* _previews;
|
||||||
QVector<BasePreview*> _previews_list;
|
QVector<BasePreview*> _previews_list;
|
||||||
bool _auto_update_previews;
|
bool _auto_update_previews;
|
||||||
|
|
||||||
QVector<BaseInput*> _inputs_list;
|
QVector<BaseInput*> _inputs_list;
|
||||||
|
|
||||||
QStringList _preset_list;
|
QStringList _preset_list;
|
||||||
|
|
||||||
bool _with_layers;
|
bool _with_layers;
|
||||||
QComboBox* _layer_list;
|
QComboBox* _layer_list;
|
||||||
int _layer_count;
|
int _layer_count;
|
||||||
|
|
|
@ -9,51 +9,49 @@
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "../lib_paysages/terrain.h"
|
|
||||||
#include "../lib_paysages/scenery.h"
|
#include "../lib_paysages/scenery.h"
|
||||||
#include "widgetheightmap.h"
|
#include "widgetheightmap.h"
|
||||||
|
|
||||||
/**************** Dialog form ****************/
|
/**************** Dialog form ****************/
|
||||||
DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas) : DialogWithPreview(parent)
|
DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas) : DialogWithPreview(parent)
|
||||||
{
|
{
|
||||||
QWidget* mainarea;
|
QWidget* mainarea;
|
||||||
QWidget* buttons;
|
QWidget* buttons;
|
||||||
QWidget* panel;
|
QWidget* panel;
|
||||||
QWidget* viewer;
|
QWidget* viewer;
|
||||||
QGridLayout* viewer_layout;
|
QGridLayout* viewer_layout;
|
||||||
|
|
||||||
QLabel* label;
|
QLabel* label;
|
||||||
QSlider* slider;
|
QSlider* slider;
|
||||||
QPushButton* button;
|
QPushButton* button;
|
||||||
QComboBox* combobox;
|
QComboBox* combobox;
|
||||||
|
|
||||||
_canvas = canvas;
|
|
||||||
_value_original = heightmap;
|
_value_original = heightmap;
|
||||||
_value_modified = heightmapCreate();
|
_value_modified = heightmapCreate();
|
||||||
heightmapCopy(_value_original, &_value_modified);
|
heightmapCopy(_value_original, &_value_modified);
|
||||||
setLayout(new QVBoxLayout());
|
setLayout(new QVBoxLayout());
|
||||||
|
|
||||||
// Dialog layout (main area + buttons)
|
// Dialog layout (main area + buttons)
|
||||||
mainarea = new QWidget(this);
|
mainarea = new QWidget(this);
|
||||||
mainarea->setLayout(new QHBoxLayout());
|
mainarea->setLayout(new QHBoxLayout());
|
||||||
this->layout()->addWidget(mainarea);
|
this->layout()->addWidget(mainarea);
|
||||||
|
|
||||||
buttons = new QWidget(this);
|
buttons = new QWidget(this);
|
||||||
buttons->setLayout(new QHBoxLayout());
|
buttons->setLayout(new QHBoxLayout());
|
||||||
buttons->layout()->setAlignment(buttons, Qt::AlignBottom);
|
buttons->layout()->setAlignment(buttons, Qt::AlignBottom);
|
||||||
this->layout()->addWidget(buttons);
|
this->layout()->addWidget(buttons);
|
||||||
|
|
||||||
// Main area layout (viewer + panel)
|
// Main area layout (viewer + panel)
|
||||||
viewer = new QWidget(mainarea);
|
viewer = new QWidget(mainarea);
|
||||||
viewer_layout = new QGridLayout();
|
viewer_layout = new QGridLayout();
|
||||||
viewer->setLayout(viewer_layout);
|
viewer->setLayout(viewer_layout);
|
||||||
mainarea->layout()->addWidget(viewer);
|
mainarea->layout()->addWidget(viewer);
|
||||||
|
|
||||||
panel = new QWidget(mainarea);
|
panel = new QWidget(mainarea);
|
||||||
panel->setLayout(new QVBoxLayout());
|
panel->setLayout(new QVBoxLayout());
|
||||||
mainarea->layout()->addWidget(panel);
|
mainarea->layout()->addWidget(panel);
|
||||||
mainarea->layout()->setAlignment(panel, Qt::AlignTop);
|
mainarea->layout()->setAlignment(panel, Qt::AlignTop);
|
||||||
|
|
||||||
// Viewer layout (3d display + sliders)
|
// Viewer layout (3d display + sliders)
|
||||||
_3dview = new WidgetHeightMap(viewer, &_value_modified);
|
_3dview = new WidgetHeightMap(viewer, &_value_modified);
|
||||||
viewer_layout->addWidget(_3dview, 0, 0);
|
viewer_layout->addWidget(_3dview, 0, 0);
|
||||||
|
@ -65,7 +63,7 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC
|
||||||
slider->setRange(-300, 700);
|
slider->setRange(-300, 700);
|
||||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(angleVChanged(int)));
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(angleVChanged(int)));
|
||||||
viewer_layout->addWidget(slider, 0, 1);
|
viewer_layout->addWidget(slider, 0, 1);
|
||||||
|
|
||||||
// Panel layout
|
// Panel layout
|
||||||
if (canvas)
|
if (canvas)
|
||||||
{
|
{
|
||||||
|
@ -81,20 +79,20 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC
|
||||||
button = new QPushButton(tr("Change resolution"), panel);
|
button = new QPushButton(tr("Change resolution"), panel);
|
||||||
connect(button, SIGNAL(clicked()), this, SLOT(changeResolution()));
|
connect(button, SIGNAL(clicked()), this, SLOT(changeResolution()));
|
||||||
panel->layout()->addWidget(button);
|
panel->layout()->addWidget(button);
|
||||||
|
|
||||||
_resolution_label = new QLabel("", panel);
|
_resolution_label = new QLabel("", panel);
|
||||||
panel->layout()->addWidget(_resolution_label);
|
panel->layout()->addWidget(_resolution_label);
|
||||||
updateResolutionLabel();
|
updateResolutionLabel();
|
||||||
|
|
||||||
combobox = new QComboBox(panel);
|
combobox = new QComboBox(panel);
|
||||||
combobox->addItem(tr("Raise / lower"));
|
combobox->addItem(tr("Raise / lower"));
|
||||||
combobox->addItem(tr("Add noise / smooth"));
|
combobox->addItem(tr("Add noise / smooth"));
|
||||||
connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(brushModeChanged(int)));
|
connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(brushModeChanged(int)));
|
||||||
panel->layout()->addWidget(combobox);
|
panel->layout()->addWidget(combobox);
|
||||||
|
|
||||||
label = new QLabel(tr("Brush size"), panel);
|
label = new QLabel(tr("Brush size"), panel);
|
||||||
panel->layout()->addWidget(label);
|
panel->layout()->addWidget(label);
|
||||||
|
|
||||||
slider = new QSlider(Qt::Horizontal, panel);
|
slider = new QSlider(Qt::Horizontal, panel);
|
||||||
slider->setRange(6, 300);
|
slider->setRange(6, 300);
|
||||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSizeChanged(int)));
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSizeChanged(int)));
|
||||||
|
@ -103,22 +101,22 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC
|
||||||
|
|
||||||
label = new QLabel(tr("Brush smoothing"), panel);
|
label = new QLabel(tr("Brush smoothing"), panel);
|
||||||
panel->layout()->addWidget(label);
|
panel->layout()->addWidget(label);
|
||||||
|
|
||||||
slider = new QSlider(Qt::Horizontal, panel);
|
slider = new QSlider(Qt::Horizontal, panel);
|
||||||
slider->setRange(0, 1000);
|
slider->setRange(0, 1000);
|
||||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSmoothingChanged(int)));
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSmoothingChanged(int)));
|
||||||
panel->layout()->addWidget(slider);
|
panel->layout()->addWidget(slider);
|
||||||
slider->setValue(600);
|
slider->setValue(600);
|
||||||
|
|
||||||
label = new QLabel(tr("Brush strength"), panel);
|
label = new QLabel(tr("Brush strength"), panel);
|
||||||
panel->layout()->addWidget(label);
|
panel->layout()->addWidget(label);
|
||||||
|
|
||||||
slider = new QSlider(Qt::Horizontal, panel);
|
slider = new QSlider(Qt::Horizontal, panel);
|
||||||
slider->setRange(0, 1000);
|
slider->setRange(0, 1000);
|
||||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushStrengthChanged(int)));
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushStrengthChanged(int)));
|
||||||
panel->layout()->addWidget(slider);
|
panel->layout()->addWidget(slider);
|
||||||
slider->setValue(200);
|
slider->setValue(200);
|
||||||
|
|
||||||
// Buttons layout
|
// Buttons layout
|
||||||
button = new QPushButton(tr("Cancel"), buttons);
|
button = new QPushButton(tr("Cancel"), buttons);
|
||||||
button->setIcon(QIcon("images/cancel.png"));
|
button->setIcon(QIcon("images/cancel.png"));
|
||||||
|
@ -138,7 +136,7 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainC
|
||||||
setWindowTitle(tr("Paysages 3D - Height map painting"));
|
setWindowTitle(tr("Paysages 3D - Height map painting"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogHeightMap::editHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas)
|
bool DialogHeightMap::editHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -206,7 +204,7 @@ void DialogHeightMap::loadFromFile()
|
||||||
|
|
||||||
void DialogHeightMap::resetToTerrain()
|
void DialogHeightMap::resetToTerrain()
|
||||||
{
|
{
|
||||||
if (_canvas)
|
/*if (_canvas)
|
||||||
{
|
{
|
||||||
TerrainDefinition terrain;
|
TerrainDefinition terrain;
|
||||||
|
|
||||||
|
@ -216,9 +214,9 @@ void DialogHeightMap::resetToTerrain()
|
||||||
heightmapRevertToTerrain(&_value_modified, &terrain, &_canvas->area);
|
heightmapRevertToTerrain(&_value_modified, &terrain, &_canvas->area);
|
||||||
|
|
||||||
terrainDeleteDefinition(&terrain);
|
terrainDeleteDefinition(&terrain);
|
||||||
|
|
||||||
_3dview->revert();
|
_3dview->revert();
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogHeightMap::changeResolution()
|
void DialogHeightMap::changeResolution()
|
||||||
|
@ -226,7 +224,7 @@ void DialogHeightMap::changeResolution()
|
||||||
QString result;
|
QString result;
|
||||||
QStringList items;
|
QStringList items;
|
||||||
int current;
|
int current;
|
||||||
|
|
||||||
items << QString("64 x 64") << QString("128 x 128") << QString("256 x 256") << QString("512 x 512");
|
items << QString("64 x 64") << QString("128 x 128") << QString("256 x 256") << QString("512 x 512");
|
||||||
current = 1;
|
current = 1;
|
||||||
if (_value_modified.resolution_x == 64 && _value_modified.resolution_z == 64)
|
if (_value_modified.resolution_x == 64 && _value_modified.resolution_z == 64)
|
||||||
|
@ -261,7 +259,7 @@ void DialogHeightMap::changeResolution()
|
||||||
{
|
{
|
||||||
new_res_x = new_res_z = 128;
|
new_res_x = new_res_z = 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_res_x != _value_modified.resolution_x or new_res_z != _value_modified.resolution_z)
|
if (new_res_x != _value_modified.resolution_x or new_res_z != _value_modified.resolution_z)
|
||||||
{
|
{
|
||||||
heightmapChangeResolution(&_value_modified, new_res_x, new_res_z);
|
heightmapChangeResolution(&_value_modified, new_res_x, new_res_z);
|
||||||
|
|
|
@ -5,19 +5,18 @@
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "widgetheightmap.h"
|
#include "widgetheightmap.h"
|
||||||
#include "../lib_paysages/heightmap.h"
|
#include "../lib_paysages/heightmap.h"
|
||||||
#include "../lib_paysages/terraincanvas.h"
|
|
||||||
|
|
||||||
class DialogHeightMap : public DialogWithPreview
|
class DialogHeightMap : public DialogWithPreview
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit DialogHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas);
|
explicit DialogHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas);
|
||||||
static bool editHeightMap(QWidget* parent, HeightMap* heightmap, TerrainCanvas* canvas);
|
static bool editHeightMap(QWidget* parent, HeightMap* heightmap, void* canvas);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void accept();
|
virtual void accept();
|
||||||
void revert();
|
void revert();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void angleHChanged(int value);
|
void angleHChanged(int value);
|
||||||
void angleVChanged(int value);
|
void angleVChanged(int value);
|
||||||
|
@ -35,7 +34,6 @@ private:
|
||||||
HeightMap _value_modified;
|
HeightMap _value_modified;
|
||||||
WidgetHeightMap* _3dview;
|
WidgetHeightMap* _3dview;
|
||||||
QLabel* _resolution_label;
|
QLabel* _resolution_label;
|
||||||
TerrainCanvas* _canvas;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,14 +10,14 @@ ExplorerChunkTerrain::ExplorerChunkTerrain(Renderer* renderer, double x, double
|
||||||
_startz = z;
|
_startz = z;
|
||||||
_size = size;
|
_size = size;
|
||||||
_overall_step = size * (double)nbchunks;
|
_overall_step = size * (double)nbchunks;
|
||||||
|
|
||||||
_tessellation_max_size = 32;
|
_tessellation_max_size = 32;
|
||||||
_tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)];
|
_tessellation = new double[(_tessellation_max_size + 1) * (_tessellation_max_size + 1)];
|
||||||
_tessellation_current_size = 0;
|
_tessellation_current_size = 0;
|
||||||
_tessellation_step = _size / (double)_tessellation_max_size;
|
_tessellation_step = _size / (double)_tessellation_max_size;
|
||||||
|
|
||||||
setMaxTextureSize(128);
|
setMaxTextureSize(128);
|
||||||
|
|
||||||
maintain();
|
maintain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ void ExplorerChunkTerrain::onResetEvent()
|
||||||
bool ExplorerChunkTerrain::onMaintainEvent()
|
bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
{
|
{
|
||||||
Renderer* renderer = this->renderer();
|
Renderer* renderer = this->renderer();
|
||||||
|
|
||||||
// Improve heightmap resolution
|
// Improve heightmap resolution
|
||||||
if (_tessellation_current_size < _tessellation_max_size)
|
if (_tessellation_current_size < _tessellation_max_size)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,7 @@ bool ExplorerChunkTerrain::onMaintainEvent()
|
||||||
{
|
{
|
||||||
if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0)
|
if (_tessellation_current_size == 0 || i % old_tessellation_inc != 0 || j % old_tessellation_inc != 0)
|
||||||
{
|
{
|
||||||
double height = renderer->getTerrainHeight(renderer, _startx + _tessellation_step * (double)i, _startz + _tessellation_step * (double)j);
|
double height = renderer->terrain->getHeight(renderer, _startx + _tessellation_step * (double)i, _startz + _tessellation_step * (double)j);
|
||||||
_tessellation[j * (_tessellation_max_size + 1) + i] = height;
|
_tessellation[j * (_tessellation_max_size + 1) + i] = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ void ExplorerChunkTerrain::onRenderEvent(QGLWidget* widget)
|
||||||
int tessellation_size = _tessellation_current_size;
|
int tessellation_size = _tessellation_current_size;
|
||||||
double tsize = 1.0 / (double)_tessellation_max_size;
|
double tsize = 1.0 / (double)_tessellation_max_size;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
if (tessellation_size <= 1)
|
if (tessellation_size <= 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -149,10 +149,10 @@ Color ExplorerChunkTerrain::getTextureColor(double x, double y)
|
||||||
Vector3 ExplorerChunkTerrain::getCenter()
|
Vector3 ExplorerChunkTerrain::getCenter()
|
||||||
{
|
{
|
||||||
Vector3 result;
|
Vector3 result;
|
||||||
|
|
||||||
result.x = _startx + _size / 2.0;
|
result.x = _startx + _size / 2.0;
|
||||||
result.y = 0.0;
|
result.y = 0.0;
|
||||||
result.z = _startz + _size / 2.0;
|
result.z = _startz + _size / 2.0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,17 @@ public:
|
||||||
{
|
{
|
||||||
_renderer = rendererCreate();
|
_renderer = rendererCreate();
|
||||||
_renderer.applyTextures = _applyTextures;
|
_renderer.applyTextures = _applyTextures;
|
||||||
_renderer.getTerrainHeight = _getTerrainHeight;
|
|
||||||
_renderer.alterLight = _alterLight;
|
|
||||||
_renderer.getLightStatus = _getLightStatus;
|
_renderer.getLightStatus = _getLightStatus;
|
||||||
_renderer.camera_location.x = 0.0;
|
_renderer.camera_location.x = 0.0;
|
||||||
_renderer.camera_location.y = 50.0;
|
_renderer.camera_location.y = 50.0;
|
||||||
_renderer.camera_location.z = 0.0;
|
_renderer.camera_location.z = 0.0;
|
||||||
|
|
||||||
_terrain = terrainCreateDefinition();
|
|
||||||
_textures = texturesCreateDefinition();
|
_textures = texturesCreateDefinition();
|
||||||
_lighting = lightingCreateDefinition();
|
_lighting = lightingCreateDefinition();
|
||||||
_water = waterCreateDefinition();
|
_water = waterCreateDefinition();
|
||||||
|
|
||||||
_atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
|
_atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
|
||||||
|
_terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
|
||||||
|
|
||||||
_renderer.customData[0] = &_terrain;
|
_renderer.customData[0] = &_terrain;
|
||||||
_renderer.customData[1] = &_textures;
|
_renderer.customData[1] = &_textures;
|
||||||
|
@ -44,7 +43,7 @@ protected:
|
||||||
{
|
{
|
||||||
Vector3 down = {0.0, -1.0, 0.0};
|
Vector3 down = {0.0, -1.0, 0.0};
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
double height = terrainGetHeight(&_terrain, x, y);
|
double height = _renderer.terrain->getHeight(&_renderer, x, y);
|
||||||
|
|
||||||
if (height < _water.height)
|
if (height < _water.height)
|
||||||
{
|
{
|
||||||
|
@ -55,12 +54,14 @@ protected:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return colorToQColor(terrainGetColor(&_terrain, &_renderer, x, y, scaling));
|
location.x = x;
|
||||||
|
location.y = height;
|
||||||
|
location.z = y;
|
||||||
|
return colorToQColor(_renderer.terrain->getFinalColor(&_renderer, location, scaling));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
sceneryGetTerrain(&_terrain);
|
|
||||||
sceneryGetLighting(&_lighting);
|
sceneryGetLighting(&_lighting);
|
||||||
sceneryGetTextures(&_textures);
|
sceneryGetTextures(&_textures);
|
||||||
sceneryGetWater(&_water);
|
sceneryGetWater(&_water);
|
||||||
|
@ -68,30 +69,23 @@ protected:
|
||||||
sceneryGetAtmosphere(_atmosphere);
|
sceneryGetAtmosphere(_atmosphere);
|
||||||
AtmosphereRendererClass.bind(_renderer.atmosphere, _atmosphere);
|
AtmosphereRendererClass.bind(_renderer.atmosphere, _atmosphere);
|
||||||
_renderer.atmosphere->applyAerialPerspective = _applyAerialPerspective;
|
_renderer.atmosphere->applyAerialPerspective = _applyAerialPerspective;
|
||||||
|
|
||||||
|
sceneryGetTerrain(_terrain);
|
||||||
|
TerrainRendererClass.bind(_renderer.terrain, _terrain);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Renderer _renderer;
|
Renderer _renderer;
|
||||||
TerrainDefinition _terrain;
|
TerrainDefinition* _terrain;
|
||||||
WaterDefinition _water;
|
WaterDefinition _water;
|
||||||
TexturesDefinition _textures;
|
TexturesDefinition _textures;
|
||||||
LightingDefinition _lighting;
|
LightingDefinition _lighting;
|
||||||
AtmosphereDefinition* _atmosphere;
|
AtmosphereDefinition* _atmosphere;
|
||||||
|
|
||||||
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
|
||||||
{
|
|
||||||
return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
||||||
{
|
{
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
|
||||||
{
|
|
||||||
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location)
|
static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location)
|
||||||
{
|
{
|
||||||
lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status);
|
lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status);
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include "formterraincanvas.h"
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#include "../lib_paysages/terrain.h"
|
|
||||||
#include "../lib_paysages/scenery.h"
|
#include "../lib_paysages/scenery.h"
|
||||||
#include "../lib_paysages/euclid.h"
|
#include "../lib_paysages/euclid.h"
|
||||||
|
|
||||||
static TerrainDefinition _definition;
|
static TerrainDefinition* _definition;
|
||||||
|
|
||||||
/**************** Previews ****************/
|
/**************** Previews ****************/
|
||||||
class PreviewTerrainHeight:public BasePreview
|
class PreviewTerrainHeight:public BasePreview
|
||||||
|
@ -18,27 +16,28 @@ class PreviewTerrainHeight:public BasePreview
|
||||||
public:
|
public:
|
||||||
PreviewTerrainHeight(QWidget* parent):BasePreview(parent)
|
PreviewTerrainHeight(QWidget* parent):BasePreview(parent)
|
||||||
{
|
{
|
||||||
_preview_definition = terrainCreateDefinition();
|
_renderer = rendererCreate();
|
||||||
|
|
||||||
addOsd(QString("geolocation"));
|
addOsd(QString("geolocation"));
|
||||||
|
|
||||||
configScaling(0.5, 200.0, 3.0, 50.0);
|
configScaling(0.5, 200.0, 3.0, 50.0);
|
||||||
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
QColor getColor(double x, double y)
|
QColor getColor(double x, double y)
|
||||||
{
|
{
|
||||||
double height;
|
double height = 0.0;
|
||||||
|
|
||||||
height = terrainGetHeightNormalized(&_preview_definition, x, y);
|
// TODO
|
||||||
|
//height = terrainGetHeightNormalized(&_preview_definition, x, y);
|
||||||
return QColor((int)(255.0 * height), (int)(255.0 * height), (int)(255.0 * height));
|
return QColor((int)(255.0 * height), (int)(255.0 * height), (int)(255.0 * height));
|
||||||
}
|
}
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
terrainCopyDefinition(&_definition, &_preview_definition);
|
TerrainRendererClass.bind(_renderer.terrain, _definition);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
TerrainDefinition _preview_definition;
|
Renderer _renderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreviewTerrainColor:public BasePreview
|
class PreviewTerrainColor:public BasePreview
|
||||||
|
@ -52,8 +51,6 @@ public:
|
||||||
_renderer = rendererCreate();
|
_renderer = rendererCreate();
|
||||||
_renderer.render_quality = 3;
|
_renderer.render_quality = 3;
|
||||||
_renderer.applyTextures = _applyTextures;
|
_renderer.applyTextures = _applyTextures;
|
||||||
_renderer.getTerrainHeight = _getTerrainHeight;
|
|
||||||
_renderer.alterLight = _alterLight;
|
|
||||||
_renderer.getLightStatus = _getLightStatus;
|
_renderer.getLightStatus = _getLightStatus;
|
||||||
_renderer.camera_location.x = 0.0;
|
_renderer.camera_location.x = 0.0;
|
||||||
_renderer.camera_location.y = 50.0;
|
_renderer.camera_location.y = 50.0;
|
||||||
|
@ -83,7 +80,6 @@ public:
|
||||||
lightingAddLight(&_lighting, light);
|
lightingAddLight(&_lighting, light);
|
||||||
lightingValidateDefinition(&_lighting);
|
lightingValidateDefinition(&_lighting);
|
||||||
|
|
||||||
_terrain = terrainCreateDefinition();
|
|
||||||
_textures = texturesCreateDefinition();
|
_textures = texturesCreateDefinition();
|
||||||
texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL));
|
texture = (TextureLayerDefinition*)layersGetLayer(_textures.layers, layersAddLayer(_textures.layers, NULL));
|
||||||
texture->material.base = COLOR_WHITE;
|
texture->material.base = COLOR_WHITE;
|
||||||
|
@ -92,92 +88,80 @@ public:
|
||||||
texture->bump_height = 0.0;
|
texture->bump_height = 0.0;
|
||||||
texturesLayerValidateDefinition(texture);
|
texturesLayerValidateDefinition(texture);
|
||||||
|
|
||||||
_renderer.customData[0] = &_terrain;
|
|
||||||
_renderer.customData[1] = &_textures;
|
_renderer.customData[1] = &_textures;
|
||||||
_renderer.customData[2] = &_lighting;
|
_renderer.customData[2] = &_lighting;
|
||||||
|
|
||||||
addOsd(QString("geolocation"));
|
addOsd(QString("geolocation"));
|
||||||
|
|
||||||
configScaling(0.5, 200.0, 3.0, 50.0);
|
configScaling(0.5, 200.0, 3.0, 50.0);
|
||||||
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
QColor getColor(double x, double y)
|
QColor getColor(double x, double y)
|
||||||
{
|
{
|
||||||
return colorToQColor(terrainGetColor(&_terrain, &_renderer, x, y, scaling));
|
Vector3 point;
|
||||||
|
|
||||||
|
point.x = x;
|
||||||
|
point.y = _renderer.terrain->getHeight(&_renderer, x, y);
|
||||||
|
point.z = y;
|
||||||
|
|
||||||
|
return colorToQColor(_renderer.terrain->getFinalColor(&_renderer, point, scaling));
|
||||||
}
|
}
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
terrainCopyDefinition(&_definition, &_terrain);
|
TerrainRendererClass.bind(_renderer.terrain, _definition);
|
||||||
//sceneryGetTextures(&_textures);
|
//sceneryGetTextures(&_textures);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Renderer _renderer;
|
Renderer _renderer;
|
||||||
TerrainDefinition _terrain;
|
|
||||||
TexturesDefinition _textures;
|
TexturesDefinition _textures;
|
||||||
LightingDefinition _lighting;
|
LightingDefinition _lighting;
|
||||||
|
|
||||||
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
|
||||||
{
|
|
||||||
return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
||||||
{
|
{
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
|
||||||
{
|
|
||||||
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location)
|
static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location)
|
||||||
{
|
{
|
||||||
lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status);
|
lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************** Form ****************/
|
/**************** Form ****************/
|
||||||
static BaseFormLayer* _formBuilderCanvas(DialogLayers* parent, Layers* layers)
|
|
||||||
{
|
|
||||||
return new FormTerrainCanvas(parent, layers);
|
|
||||||
}
|
|
||||||
|
|
||||||
FormTerrain::FormTerrain(QWidget *parent):
|
FormTerrain::FormTerrain(QWidget *parent):
|
||||||
BaseForm(parent)
|
BaseForm(parent)
|
||||||
{
|
{
|
||||||
_definition = terrainCreateDefinition();
|
_definition = (TerrainDefinition*)TerrainDefinitionClass.create();
|
||||||
|
|
||||||
previewHeight = new PreviewTerrainHeight(this);
|
previewHeight = new PreviewTerrainHeight(this);
|
||||||
previewColor = new PreviewTerrainColor(this);
|
previewColor = new PreviewTerrainColor(this);
|
||||||
addPreview(previewHeight, tr("Height preview (normalized)"));
|
addPreview(previewHeight, tr("Height preview (normalized)"));
|
||||||
addPreview(previewColor, tr("Lighted preview (no texture)"));
|
addPreview(previewColor, tr("Lighted preview (no texture)"));
|
||||||
|
|
||||||
addInputNoise(tr("Noise"), _definition.height_noise);
|
//addInputNoise(tr("Noise"), _definition.height_noise);
|
||||||
addInputDouble(tr("Height"), &_definition.height_factor, 0.0, 20.0, 0.1, 1.0);
|
addInputDouble(tr("Height"), &_definition->height, 0.0, 20.0, 0.1, 1.0);
|
||||||
addInputDouble(tr("Scaling"), &_definition.scaling, 20.0, 200.0, 1.0, 10.0);
|
addInputDouble(tr("Scaling"), &_definition->scaling, 20.0, 200.0, 1.0, 10.0);
|
||||||
addInputDouble(tr("Shadow smoothing"), &_definition.shadow_smoothing, 0.0, 0.3, 0.003, 0.03);
|
addInputDouble(tr("Shadow smoothing"), &_definition->shadow_smoothing, 0.0, 0.3, 0.003, 0.03);
|
||||||
addInputLayers(tr("Canvases"), _definition.canvases, _formBuilderCanvas);
|
|
||||||
|
|
||||||
revertConfig();
|
revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormTerrain::revertConfig()
|
void FormTerrain::revertConfig()
|
||||||
{
|
{
|
||||||
sceneryGetTerrain(&_definition);
|
sceneryGetTerrain(_definition);
|
||||||
BaseForm::revertConfig();
|
BaseForm::revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormTerrain::applyConfig()
|
void FormTerrain::applyConfig()
|
||||||
{
|
{
|
||||||
scenerySetTerrain(&_definition);
|
scenerySetTerrain(_definition);
|
||||||
BaseForm::applyConfig();
|
BaseForm::applyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormTerrain::configChangeEvent()
|
void FormTerrain::configChangeEvent()
|
||||||
{
|
{
|
||||||
terrainValidateDefinition(&_definition);
|
TerrainDefinitionClass.validate(_definition);
|
||||||
BaseForm::configChangeEvent();
|
BaseForm::configChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
#include "formterraincanvas.h"
|
|
||||||
|
|
||||||
/**************** Form ****************/
|
|
||||||
class PreviewTerrainCanvasHeight:public BasePreview
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PreviewTerrainCanvasHeight(QWidget* parent, TerrainCanvas* canvas):BasePreview(parent)
|
|
||||||
{
|
|
||||||
_base_canvas = canvas;
|
|
||||||
_preview_canvas = terrainCanvasCreate();
|
|
||||||
|
|
||||||
//addOsd(QString("geolocation"));
|
|
||||||
|
|
||||||
configScaling(1.0, 1.0, 1.0, 1.0);
|
|
||||||
//configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
~PreviewTerrainCanvasHeight()
|
|
||||||
{
|
|
||||||
terrainCanvasDelete(_preview_canvas);
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
QColor getColor(double x, double y)
|
|
||||||
{
|
|
||||||
Color col, mask;
|
|
||||||
double height;
|
|
||||||
|
|
||||||
if (_max - _min < 0.000001)
|
|
||||||
{
|
|
||||||
return Qt::black;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
height = heightmapGetValue(&_preview_canvas->height_map, x + 0.5, y + 0.5);
|
|
||||||
col.r = col.g = col.b = (height - _min) / (_max - _min);
|
|
||||||
col.a = 1.0;
|
|
||||||
|
|
||||||
mask.r = 0.3;
|
|
||||||
mask.g = 0.0;
|
|
||||||
mask.b = 0.0;
|
|
||||||
mask.a = 1.0 - terrainCanvasGetMaskValue(_preview_canvas, x + 0.5, y + 0.5);
|
|
||||||
colorMask(&col, &mask);
|
|
||||||
|
|
||||||
return colorToQColor(col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void updateData()
|
|
||||||
{
|
|
||||||
terrainCanvasCopy(_base_canvas, _preview_canvas);
|
|
||||||
heightmapGetLimits(&_preview_canvas->height_map, &_min, &_max);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
TerrainCanvas* _base_canvas;
|
|
||||||
TerrainCanvas* _preview_canvas;
|
|
||||||
double _max, _min;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************** Form ****************/
|
|
||||||
FormTerrainCanvas::FormTerrainCanvas(QWidget *parent, Layers* layers):
|
|
||||||
BaseFormLayer(parent, layers)
|
|
||||||
{
|
|
||||||
_definition = terrainCanvasCreate();
|
|
||||||
|
|
||||||
// TODO Area
|
|
||||||
//addInputDouble(tr("Apply at height"), &_definition->offset_y, -20.0, 20.0, 0.1, 1.0);
|
|
||||||
addInputHeightMap(tr("Height map"), &_definition->height_map, _definition);
|
|
||||||
//addInputDouble(tr("Canvas height"), &_definition->height_factor, 0.0, 20.0, 0.1, 1.0);
|
|
||||||
addInputNoise(tr("Detail noise"), _definition->detail_noise);
|
|
||||||
addInputDouble(tr("Detail noise height"), &_definition->detail_height_factor, 0.0, 20.0, 0.1, 1.0);
|
|
||||||
addInputDouble(tr("Detail noise scaling"), &_definition->detail_scaling, 0.0, 20.0, 0.1, 1.0);
|
|
||||||
addInputEnum(tr("Mask shape"), &_definition->mask.mode, QStringList(tr("Square")) << tr("Circle"));
|
|
||||||
addInputDouble(tr("Mask smoothing"), &_definition->mask.smoothing, 0.0, 1.0, 0.01, 0.1);
|
|
||||||
|
|
||||||
_previewHeight = new PreviewTerrainCanvasHeight(this, _definition);
|
|
||||||
addPreview(_previewHeight, tr("Height preview (normalized)"));
|
|
||||||
|
|
||||||
revertConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
FormTerrainCanvas::~FormTerrainCanvas()
|
|
||||||
{
|
|
||||||
terrainCanvasDelete(_definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormTerrainCanvas::layerReadCurrentFrom(void* layer_definition)
|
|
||||||
{
|
|
||||||
terrainCanvasCopy((TerrainCanvas*)layer_definition, _definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormTerrainCanvas::layerWriteCurrentTo(void* layer_definition)
|
|
||||||
{
|
|
||||||
terrainCanvasCopy(_definition, (TerrainCanvas*)layer_definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormTerrainCanvas::afterLayerAdded(void* layer_definition)
|
|
||||||
{
|
|
||||||
terrainCanvasRevertToTerrain((TerrainCanvas*)layer_definition);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef _PAYSAGES_QT_FORMTERRAINCANVAS_H_
|
|
||||||
#define _PAYSAGES_QT_FORMTERRAINCANVAS_H_
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include "basepreview.h"
|
|
||||||
#include "baseformlayer.h"
|
|
||||||
#include "../lib_paysages/terraincanvas.h"
|
|
||||||
|
|
||||||
class FormTerrainCanvas : public BaseFormLayer
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
FormTerrainCanvas(QWidget* parent, Layers* layers);
|
|
||||||
~FormTerrainCanvas();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void layerReadCurrentFrom(void* layer_definition);
|
|
||||||
virtual void layerWriteCurrentTo(void* layer_definition);
|
|
||||||
virtual void afterLayerAdded(void* layer_definition);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TerrainCanvas* _definition;
|
|
||||||
BasePreview* _previewHeight;
|
|
||||||
BasePreview* _previewColor;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -17,12 +17,10 @@ class PreviewTexturesCoverage:public BasePreview
|
||||||
public:
|
public:
|
||||||
PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer):BasePreview(parent)
|
PreviewTexturesCoverage(QWidget* parent, TextureLayerDefinition* layer):BasePreview(parent)
|
||||||
{
|
{
|
||||||
_terrain = terrainCreateDefinition();
|
_terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
|
||||||
|
|
||||||
_renderer = rendererCreate();
|
_renderer = rendererCreate();
|
||||||
_renderer.render_quality = 3;
|
_renderer.render_quality = 3;
|
||||||
_renderer.getTerrainHeight = _getTerrainHeight;
|
|
||||||
_renderer.customData[0] = &_terrain;
|
|
||||||
|
|
||||||
_original_layer = layer;
|
_original_layer = layer;
|
||||||
_preview_layer = texturesLayerCreateDefinition();
|
_preview_layer = texturesLayerCreateDefinition();
|
||||||
|
@ -42,27 +40,24 @@ protected:
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
double coverage;
|
double coverage;
|
||||||
location.x = x;
|
location.x = x;
|
||||||
location.y = terrainGetHeight(&_terrain, x, y);
|
location.y = _renderer.terrain->getHeight(&_renderer, x, y);
|
||||||
location.z = y;
|
location.z = y;
|
||||||
coverage = texturesGetLayerCoverage(_preview_layer, &_renderer, location, this->scaling);
|
coverage = texturesGetLayerCoverage(_preview_layer, &_renderer, location, this->scaling);
|
||||||
return QColor::fromRgbF(coverage, coverage, coverage, 1.0);
|
return QColor::fromRgbF(coverage, coverage, coverage, 1.0);
|
||||||
}
|
}
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
sceneryGetTerrain(&_terrain);
|
sceneryGetTerrain(_terrain);
|
||||||
|
TerrainRendererClass.bind(_renderer.terrain, _terrain);
|
||||||
|
|
||||||
texturesLayerCopyDefinition(_original_layer, _preview_layer);
|
texturesLayerCopyDefinition(_original_layer, _preview_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
|
||||||
{
|
|
||||||
return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer _renderer;
|
Renderer _renderer;
|
||||||
TextureLayerDefinition* _original_layer;
|
TextureLayerDefinition* _original_layer;
|
||||||
TextureLayerDefinition* _preview_layer;
|
TextureLayerDefinition* _preview_layer;
|
||||||
TerrainDefinition _terrain;
|
TerrainDefinition* _terrain;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreviewTexturesColor:public BasePreview
|
class PreviewTexturesColor:public BasePreview
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "../lib_paysages/lighting.h"
|
#include "../lib_paysages/lighting.h"
|
||||||
#include "../lib_paysages/renderer.h"
|
#include "../lib_paysages/renderer.h"
|
||||||
#include "../lib_paysages/scenery.h"
|
#include "../lib_paysages/scenery.h"
|
||||||
#include "../lib_paysages/terrain.h"
|
|
||||||
#include "../lib_paysages/water.h"
|
#include "../lib_paysages/water.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
|
@ -21,15 +20,15 @@ class PreviewWaterCoverage:public BasePreview
|
||||||
public:
|
public:
|
||||||
PreviewWaterCoverage(QWidget* parent):BasePreview(parent)
|
PreviewWaterCoverage(QWidget* parent):BasePreview(parent)
|
||||||
{
|
{
|
||||||
_water = waterCreateDefinition();
|
/*_water = waterCreateDefinition();
|
||||||
_terrain = terrainCreateDefinition();
|
_terrain = terrainCreateDefinition();*/
|
||||||
|
|
||||||
addOsd(QString("geolocation"));
|
addOsd(QString("geolocation"));
|
||||||
|
|
||||||
configScaling(0.5, 200.0, 3.0, 50.0);
|
configScaling(0.5, 200.0, 3.0, 50.0);
|
||||||
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
||||||
}
|
}
|
||||||
protected:
|
/*protected:
|
||||||
QColor getColor(double x, double y)
|
QColor getColor(double x, double y)
|
||||||
{
|
{
|
||||||
double height;
|
double height;
|
||||||
|
@ -49,7 +48,7 @@ protected:
|
||||||
{
|
{
|
||||||
waterCopyDefinition(&_definition, &_water);
|
waterCopyDefinition(&_definition, &_water);
|
||||||
sceneryGetTerrain(&_terrain);
|
sceneryGetTerrain(&_terrain);
|
||||||
}
|
}*/
|
||||||
private:
|
private:
|
||||||
WaterDefinition _water;
|
WaterDefinition _water;
|
||||||
TerrainDefinition _terrain;
|
TerrainDefinition _terrain;
|
||||||
|
@ -61,12 +60,12 @@ public:
|
||||||
PreviewWaterColor(QWidget* parent):BasePreview(parent)
|
PreviewWaterColor(QWidget* parent):BasePreview(parent)
|
||||||
{
|
{
|
||||||
LightDefinition light;
|
LightDefinition light;
|
||||||
|
|
||||||
_background = 0;
|
_background = 0;
|
||||||
_lighting_enabled = false;
|
_lighting_enabled = false;
|
||||||
|
|
||||||
_water = waterCreateDefinition();
|
_water = waterCreateDefinition();
|
||||||
|
|
||||||
_lighting = lightingCreateDefinition();
|
_lighting = lightingCreateDefinition();
|
||||||
light.color = COLOR_WHITE;
|
light.color = COLOR_WHITE;
|
||||||
light.direction.x = 0.0;
|
light.direction.x = 0.0;
|
||||||
|
@ -85,7 +84,7 @@ public:
|
||||||
_renderer.customData[0] = &_water;
|
_renderer.customData[0] = &_water;
|
||||||
_renderer.customData[1] = &_lighting;
|
_renderer.customData[1] = &_lighting;
|
||||||
_renderer.customData[2] = this;
|
_renderer.customData[2] = this;
|
||||||
|
|
||||||
configScaling(10.0, 1000.0, 10.0, 250.0);
|
configScaling(10.0, 1000.0, 10.0, 250.0);
|
||||||
//configScrolling(-30.0, 30.0, 0.0, -20.0, 20.0, 0.0);
|
//configScrolling(-30.0, 30.0, 0.0, -20.0, 20.0, 0.0);
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ private:
|
||||||
WaterDefinition _water;
|
WaterDefinition _water;
|
||||||
LightingDefinition _lighting;
|
LightingDefinition _lighting;
|
||||||
bool _lighting_enabled;
|
bool _lighting_enabled;
|
||||||
|
|
||||||
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds)
|
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds)
|
||||||
{
|
{
|
||||||
RayCastingResult result;
|
RayCastingResult result;
|
||||||
|
@ -208,7 +207,7 @@ FormWater::FormWater(QWidget *parent):
|
||||||
{
|
{
|
||||||
addAutoPreset(tr("Lake surface"));
|
addAutoPreset(tr("Lake surface"));
|
||||||
addAutoPreset(tr("Standard sea"));
|
addAutoPreset(tr("Standard sea"));
|
||||||
|
|
||||||
_definition = waterCreateDefinition();
|
_definition = waterCreateDefinition();
|
||||||
|
|
||||||
previewCoverage = new PreviewWaterCoverage(this);
|
previewCoverage = new PreviewWaterCoverage(this);
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
#include "inputheightmap.h"
|
|
||||||
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QPainter>
|
|
||||||
#include "dialogheightmap.h"
|
|
||||||
|
|
||||||
class SmallPreviewHeightMap:public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SmallPreviewHeightMap(QWidget* parent, HeightMap* value) : QWidget(parent)
|
|
||||||
{
|
|
||||||
_value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent* event)
|
|
||||||
{
|
|
||||||
double min, max, value, fx, fy;
|
|
||||||
int ivalue;
|
|
||||||
QPainter painter(this);
|
|
||||||
|
|
||||||
heightmapGetLimits(_value, &min, &max);
|
|
||||||
if (max - min < 0.000001)
|
|
||||||
{
|
|
||||||
painter.fillRect(rect(), Qt::black);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fx = 1.0 / (double)(width() - 1);
|
|
||||||
fy = 1.0 / (double)(height() - 1);
|
|
||||||
for (int x = 0; x < width(); x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < height(); y++)
|
|
||||||
{
|
|
||||||
value = heightmapGetRawValue(_value, fx * x, fy * y);
|
|
||||||
ivalue = (int)(255.0 * (value - min) / (max - min));
|
|
||||||
if (ivalue > 255 || ivalue < 0)
|
|
||||||
{
|
|
||||||
ivalue = 128;
|
|
||||||
}
|
|
||||||
painter.setPen(QColor(ivalue, ivalue, ivalue));
|
|
||||||
painter.drawPoint(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HeightMap* _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
InputHeightMap::InputHeightMap(QWidget* form, QString label, HeightMap* value, TerrainCanvas* canvas) : BaseInput(form, label)
|
|
||||||
{
|
|
||||||
_value = value;
|
|
||||||
_canvas = canvas;
|
|
||||||
|
|
||||||
_preview = new SmallPreviewHeightMap(form, value);
|
|
||||||
_preview->setMinimumSize(100, 100);
|
|
||||||
|
|
||||||
_control = new QPushButton(tr("Paint"), form);
|
|
||||||
_control->setMaximumWidth(150);
|
|
||||||
|
|
||||||
connect((QPushButton*)_control, SIGNAL(clicked()), this, SLOT(editHeightMap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputHeightMap::updatePreview()
|
|
||||||
{
|
|
||||||
_preview->update();
|
|
||||||
|
|
||||||
BaseInput::updatePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputHeightMap::applyValue()
|
|
||||||
{
|
|
||||||
BaseInput::applyValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputHeightMap::revert()
|
|
||||||
{
|
|
||||||
BaseInput::revert();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputHeightMap::editHeightMap()
|
|
||||||
{
|
|
||||||
if (DialogHeightMap::editHeightMap(_control, _value, _canvas))
|
|
||||||
{
|
|
||||||
applyValue();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef _PAYSAGES_QT_INPUTHEIGHTMAP_H_
|
|
||||||
#define _PAYSAGES_QT_INPUTHEIGHTMAP_H_
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include "baseinput.h"
|
|
||||||
|
|
||||||
#include "../lib_paysages/heightmap.h"
|
|
||||||
#include "../lib_paysages/terraincanvas.h"
|
|
||||||
|
|
||||||
class InputHeightMap:public BaseInput
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
InputHeightMap(QWidget* form, QString label, HeightMap* value, TerrainCanvas* canvas);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void updatePreview();
|
|
||||||
virtual void applyValue();
|
|
||||||
virtual void revert();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void editHeightMap();
|
|
||||||
|
|
||||||
private:
|
|
||||||
HeightMap* _value;
|
|
||||||
TerrainCanvas* _canvas;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -54,7 +54,7 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePreview::initDrawers();
|
BasePreview::initDrawers();
|
||||||
|
|
||||||
window = new MainWindow();
|
window = new MainWindow();
|
||||||
window->show();
|
window->show();
|
||||||
|
|
||||||
|
@ -127,14 +127,14 @@ QMainWindow(parent)
|
||||||
toolbar->addAction(QIcon("images/explore.png"), tr("&Explore (F2)"), this, SLOT(explore3D()))->setShortcut(QKeySequence(tr("F2")));
|
toolbar->addAction(QIcon("images/explore.png"), tr("&Explore (F2)"), this, SLOT(explore3D()))->setShortcut(QKeySequence(tr("F2")));
|
||||||
toolbar->addAction(QIcon("images/render.png"), tr("&Quick\nrender (F5)"), this, SLOT(quickPreview()))->setShortcut(QKeySequence(tr("F5")));
|
toolbar->addAction(QIcon("images/render.png"), tr("&Quick\nrender (F5)"), this, SLOT(quickPreview()))->setShortcut(QKeySequence(tr("F5")));
|
||||||
toolbar->addAction(QIcon("images/about.png"), tr("&About"), this, SLOT(showAboutDialog()));
|
toolbar->addAction(QIcon("images/about.png"), tr("&About"), this, SLOT(showAboutDialog()));
|
||||||
|
|
||||||
setCentralWidget(tabs);
|
setCentralWidget(tabs);
|
||||||
|
|
||||||
setWindowTitle("Paysages 3D");
|
setWindowTitle("Paysages 3D");
|
||||||
setWindowIcon(QIcon("images/logo_32.png"));
|
setWindowIcon(QIcon("images/logo_32.png"));
|
||||||
|
|
||||||
scenerySetCustomDataCallback(MainWindow::guiSaveCallback, MainWindow::guiLoadCallback, this);
|
scenerySetCustomDataCallback(MainWindow::guiSaveCallback, MainWindow::guiLoadCallback, this);
|
||||||
|
|
||||||
refreshAll();
|
refreshAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,20 +144,20 @@ bool MainWindow::event(QEvent* event)
|
||||||
{
|
{
|
||||||
BasePreview::reviveAll();
|
BasePreview::reviveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
return QMainWindow::event(event);
|
return QMainWindow::event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshAll()
|
void MainWindow::refreshAll()
|
||||||
{
|
{
|
||||||
logDebug("[MainWindow] Refreshing whole UI");
|
logDebug("[MainWindow] Refreshing whole UI");
|
||||||
|
|
||||||
// Refresh all tabs
|
// Refresh all tabs
|
||||||
for (int i = 0; i < _forms.size(); i++)
|
for (int i = 0; i < _forms.size(); i++)
|
||||||
{
|
{
|
||||||
_forms[i]->revertConfig();
|
_forms[i]->revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh preview OSD
|
// Refresh preview OSD
|
||||||
CameraDefinition camera = cameraCreateDefinition();
|
CameraDefinition camera = cameraCreateDefinition();
|
||||||
PreviewOsd* osd = PreviewOsd::getInstance(QString("geolocation"));
|
PreviewOsd* osd = PreviewOsd::getInstance(QString("geolocation"));
|
||||||
|
|
|
@ -25,12 +25,12 @@ public:
|
||||||
{
|
{
|
||||||
_running = false;
|
_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void usleep(unsigned long us)
|
static inline void usleep(unsigned long us)
|
||||||
{
|
{
|
||||||
QThread::usleep(us);
|
QThread::usleep(us);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ protected:
|
||||||
QThread::usleep(10000);
|
QThread::usleep(10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _running;
|
bool _running;
|
||||||
WidgetExplorer* _wanderer;
|
WidgetExplorer* _wanderer;
|
||||||
|
@ -48,21 +48,11 @@ private:
|
||||||
|
|
||||||
static QVector<ChunkMaintenanceThread*> _threads;
|
static QVector<ChunkMaintenanceThread*> _threads;
|
||||||
|
|
||||||
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
|
||||||
{
|
|
||||||
return terrainGetHeight((TerrainDefinition*)(renderer->customData[0]), x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
static Color _applyTextures(Renderer* renderer, Vector3 location, double precision)
|
||||||
{
|
{
|
||||||
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
return texturesGetColor((TexturesDefinition*)(renderer->customData[1]), renderer, location.x, location.z, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
|
||||||
{
|
|
||||||
light->color = terrainLightFilter((TerrainDefinition*)(renderer->customData[0]), renderer, light->color, location, v3Scale(light->direction, -1000.0), v3Scale(light->direction, -1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location)
|
static void _getLightStatus(Renderer* renderer, LightStatus* status, Vector3 location)
|
||||||
{
|
{
|
||||||
lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status);
|
lightingGetStatus((LightingDefinition*)renderer->customData[2], renderer, location, status);
|
||||||
|
@ -79,24 +69,19 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
|
|
||||||
_water = waterCreateDefinition();
|
_water = waterCreateDefinition();
|
||||||
sceneryGetWater(&_water);
|
sceneryGetWater(&_water);
|
||||||
_terrain = terrainCreateDefinition();
|
|
||||||
sceneryGetTerrain(&_terrain);
|
|
||||||
_textures = texturesCreateDefinition();
|
_textures = texturesCreateDefinition();
|
||||||
sceneryGetTextures(&_textures);
|
sceneryGetTextures(&_textures);
|
||||||
_lighting = lightingCreateDefinition();
|
_lighting = lightingCreateDefinition();
|
||||||
sceneryGetLighting(&_lighting);
|
sceneryGetLighting(&_lighting);
|
||||||
|
|
||||||
_renderer = sceneryCreateStandardRenderer();
|
_renderer = sceneryCreateStandardRenderer();
|
||||||
_renderer.render_quality = 3;
|
_renderer.render_quality = 3;
|
||||||
_renderer.customData[0] = &_terrain;
|
|
||||||
_renderer.customData[1] = &_textures;
|
_renderer.customData[1] = &_textures;
|
||||||
_renderer.customData[2] = &_lighting;
|
_renderer.customData[2] = &_lighting;
|
||||||
_renderer.customData[3] = &_water;
|
_renderer.customData[3] = &_water;
|
||||||
_renderer.applyTextures = _applyTextures;
|
_renderer.applyTextures = _applyTextures;
|
||||||
_renderer.getTerrainHeight = _getTerrainHeight;
|
|
||||||
_renderer.alterLight = _alterLight;
|
|
||||||
_renderer.getLightStatus = _getLightStatus;
|
_renderer.getLightStatus = _getLightStatus;
|
||||||
|
|
||||||
_updated = false;
|
_updated = false;
|
||||||
|
|
||||||
// Add terrain
|
// Add terrain
|
||||||
|
@ -113,7 +98,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
_updateQueue.append(chunk);
|
_updateQueue.append(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add skybox
|
// Add skybox
|
||||||
for (int orientation = 0; orientation < 6; orientation++)
|
for (int orientation = 0; orientation < 6; orientation++)
|
||||||
{
|
{
|
||||||
|
@ -124,7 +109,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
|
|
||||||
startThreads();
|
startThreads();
|
||||||
startTimer(500);
|
startTimer(500);
|
||||||
|
|
||||||
_average_frame_time = 0.05;
|
_average_frame_time = 0.05;
|
||||||
_quality = 3;
|
_quality = 3;
|
||||||
_last_mouse_x = 0;
|
_last_mouse_x = 0;
|
||||||
|
@ -134,7 +119,7 @@ WidgetExplorer::WidgetExplorer(QWidget *parent, CameraDefinition* camera):
|
||||||
WidgetExplorer::~WidgetExplorer()
|
WidgetExplorer::~WidgetExplorer()
|
||||||
{
|
{
|
||||||
stopThreads();
|
stopThreads();
|
||||||
|
|
||||||
for (int i = 0; i < _chunks.count(); i++)
|
for (int i = 0; i < _chunks.count(); i++)
|
||||||
{
|
{
|
||||||
delete _chunks[i];
|
delete _chunks[i];
|
||||||
|
@ -145,15 +130,15 @@ WidgetExplorer::~WidgetExplorer()
|
||||||
void WidgetExplorer::startThreads()
|
void WidgetExplorer::startThreads()
|
||||||
{
|
{
|
||||||
int nbcore;
|
int nbcore;
|
||||||
|
|
||||||
_alive = true;
|
_alive = true;
|
||||||
|
|
||||||
nbcore = QThread::idealThreadCount();
|
nbcore = QThread::idealThreadCount();
|
||||||
if (nbcore < 1)
|
if (nbcore < 1)
|
||||||
{
|
{
|
||||||
nbcore = 1;
|
nbcore = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < nbcore; i++)
|
for (int i = 0; i < nbcore; i++)
|
||||||
{
|
{
|
||||||
_threads.append(new ChunkMaintenanceThread(this));
|
_threads.append(new ChunkMaintenanceThread(this));
|
||||||
|
@ -185,7 +170,7 @@ bool _cmpChunks(const BaseExplorerChunk* c1, const BaseExplorerChunk* c2)
|
||||||
void WidgetExplorer::performChunksMaintenance()
|
void WidgetExplorer::performChunksMaintenance()
|
||||||
{
|
{
|
||||||
BaseExplorerChunk* chunk;
|
BaseExplorerChunk* chunk;
|
||||||
|
|
||||||
_lock_chunks.lock();
|
_lock_chunks.lock();
|
||||||
if (_updateQueue.count() > 0)
|
if (_updateQueue.count() > 0)
|
||||||
{
|
{
|
||||||
|
@ -197,7 +182,7 @@ void WidgetExplorer::performChunksMaintenance()
|
||||||
_lock_chunks.unlock();
|
_lock_chunks.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk->maintain())
|
if (chunk->maintain())
|
||||||
{
|
{
|
||||||
if (!_alive)
|
if (!_alive)
|
||||||
|
@ -207,7 +192,7 @@ void WidgetExplorer::performChunksMaintenance()
|
||||||
|
|
||||||
_updated = true;
|
_updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock_chunks.lock();
|
_lock_chunks.lock();
|
||||||
_updateQueue.append(chunk);
|
_updateQueue.append(chunk);
|
||||||
_lock_chunks.unlock();
|
_lock_chunks.unlock();
|
||||||
|
@ -361,7 +346,7 @@ void WidgetExplorer::timerEvent(QTimerEvent *event)
|
||||||
_updated = false;
|
_updated = false;
|
||||||
updateGL();
|
updateGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _chunks.count(); i++)
|
for (int i = 0; i < _chunks.count(); i++)
|
||||||
{
|
{
|
||||||
_chunks[i]->updatePriority(&_current_camera);
|
_chunks[i]->updatePriority(&_current_camera);
|
||||||
|
@ -397,13 +382,13 @@ void WidgetExplorer::initializeGL()
|
||||||
void WidgetExplorer::resizeGL(int w, int h)
|
void WidgetExplorer::resizeGL(int w, int h)
|
||||||
{
|
{
|
||||||
cameraSetRenderSize(&_current_camera, w, h);
|
cameraSetRenderSize(&_current_camera, w, h);
|
||||||
|
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluPerspective(_current_camera.yfov * 180.0 / M_PI, _current_camera.xratio, _current_camera.znear, _current_camera.zfar);
|
gluPerspective(_current_camera.yfov * 180.0 / M_PI, _current_camera.xratio, _current_camera.znear, _current_camera.zfar);
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,17 +397,17 @@ void WidgetExplorer::paintGL()
|
||||||
GLenum error_code;
|
GLenum error_code;
|
||||||
QTime start_time;
|
QTime start_time;
|
||||||
double frame_time;
|
double frame_time;
|
||||||
|
|
||||||
if (_current_camera.location.y > 30.0)
|
if (_current_camera.location.y > 30.0)
|
||||||
{
|
{
|
||||||
_current_camera.location.y = 30.0;
|
_current_camera.location.y = 30.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraValidateDefinition(&_current_camera, 1);
|
cameraValidateDefinition(&_current_camera, 1);
|
||||||
_renderer.camera_location = _current_camera.location;
|
_renderer.camera_location = _current_camera.location;
|
||||||
|
|
||||||
start_time = QTime::currentTime();
|
start_time = QTime::currentTime();
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z);
|
gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z);
|
||||||
|
@ -448,12 +433,12 @@ void WidgetExplorer::paintGL()
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
_chunks[i]->render(this);
|
_chunks[i]->render(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_time = 0.001 * (double)start_time.msecsTo(QTime::currentTime());
|
frame_time = 0.001 * (double)start_time.msecsTo(QTime::currentTime());
|
||||||
|
|
||||||
_average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2;
|
_average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2;
|
||||||
//printf("%d %f\n", quality, average_frame_time);
|
//printf("%d %f\n", quality, average_frame_time);
|
||||||
|
|
||||||
if (_average_frame_time > 0.1 && _quality > 1)
|
if (_average_frame_time > 0.1 && _quality > 1)
|
||||||
{
|
{
|
||||||
_quality--;
|
_quality--;
|
||||||
|
@ -462,7 +447,7 @@ void WidgetExplorer::paintGL()
|
||||||
{
|
{
|
||||||
_quality++;
|
_quality++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((error_code = glGetError()) != GL_NO_ERROR)
|
while ((error_code = glGetError()) != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
logDebug(QString("[OpenGL] ERROR : ") + (const char*)gluErrorString(error_code));
|
logDebug(QString("[OpenGL] ERROR : ") + (const char*)gluErrorString(error_code));
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "../lib_paysages/camera.h"
|
#include "../lib_paysages/camera.h"
|
||||||
#include "../lib_paysages/water.h"
|
#include "../lib_paysages/water.h"
|
||||||
#include "../lib_paysages/renderer.h"
|
#include "../lib_paysages/renderer.h"
|
||||||
#include "../lib_paysages/terrain.h"
|
|
||||||
#include "../lib_paysages/textures.h"
|
#include "../lib_paysages/textures.h"
|
||||||
#include "../lib_paysages/lighting.h"
|
#include "../lib_paysages/lighting.h"
|
||||||
|
|
||||||
|
@ -16,7 +15,7 @@ class WidgetExplorer : public QGLWidget
|
||||||
public:
|
public:
|
||||||
WidgetExplorer(QWidget* parent, CameraDefinition* camera);
|
WidgetExplorer(QWidget* parent, CameraDefinition* camera);
|
||||||
~WidgetExplorer();
|
~WidgetExplorer();
|
||||||
|
|
||||||
void performChunksMaintenance();
|
void performChunksMaintenance();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -33,27 +32,26 @@ protected:
|
||||||
void initializeGL();
|
void initializeGL();
|
||||||
void resizeGL(int w, int h);
|
void resizeGL(int w, int h);
|
||||||
void paintGL();
|
void paintGL();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startThreads();
|
void startThreads();
|
||||||
void stopThreads();
|
void stopThreads();
|
||||||
|
|
||||||
CameraDefinition _current_camera;
|
CameraDefinition _current_camera;
|
||||||
CameraDefinition* _base_camera;
|
CameraDefinition* _base_camera;
|
||||||
|
|
||||||
Renderer _renderer;
|
Renderer _renderer;
|
||||||
bool _updated;
|
bool _updated;
|
||||||
|
|
||||||
QVector<BaseExplorerChunk*> _chunks;
|
QVector<BaseExplorerChunk*> _chunks;
|
||||||
QList<BaseExplorerChunk*> _updateQueue;
|
QList<BaseExplorerChunk*> _updateQueue;
|
||||||
bool _alive;
|
bool _alive;
|
||||||
QMutex _lock_chunks;
|
QMutex _lock_chunks;
|
||||||
|
|
||||||
WaterDefinition _water;
|
WaterDefinition _water;
|
||||||
TerrainDefinition _terrain;
|
|
||||||
TexturesDefinition _textures;
|
TexturesDefinition _textures;
|
||||||
LightingDefinition _lighting;
|
LightingDefinition _lighting;
|
||||||
|
|
||||||
double _average_frame_time;
|
double _average_frame_time;
|
||||||
int _quality;
|
int _quality;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
BUILDMODE = debug
|
BUILDMODE = debug
|
||||||
BUILDPATH = ../build/${BUILDMODE}
|
BUILDPATH = ../build/${BUILDMODE}
|
||||||
OBJPATH = ./obj/${BUILDMODE}
|
OBJPATH = ./obj/${BUILDMODE}
|
||||||
SOURCES = $(wildcard *.c atmosphere/*.c)
|
SOURCES = $(wildcard *.c atmosphere/*.c terrain/*.c)
|
||||||
OBJECTS = ${SOURCES:%.c=${OBJPATH}/%.o}
|
OBJECTS = ${SOURCES:%.c=${OBJPATH}/%.o}
|
||||||
HEADERS = $(wildcard shared/*.h atmosphere/*.h *.h)
|
HEADERS = $(wildcard *.h atmosphere/*.h terrain/*.h shared/*.h)
|
||||||
RESULT = ${BUILDPATH}/libpaysages.so
|
RESULT = ${BUILDPATH}/libpaysages.so
|
||||||
LIBS = glib-2.0 gthread-2.0 IL ILU
|
LIBS = glib-2.0 gthread-2.0 IL ILU
|
||||||
CC_FLAGS = -Wall -fPIC -DHAVE_GLIB=1
|
CC_FLAGS = -Wall -fPIC -DHAVE_GLIB=1
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "../lighting.h"
|
#include "../lighting.h"
|
||||||
#include "../system.h"
|
#include "../system.h"
|
||||||
|
|
||||||
#define SPHERE_SIZE 1000.0
|
|
||||||
#define MAX_SKYDOME_LIGHTS 100
|
#define MAX_SKYDOME_LIGHTS 100
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -342,73 +341,3 @@ StandardRenderer AtmosphereRendererClass = {
|
||||||
(FuncObjectDelete)_deleteRenderer,
|
(FuncObjectDelete)_deleteRenderer,
|
||||||
(FuncObjectBind)_bindRenderer
|
(FuncObjectBind)_bindRenderer
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************** Utilities ********************/
|
|
||||||
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data)
|
|
||||||
{
|
|
||||||
Vector3 direction;
|
|
||||||
Color result;
|
|
||||||
|
|
||||||
UNUSED(data);
|
|
||||||
|
|
||||||
direction = v3Sub(location, renderer->camera_location);
|
|
||||||
|
|
||||||
/* TODO Don't compute result->color if it's fully covered by clouds */
|
|
||||||
result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction));
|
|
||||||
result = renderer->applyClouds(renderer, result, renderer->camera_location, v3Add(renderer->camera_location, v3Scale(direction, 10.0)));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void atmosphereRenderSkydome(Renderer* renderer)
|
|
||||||
{
|
|
||||||
int res_i, res_j;
|
|
||||||
int i, j;
|
|
||||||
double step_i, step_j;
|
|
||||||
double current_i, current_j;
|
|
||||||
Vector3 vertex1, vertex2, vertex3, vertex4;
|
|
||||||
Vector3 direction;
|
|
||||||
|
|
||||||
res_i = renderer->render_quality * 40;
|
|
||||||
res_j = renderer->render_quality * 20;
|
|
||||||
step_i = M_PI * 2.0 / (double)res_i;
|
|
||||||
step_j = M_PI / (double)res_j;
|
|
||||||
|
|
||||||
for (j = 0; j < res_j; j++)
|
|
||||||
{
|
|
||||||
if (!renderer->addRenderProgress(renderer, 0.0))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_j = (double)(j - res_j / 2) * step_j;
|
|
||||||
|
|
||||||
for (i = 0; i < res_i; i++)
|
|
||||||
{
|
|
||||||
current_i = (double)i * step_i;
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j);
|
|
||||||
vertex1 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j);
|
|
||||||
vertex2 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j);
|
|
||||||
vertex3 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j);
|
|
||||||
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
|
||||||
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j);
|
|
||||||
vertex4 = v3Add(renderer->camera_location, direction);
|
|
||||||
|
|
||||||
/* TODO Triangles at poles */
|
|
||||||
renderer->pushQuad(renderer, vertex1, vertex4, vertex3, vertex2, _postProcessFragment, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "../renderer.h"
|
#include "../renderer.h"
|
||||||
#include "../lighting.h"
|
#include "../lighting.h"
|
||||||
#include "../terrain.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Atmosphere previews.
|
* Atmosphere previews.
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _PAYSAGES_ATMOSPHERE_PRIVATE_H_
|
#ifndef _PAYSAGES_ATMOSPHERE_PRIVATE_H_
|
||||||
#define _PAYSAGES_ATMOSPHERE_PRIVATE_H_
|
#define _PAYSAGES_ATMOSPHERE_PRIVATE_H_
|
||||||
|
|
||||||
|
#define SPHERE_SIZE 1000.0
|
||||||
|
|
||||||
Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position);
|
Color brunetonGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position);
|
||||||
|
|
||||||
Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position);
|
Color preethamGetSkyColor(AtmosphereDefinition* definition, Vector3 eye, Vector3 direction, Vector3 sun_position);
|
||||||
|
|
|
@ -11,31 +11,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** TO EXTRACT ***/
|
|
||||||
typedef void* (*FuncObjectCreate)();
|
|
||||||
typedef void (*FuncObjectDelete)(void* object);
|
|
||||||
typedef void (*FuncObjectCopy)(void* source, void* destination);
|
|
||||||
typedef void (*FuncObjectValidate)(void* object);
|
|
||||||
typedef void (*FuncObjectSave)(PackStream* stream, void* object);
|
|
||||||
typedef void (*FuncObjectLoad)(PackStream* stream, void* object);
|
|
||||||
typedef void (*FuncObjectBind)(void* base, void* sub);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FuncObjectCreate create;
|
|
||||||
FuncObjectDelete destroy;
|
|
||||||
FuncObjectCopy copy;
|
|
||||||
FuncObjectValidate validate;
|
|
||||||
FuncObjectSave save;
|
|
||||||
FuncObjectLoad load;
|
|
||||||
} StandardDefinition;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FuncObjectCreate create;
|
|
||||||
FuncObjectDelete destroy;
|
|
||||||
FuncObjectBind bind;
|
|
||||||
} StandardRenderer;
|
|
||||||
/*** TO EXTRACT ***/
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
ATMOSPHERE_MODEL_PREETHAM = 0,
|
ATMOSPHERE_MODEL_PREETHAM = 0,
|
||||||
|
|
76
lib_paysages/atmosphere/raster.c
Normal file
76
lib_paysages/atmosphere/raster.c
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#include "public.h"
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../tools.h"
|
||||||
|
#include "../renderer.h"
|
||||||
|
|
||||||
|
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data)
|
||||||
|
{
|
||||||
|
Vector3 direction;
|
||||||
|
Color result;
|
||||||
|
|
||||||
|
UNUSED(data);
|
||||||
|
|
||||||
|
direction = v3Sub(location, renderer->camera_location);
|
||||||
|
|
||||||
|
/* TODO Don't compute result->color if it's fully covered by clouds */
|
||||||
|
result = renderer->atmosphere->getSkyColor(renderer, v3Normalize(direction));
|
||||||
|
result = renderer->applyClouds(renderer, result, renderer->camera_location, v3Add(renderer->camera_location, v3Scale(direction, 10.0)));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void atmosphereRenderSkydome(Renderer* renderer)
|
||||||
|
{
|
||||||
|
int res_i, res_j;
|
||||||
|
int i, j;
|
||||||
|
double step_i, step_j;
|
||||||
|
double current_i, current_j;
|
||||||
|
Vector3 vertex1, vertex2, vertex3, vertex4;
|
||||||
|
Vector3 direction;
|
||||||
|
|
||||||
|
res_i = renderer->render_quality * 40;
|
||||||
|
res_j = renderer->render_quality * 20;
|
||||||
|
step_i = M_PI * 2.0 / (double)res_i;
|
||||||
|
step_j = M_PI / (double)res_j;
|
||||||
|
|
||||||
|
for (j = 0; j < res_j; j++)
|
||||||
|
{
|
||||||
|
if (!renderer->addRenderProgress(renderer, 0.0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_j = (double)(j - res_j / 2) * step_j;
|
||||||
|
|
||||||
|
for (i = 0; i < res_i; i++)
|
||||||
|
{
|
||||||
|
current_i = (double)i * step_i;
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j);
|
||||||
|
vertex1 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j);
|
||||||
|
vertex2 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j);
|
||||||
|
vertex3 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j);
|
||||||
|
direction.y = SPHERE_SIZE * sin(current_j + step_j);
|
||||||
|
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j);
|
||||||
|
vertex4 = v3Add(renderer->camera_location, direction);
|
||||||
|
|
||||||
|
/* TODO Triangles at poles */
|
||||||
|
renderer->pushQuad(renderer, vertex1, vertex4, vertex3, vertex2, _postProcessFragment, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,6 @@
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include "modifiers.h"
|
#include "modifiers.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "terrain.h"
|
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "scenery.h"
|
#include "scenery.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
@ -66,17 +65,6 @@ void autoGenRealisticLandscape(int seed)
|
||||||
scenerySetWater(&water);
|
scenerySetWater(&water);
|
||||||
waterDeleteDefinition(&water);
|
waterDeleteDefinition(&water);
|
||||||
|
|
||||||
/* Terrain */
|
|
||||||
terrain = terrainCreateDefinition();
|
|
||||||
noiseClearLevels(terrain.height_noise);
|
|
||||||
noiseAddLevelsSimple(terrain.height_noise, 10, 1.0, 1.0);
|
|
||||||
noiseSetFunctionParams(terrain.height_noise, NOISE_FUNCTION_SIMPLEX, -0.2);
|
|
||||||
terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise);
|
|
||||||
terrain.scaling = 80.0;
|
|
||||||
terrain.shadow_smoothing = 0.03;
|
|
||||||
scenerySetTerrain(&terrain);
|
|
||||||
terrainDeleteDefinition(&terrain);
|
|
||||||
|
|
||||||
/* Textures */
|
/* Textures */
|
||||||
textures = texturesCreateDefinition();
|
textures = texturesCreateDefinition();
|
||||||
layer = layersAddLayer(textures.layers, NULL);
|
layer = layersAddLayer(textures.layers, NULL);
|
||||||
|
|
|
@ -36,14 +36,14 @@ CameraDefinition cameraCreateDefinition()
|
||||||
definition.yaw = 0.0;
|
definition.yaw = 0.0;
|
||||||
definition.pitch = 0.0;
|
definition.pitch = 0.0;
|
||||||
definition.roll = 0.0;
|
definition.roll = 0.0;
|
||||||
|
|
||||||
definition.width = 1.0;
|
definition.width = 1.0;
|
||||||
definition.height = 1.0;
|
definition.height = 1.0;
|
||||||
definition.yfov = 1.57;
|
definition.yfov = 1.57;
|
||||||
definition.xratio = 1.0;
|
definition.xratio = 1.0;
|
||||||
definition.znear = 1.0;
|
definition.znear = 1.0;
|
||||||
definition.zfar = 1000.0;
|
definition.zfar = 1000.0;
|
||||||
|
|
||||||
cameraValidateDefinition(&definition, 0);
|
cameraValidateDefinition(&definition, 0);
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
|
@ -56,18 +56,18 @@ void cameraDeleteDefinition(CameraDefinition* definition)
|
||||||
void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination)
|
void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination)
|
||||||
{
|
{
|
||||||
*destination = *source;
|
*destination = *source;
|
||||||
|
|
||||||
cameraValidateDefinition(destination, 0);
|
cameraValidateDefinition(destination, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cameraValidateDefinition(CameraDefinition* definition, int check_above)
|
void cameraValidateDefinition(CameraDefinition* definition, int check_above)
|
||||||
{
|
{
|
||||||
WaterDefinition water;
|
WaterDefinition water;
|
||||||
TerrainDefinition terrain;
|
Renderer renderer;
|
||||||
double water_height, terrain_height, diff;
|
double water_height, terrain_height, diff;
|
||||||
Vector3 move;
|
Vector3 move;
|
||||||
Matrix4 rotation;
|
Matrix4 rotation;
|
||||||
|
|
||||||
if (check_above)
|
if (check_above)
|
||||||
{
|
{
|
||||||
water = waterCreateDefinition();
|
water = waterCreateDefinition();
|
||||||
|
@ -75,11 +75,10 @@ void cameraValidateDefinition(CameraDefinition* definition, int check_above)
|
||||||
water_height = water.height + 0.5;
|
water_height = water.height + 0.5;
|
||||||
waterDeleteDefinition(&water);
|
waterDeleteDefinition(&water);
|
||||||
|
|
||||||
terrain = terrainCreateDefinition();
|
renderer = sceneryCreateStandardRenderer();
|
||||||
sceneryGetTerrain(&terrain);
|
terrain_height = renderer.terrain->getHeight(&renderer, definition->location.x, definition->location.z) + 0.5;
|
||||||
terrain_height = terrainGetHeight(&terrain, definition->location.x, definition->location.z) + 0.5;
|
rendererDelete(&renderer);
|
||||||
terrainDeleteDefinition(&terrain);
|
|
||||||
|
|
||||||
if (definition->location.y < water_height || definition->location.y < terrain_height)
|
if (definition->location.y < water_height || definition->location.y < terrain_height)
|
||||||
{
|
{
|
||||||
if (water_height > terrain_height)
|
if (water_height > terrain_height)
|
||||||
|
@ -96,7 +95,7 @@ void cameraValidateDefinition(CameraDefinition* definition, int check_above)
|
||||||
definition->location = v3Add(definition->location, move);
|
definition->location = v3Add(definition->location, move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
definition->forward.x = 1.0;
|
definition->forward.x = 1.0;
|
||||||
definition->forward.y = 0.0;
|
definition->forward.y = 0.0;
|
||||||
definition->forward.z = 0.0;
|
definition->forward.z = 0.0;
|
||||||
|
@ -106,13 +105,13 @@ void cameraValidateDefinition(CameraDefinition* definition, int check_above)
|
||||||
definition->up.x = 0.0;
|
definition->up.x = 0.0;
|
||||||
definition->up.y = 1.0;
|
definition->up.y = 1.0;
|
||||||
definition->up.z = 0.0;
|
definition->up.z = 0.0;
|
||||||
|
|
||||||
rotation = m4NewRotateEuler(definition->yaw, definition->pitch, definition->roll);
|
rotation = m4NewRotateEuler(definition->yaw, definition->pitch, definition->roll);
|
||||||
|
|
||||||
definition->forward = m4MultPoint(rotation, definition->forward);
|
definition->forward = m4MultPoint(rotation, definition->forward);
|
||||||
definition->right = m4MultPoint(rotation, definition->right);
|
definition->right = m4MultPoint(rotation, definition->right);
|
||||||
definition->up = m4MultPoint(rotation, definition->up);
|
definition->up = m4MultPoint(rotation, definition->up);
|
||||||
|
|
||||||
definition->target = v3Add(definition->location, definition->forward);
|
definition->target = v3Add(definition->location, definition->forward);
|
||||||
|
|
||||||
definition->project = m4Mult(m4NewPerspective(definition->yfov, definition->xratio, definition->znear, definition->zfar), m4NewLookAt(definition->location, definition->target, definition->up));
|
definition->project = m4Mult(m4NewPerspective(definition->yfov, definition->xratio, definition->znear, definition->zfar), m4NewLookAt(definition->location, definition->target, definition->up));
|
||||||
|
@ -131,18 +130,18 @@ void cameraSetLocation(CameraDefinition* camera, double x, double y, double z)
|
||||||
void cameraSetTarget(CameraDefinition* camera, double x, double y, double z)
|
void cameraSetTarget(CameraDefinition* camera, double x, double y, double z)
|
||||||
{
|
{
|
||||||
Vector3 forward, target;
|
Vector3 forward, target;
|
||||||
|
|
||||||
target.x = x;
|
target.x = x;
|
||||||
target.y = y;
|
target.y = y;
|
||||||
target.z = z;
|
target.z = z;
|
||||||
|
|
||||||
forward = v3Sub(target, camera->location);
|
forward = v3Sub(target, camera->location);
|
||||||
if (v3Norm(forward) < 0.0000001)
|
if (v3Norm(forward) < 0.0000001)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
forward = v3Normalize(forward);
|
forward = v3Normalize(forward);
|
||||||
|
|
||||||
if (fabs(forward.x) < 0.0000001 && fabs(forward.z) < 0.0000001)
|
if (fabs(forward.x) < 0.0000001 && fabs(forward.z) < 0.0000001)
|
||||||
{
|
{
|
||||||
/* Forward vector is vertical */
|
/* Forward vector is vertical */
|
||||||
|
@ -217,7 +216,7 @@ void cameraSetRenderSize(CameraDefinition* camera, int width, int height)
|
||||||
camera->width = (double)width;
|
camera->width = (double)width;
|
||||||
camera->height = (double)height;
|
camera->height = (double)height;
|
||||||
camera->xratio = camera->width / camera->height;
|
camera->xratio = camera->width / camera->height;
|
||||||
|
|
||||||
cameraValidateDefinition(camera, 0);
|
cameraValidateDefinition(camera, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +287,7 @@ static inline void _updateBox(Vector3* point, double* xmin, double* xmax, double
|
||||||
{
|
{
|
||||||
*xmin = (*xmin < point->x) ? *xmin : point->x;
|
*xmin = (*xmin < point->x) ? *xmin : point->x;
|
||||||
*ymin = (*ymin < point->y) ? *ymin : point->y;
|
*ymin = (*ymin < point->y) ? *ymin : point->y;
|
||||||
|
|
||||||
*xmax = (*xmax > point->x) ? *xmax : point->x;
|
*xmax = (*xmax > point->x) ? *xmax : point->x;
|
||||||
*ymax = (*ymax > point->y) ? *ymax : point->y;
|
*ymax = (*ymax > point->y) ? *ymax : point->y;
|
||||||
*zmax = (*zmax > point->z) ? *zmax : point->z;
|
*zmax = (*zmax > point->z) ? *zmax : point->z;
|
||||||
|
@ -298,7 +297,7 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do
|
||||||
{
|
{
|
||||||
Vector3 projected;
|
Vector3 projected;
|
||||||
double xmin, xmax, ymin, ymax, zmax;
|
double xmin, xmax, ymin, ymax, zmax;
|
||||||
|
|
||||||
center.x -= xsize / 2.0;
|
center.x -= xsize / 2.0;
|
||||||
center.y -= ysize / 2.0;
|
center.y -= ysize / 2.0;
|
||||||
center.z -= zsize / 2.0;
|
center.z -= zsize / 2.0;
|
||||||
|
@ -306,7 +305,7 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do
|
||||||
xmin = xmax = projected.x;
|
xmin = xmax = projected.x;
|
||||||
ymin = ymax = projected.y;
|
ymin = ymax = projected.y;
|
||||||
zmax = projected.z;
|
zmax = projected.z;
|
||||||
|
|
||||||
center.x += xsize;
|
center.x += xsize;
|
||||||
projected = cameraProject(camera, NULL, center);
|
projected = cameraProject(camera, NULL, center);
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
||||||
|
@ -322,7 +321,7 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do
|
||||||
center.y += ysize;
|
center.y += ysize;
|
||||||
projected = cameraProject(camera, NULL, center);
|
projected = cameraProject(camera, NULL, center);
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
||||||
|
|
||||||
center.x += xsize;
|
center.x += xsize;
|
||||||
projected = cameraProject(camera, NULL, center);
|
projected = cameraProject(camera, NULL, center);
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
||||||
|
@ -334,6 +333,6 @@ int cameraIsBoxInView(CameraDefinition* camera, Vector3 center, double xsize, do
|
||||||
center.x -= xsize;
|
center.x -= xsize;
|
||||||
projected = cameraProject(camera, NULL, center);
|
projected = cameraProject(camera, NULL, center);
|
||||||
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
_updateBox(&projected, &xmin, &xmax, &ymin, &ymax, &zmax);
|
||||||
|
|
||||||
return xmin <= camera->width && xmax >= 0.0 && ymin <= camera->height && ymax >= 0.0 && zmax >= camera->znear;
|
return xmin <= camera->width && xmax >= 0.0 && ymin <= camera->height && ymax >= 0.0 && zmax >= camera->znear;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
HeightMap heightmapCreate()
|
HeightMap heightmapCreate()
|
||||||
{
|
{
|
||||||
HeightMap result;
|
HeightMap result;
|
||||||
|
|
||||||
result.data = malloc(sizeof(double));
|
result.data = malloc(sizeof(double));
|
||||||
result.resolution_x = 1;
|
result.resolution_x = 1;
|
||||||
result.resolution_z = 1;
|
result.resolution_z = 1;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ void heightmapValidate(HeightMap* heightmap)
|
||||||
void heightmapSave(PackStream* stream, HeightMap* heightmap)
|
void heightmapSave(PackStream* stream, HeightMap* heightmap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
packWriteInt(stream, &heightmap->resolution_x);
|
packWriteInt(stream, &heightmap->resolution_x);
|
||||||
packWriteInt(stream, &heightmap->resolution_z);
|
packWriteInt(stream, &heightmap->resolution_z);
|
||||||
for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++)
|
for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++)
|
||||||
|
@ -52,7 +52,7 @@ void heightmapSave(PackStream* stream, HeightMap* heightmap)
|
||||||
void heightmapLoad(PackStream* stream, HeightMap* heightmap)
|
void heightmapLoad(PackStream* stream, HeightMap* heightmap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
packReadInt(stream, &heightmap->resolution_x);
|
packReadInt(stream, &heightmap->resolution_x);
|
||||||
packReadInt(stream, &heightmap->resolution_z);
|
packReadInt(stream, &heightmap->resolution_z);
|
||||||
heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z);
|
heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z);
|
||||||
|
@ -66,7 +66,7 @@ static void _loadFromFilePixel(HeightMap* heightmap, int x, int y, Color col)
|
||||||
{
|
{
|
||||||
assert(x >= 0 && x < heightmap->resolution_x);
|
assert(x >= 0 && x < heightmap->resolution_x);
|
||||||
assert(y >= 0 && y < heightmap->resolution_z);
|
assert(y >= 0 && y < heightmap->resolution_z);
|
||||||
|
|
||||||
heightmap->data[y * heightmap->resolution_x + x] = (col.r + col.g + col.b) / 3.0;
|
heightmap->data[y * heightmap->resolution_x + x] = (col.r + col.g + col.b) / 3.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ double heightmapGetRawValue(HeightMap* heightmap, double x, double z)
|
||||||
{
|
{
|
||||||
assert(x >= 0.0 && x <= 1.0);
|
assert(x >= 0.0 && x <= 1.0);
|
||||||
assert(z >= 0.0 && z <= 1.0);
|
assert(z >= 0.0 && z <= 1.0);
|
||||||
|
|
||||||
return heightmap->data[((int)(z * (double)(heightmap->resolution_z - 1))) * heightmap->resolution_x + ((int)(x * (double)(heightmap->resolution_x - 1)))];
|
return heightmap->data[((int)(z * (double)(heightmap->resolution_z - 1))) * heightmap->resolution_x + ((int)(x * (double)(heightmap->resolution_x - 1)))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ double heightmapGetValue(HeightMap* heightmap, double x, double z)
|
||||||
int zlow;
|
int zlow;
|
||||||
double stencil[16];
|
double stencil[16];
|
||||||
int ix, iz, cx, cz;
|
int ix, iz, cx, cz;
|
||||||
|
|
||||||
if (x < 0.0)
|
if (x < 0.0)
|
||||||
{
|
{
|
||||||
x = 0.0;
|
x = 0.0;
|
||||||
|
@ -139,7 +139,7 @@ double heightmapGetValue(HeightMap* heightmap, double x, double z)
|
||||||
stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = heightmap->data[cz * heightmap->resolution_x + cx];
|
stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = heightmap->data[cz * heightmap->resolution_x + cx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return toolsBicubicInterpolate(stencil, x * xmax - (double)xlow, z * zmax - (double)zlow);
|
return toolsBicubicInterpolate(stencil, x * xmax - (double)xlow, z * zmax - (double)zlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +152,11 @@ void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath)
|
||||||
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z)
|
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
heightmap->resolution_x = resolution_x;
|
heightmap->resolution_x = resolution_x;
|
||||||
heightmap->resolution_z = resolution_z;
|
heightmap->resolution_z = resolution_z;
|
||||||
heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z);
|
heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z);
|
||||||
|
|
||||||
for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++)
|
for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++)
|
||||||
{
|
{
|
||||||
heightmap->data[i] = 0.0;
|
heightmap->data[i] = 0.0;
|
||||||
|
@ -168,7 +168,7 @@ void heightmapRevertToTerrain(HeightMap* heightmap, TerrainDefinition* terrain,
|
||||||
int rx, rz;
|
int rx, rz;
|
||||||
int x, z;
|
int x, z;
|
||||||
double dx, dz;
|
double dx, dz;
|
||||||
|
|
||||||
rx = heightmap->resolution_x;
|
rx = heightmap->resolution_x;
|
||||||
rz = heightmap->resolution_z;
|
rz = heightmap->resolution_z;
|
||||||
for (x = 0; x < rx; x++)
|
for (x = 0; x < rx; x++)
|
||||||
|
@ -178,7 +178,7 @@ void heightmapRevertToTerrain(HeightMap* heightmap, TerrainDefinition* terrain,
|
||||||
dx = (double)x / (double)(rx - 1);
|
dx = (double)x / (double)(rx - 1);
|
||||||
dz = (double)z / (double)(rz - 1);
|
dz = (double)z / (double)(rz - 1);
|
||||||
geoareaFromLocal(area, dx, dz, &dx, &dz);
|
geoareaFromLocal(area, dx, dz, &dx, &dz);
|
||||||
heightmap->data[z * rx + x] = terrainGetHeight(terrain, dx, dz);
|
// heightmap->data[z * rx + x] = terrainGetHeight(terrain, dx, dz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,9 +235,9 @@ static inline void _applyBrush(HeightMap* heightmap, HeightMapBrush* brush, doub
|
||||||
{
|
{
|
||||||
int x, x1, x2, z, z1, z2;
|
int x, x1, x2, z, z1, z2;
|
||||||
double dx, dz, distance, influence;
|
double dx, dz, distance, influence;
|
||||||
|
|
||||||
_getBrushBoundaries(brush, heightmap->resolution_x - 1, heightmap->resolution_z - 1, &x1, &x2, &z1, &z2);
|
_getBrushBoundaries(brush, heightmap->resolution_x - 1, heightmap->resolution_z - 1, &x1, &x2, &z1, &z2);
|
||||||
|
|
||||||
for (x = x1; x <= x2; x++)
|
for (x = x1; x <= x2; x++)
|
||||||
{
|
{
|
||||||
dx = (double)x / (double)heightmap->resolution_x;
|
dx = (double)x / (double)heightmap->resolution_x;
|
||||||
|
@ -245,7 +245,7 @@ static inline void _applyBrush(HeightMap* heightmap, HeightMapBrush* brush, doub
|
||||||
{
|
{
|
||||||
dz = (double)z / (double)heightmap->resolution_z;
|
dz = (double)z / (double)heightmap->resolution_z;
|
||||||
distance = sqrt((brush->relative_x - dx) * (brush->relative_x - dx) + (brush->relative_z - dz) * (brush->relative_z - dz));
|
distance = sqrt((brush->relative_x - dx) * (brush->relative_x - dx) + (brush->relative_z - dz) * (brush->relative_z - dz));
|
||||||
|
|
||||||
if (distance > brush->hard_radius)
|
if (distance > brush->hard_radius)
|
||||||
{
|
{
|
||||||
if (distance <= brush->hard_radius + brush->smoothed_size)
|
if (distance <= brush->hard_radius + brush->smoothed_size)
|
||||||
|
@ -261,7 +261,7 @@ static inline void _applyBrush(HeightMap* heightmap, HeightMapBrush* brush, doub
|
||||||
{
|
{
|
||||||
influence = 1.0;
|
influence = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
heightmap->data[z * heightmap->resolution_x + x] = callback(heightmap, brush, dx, dz, heightmap->data[z * heightmap->resolution_x + x], influence, force, data);
|
heightmap->data[z * heightmap->resolution_x + x] = callback(heightmap, brush, dx, dz, heightmap->data[z * heightmap->resolution_x + x], influence, force, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
#include "noise.h"
|
#include "noise.h"
|
||||||
#include "geoarea.h"
|
#include "geoarea.h"
|
||||||
#include "terrain.h"
|
#include "terrain/public.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -47,7 +47,7 @@ void heightmapRevertToTerrain(HeightMap* heightmap, TerrainDefinition* terrain,
|
||||||
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value);
|
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value);
|
||||||
void heightmapBrushSmooth(HeightMap* heightmap, HeightMapBrush* brush, double value);
|
void heightmapBrushSmooth(HeightMap* heightmap, HeightMapBrush* brush, double value);
|
||||||
void heightmapBrushAddNoise(HeightMap* heightmap, HeightMapBrush* brush, NoiseGenerator* generator, double value);
|
void heightmapBrushAddNoise(HeightMap* heightmap, HeightMapBrush* brush, NoiseGenerator* generator, double value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "euclid.h"
|
#include "euclid.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "scenery.h"
|
#include "scenery.h"
|
||||||
#include "terrain.h"
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "water.h"
|
#include "water.h"
|
||||||
|
|
||||||
|
@ -130,12 +129,12 @@ void lightingDeleteLight(LightingDefinition* definition, int light)
|
||||||
static int _getLightStatus(LightDefinition* definition, Renderer* renderer, Vector3 location, LightDefinition* result)
|
static int _getLightStatus(LightDefinition* definition, Renderer* renderer, Vector3 location, LightDefinition* result)
|
||||||
{
|
{
|
||||||
*result = *definition;
|
*result = *definition;
|
||||||
|
|
||||||
if (definition->masked || definition->filtered)
|
if (definition->masked || definition->filtered)
|
||||||
{
|
{
|
||||||
renderer->alterLight(renderer, result, location);
|
renderer->alterLight(renderer, result, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result->color.r > 0.0 || result->color.g > 0.0 || result->color.b > 0.0)
|
if (result->color.r > 0.0 || result->color.g > 0.0 || result->color.b > 0.0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -209,9 +208,9 @@ void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vecto
|
||||||
{
|
{
|
||||||
int i, skydome_lights_count;
|
int i, skydome_lights_count;
|
||||||
LightDefinition skydome_lights[LIGHTING_MAX_LIGHTS];
|
LightDefinition skydome_lights[LIGHTING_MAX_LIGHTS];
|
||||||
|
|
||||||
result->nblights = 0;
|
result->nblights = 0;
|
||||||
|
|
||||||
/* Apply static lights */
|
/* Apply static lights */
|
||||||
for (i = 0; i < definition->nblights; i++)
|
for (i = 0; i < definition->nblights; i++)
|
||||||
{
|
{
|
||||||
|
@ -220,7 +219,7 @@ void lightingGetStatus(LightingDefinition* definition, Renderer* renderer, Vecto
|
||||||
result->nblights++;
|
result->nblights++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply skydome lights */
|
/* Apply skydome lights */
|
||||||
/* TODO Cache skydome lights for same render */
|
/* TODO Cache skydome lights for same render */
|
||||||
skydome_lights_count = renderer->atmosphere->getSkydomeLights(renderer, skydome_lights, LIGHTING_MAX_LIGHTS);
|
skydome_lights_count = renderer->atmosphere->getSkydomeLights(renderer, skydome_lights, LIGHTING_MAX_LIGHTS);
|
||||||
|
@ -240,7 +239,7 @@ Color lightingApplyStatusToSurface(Renderer* renderer, LightStatus* status, Vect
|
||||||
|
|
||||||
result = COLOR_BLACK;
|
result = COLOR_BLACK;
|
||||||
result.a = material.base.a;
|
result.a = material.base.a;
|
||||||
|
|
||||||
for (i = 0; i < status->nblights; i++)
|
for (i = 0; i < status->nblights; i++)
|
||||||
{
|
{
|
||||||
lighted = _applyDirectLight(status->lights + i, renderer, location, normal, material);
|
lighted = _applyDirectLight(status->lights + i, renderer, location, normal, material);
|
||||||
|
@ -248,14 +247,14 @@ Color lightingApplyStatusToSurface(Renderer* renderer, LightStatus* status, Vect
|
||||||
result.g += lighted.g;
|
result.g += lighted.g;
|
||||||
result.b += lighted.b;
|
result.b += lighted.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
|
||||||
{
|
{
|
||||||
LightStatus status;
|
LightStatus status;
|
||||||
|
|
||||||
lightingGetStatus(definition, renderer, location, &status);
|
lightingGetStatus(definition, renderer, location, &status);
|
||||||
return lightingApplyStatusToSurface(renderer, &status, location, normal, material);
|
return lightingApplyStatusToSurface(renderer, &status, location, normal, material);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define _PAYSAGES_LIGHTING_H_
|
#define _PAYSAGES_LIGHTING_H_
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
#include "renderer.h"
|
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -32,6 +31,8 @@ struct LightStatus
|
||||||
LightDefinition lights[LIGHTING_MAX_LIGHTS * 2];
|
LightDefinition lights[LIGHTING_MAX_LIGHTS * 2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef LightDefinition (*FuncLightingAlterLight)(Renderer* renderer, LightDefinition* light, Vector3 at);
|
||||||
|
|
||||||
void lightingInit();
|
void lightingInit();
|
||||||
void lightingQuit();
|
void lightingQuit();
|
||||||
void lightingSave(PackStream* stream, LightingDefinition* definition);
|
void lightingSave(PackStream* stream, LightingDefinition* definition);
|
||||||
|
|
|
@ -11,7 +11,7 @@ HeightInfo _WATER_HEIGHT_INFO = {-1000000.0, -1000000.0, -1000000.0};
|
||||||
static void* _renderFirstPass(void* data)
|
static void* _renderFirstPass(void* data)
|
||||||
{
|
{
|
||||||
Renderer* renderer = (Renderer*)data;
|
Renderer* renderer = (Renderer*)data;
|
||||||
|
|
||||||
sceneryRenderFirstPass(renderer);
|
sceneryRenderFirstPass(renderer);
|
||||||
renderer->is_rendering = 0;
|
renderer->is_rendering = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -40,11 +40,11 @@ static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point)
|
||||||
static void _pushTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, f_RenderFragmentCallback callback, void* callback_data)
|
static void _pushTriangle(Renderer* renderer, Vector3 v1, Vector3 v2, Vector3 v3, f_RenderFragmentCallback callback, void* callback_data)
|
||||||
{
|
{
|
||||||
Vector3 p1, p2, p3;
|
Vector3 p1, p2, p3;
|
||||||
|
|
||||||
p1 = renderer->projectPoint(renderer, v1);
|
p1 = renderer->projectPoint(renderer, v1);
|
||||||
p2 = renderer->projectPoint(renderer, v2);
|
p2 = renderer->projectPoint(renderer, v2);
|
||||||
p3 = renderer->projectPoint(renderer, v3);
|
p3 = renderer->projectPoint(renderer, v3);
|
||||||
|
|
||||||
renderPushTriangle(renderer->render_area, p1, p2, p3, v1, v2, v3, callback, callback_data);
|
renderPushTriangle(renderer->render_area, p1, p2, p3, v1, v2, v3, callback, callback_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,11 +73,6 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector
|
||||||
return _RAYCASTING_NULL;
|
return _RAYCASTING_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HeightInfo _getWaterHeightInfo(Renderer* renderer)
|
static HeightInfo _getWaterHeightInfo(Renderer* renderer)
|
||||||
{
|
{
|
||||||
return _WATER_HEIGHT_INFO;
|
return _WATER_HEIGHT_INFO;
|
||||||
|
@ -107,7 +102,7 @@ Renderer rendererCreate()
|
||||||
result.render_camera = cameraCreateDefinition();
|
result.render_camera = cameraCreateDefinition();
|
||||||
result.camera_location = result.render_camera.location;
|
result.camera_location = result.render_camera.location;
|
||||||
result.render_area = renderCreateArea();
|
result.render_area = renderCreateArea();
|
||||||
|
|
||||||
renderSetParams(result.render_area, params);
|
renderSetParams(result.render_area, params);
|
||||||
|
|
||||||
result.addRenderProgress = _addRenderProgress;
|
result.addRenderProgress = _addRenderProgress;
|
||||||
|
@ -118,7 +113,6 @@ Renderer rendererCreate()
|
||||||
result.pushQuad = _pushQuad;
|
result.pushQuad = _pushQuad;
|
||||||
|
|
||||||
result.rayWalking = _rayWalking;
|
result.rayWalking = _rayWalking;
|
||||||
result.getTerrainHeight = _getTerrainHeight;
|
|
||||||
result.getWaterHeightInfo = _getWaterHeightInfo;
|
result.getWaterHeightInfo = _getWaterHeightInfo;
|
||||||
result.applyTextures = _applyTextures;
|
result.applyTextures = _applyTextures;
|
||||||
result.applyClouds = _applyClouds;
|
result.applyClouds = _applyClouds;
|
||||||
|
@ -126,8 +120,9 @@ Renderer rendererCreate()
|
||||||
result.alterLight = _alterLight;
|
result.alterLight = _alterLight;
|
||||||
result.getLightStatus = _getLightStatus;
|
result.getLightStatus = _getLightStatus;
|
||||||
result.applyLightStatus = _applyLightStatus;
|
result.applyLightStatus = _applyLightStatus;
|
||||||
|
|
||||||
result.atmosphere = AtmosphereRendererClass.create();
|
result.atmosphere = AtmosphereRendererClass.create();
|
||||||
|
result.terrain = TerrainRendererClass.create();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -135,6 +130,8 @@ Renderer rendererCreate()
|
||||||
void rendererDelete(Renderer* renderer)
|
void rendererDelete(Renderer* renderer)
|
||||||
{
|
{
|
||||||
AtmosphereRendererClass.destroy(renderer->atmosphere);
|
AtmosphereRendererClass.destroy(renderer->atmosphere);
|
||||||
|
TerrainRendererClass.destroy(renderer->terrain);
|
||||||
|
|
||||||
renderDeleteArea(renderer->render_area);
|
renderDeleteArea(renderer->render_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,13 +148,13 @@ void rendererStart(Renderer* renderer, RenderParams params)
|
||||||
|
|
||||||
params.antialias = (params.antialias < 1) ? 1 : params.antialias;
|
params.antialias = (params.antialias < 1) ? 1 : params.antialias;
|
||||||
params.antialias = (params.antialias > 4) ? 4 : params.antialias;
|
params.antialias = (params.antialias > 4) ? 4 : params.antialias;
|
||||||
|
|
||||||
renderer->render_quality = params.quality;
|
renderer->render_quality = params.quality;
|
||||||
renderer->render_width = params.width * params.antialias;
|
renderer->render_width = params.width * params.antialias;
|
||||||
renderer->render_height = params.height * params.antialias;
|
renderer->render_height = params.height * params.antialias;
|
||||||
renderer->render_interrupt = 0;
|
renderer->render_interrupt = 0;
|
||||||
renderer->render_progress = 0.0;
|
renderer->render_progress = 0.0;
|
||||||
|
|
||||||
cameraSetRenderSize(&renderer->render_camera, renderer->render_width, renderer->render_height);
|
cameraSetRenderSize(&renderer->render_camera, renderer->render_width, renderer->render_height);
|
||||||
renderer->camera_location = renderer->render_camera.location;
|
renderer->camera_location = renderer->render_camera.location;
|
||||||
|
|
||||||
|
@ -180,7 +177,7 @@ void rendererStart(Renderer* renderer, RenderParams params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
threadJoin(thread);
|
threadJoin(thread);
|
||||||
|
|
||||||
renderer->is_rendering = 1;
|
renderer->is_rendering = 1;
|
||||||
renderPostProcess(renderer->render_area, renderer, core_count);
|
renderPostProcess(renderer->render_area, renderer, core_count);
|
||||||
renderer->is_rendering = 0;
|
renderer->is_rendering = 0;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
#include "atmosphere/public.h"
|
#include "atmosphere/public.h"
|
||||||
|
#include "terrain/public.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -31,7 +32,6 @@ struct Renderer
|
||||||
|
|
||||||
/* Scenery related */
|
/* Scenery related */
|
||||||
RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds);
|
RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds);
|
||||||
double (*getTerrainHeight)(Renderer* renderer, double x, double z);
|
|
||||||
HeightInfo (*getWaterHeightInfo)(Renderer* renderer);
|
HeightInfo (*getWaterHeightInfo)(Renderer* renderer);
|
||||||
Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision);
|
Color (*applyTextures)(Renderer* renderer, Vector3 location, double precision);
|
||||||
Color (*applyClouds)(Renderer* renderer, Color base, Vector3 start, Vector3 end);
|
Color (*applyClouds)(Renderer* renderer, Color base, Vector3 start, Vector3 end);
|
||||||
|
@ -43,6 +43,7 @@ struct Renderer
|
||||||
|
|
||||||
/* Autonomous sub-renderers */
|
/* Autonomous sub-renderers */
|
||||||
AtmosphereRenderer* atmosphere;
|
AtmosphereRenderer* atmosphere;
|
||||||
|
TerrainRenderer* terrain;
|
||||||
|
|
||||||
/* Custom data */
|
/* Custom data */
|
||||||
void* customData[10];
|
void* customData[10];
|
||||||
|
|
|
@ -10,7 +10,7 @@ static AtmosphereDefinition* _atmosphere;
|
||||||
static CameraDefinition _camera;
|
static CameraDefinition _camera;
|
||||||
static CloudsDefinition _clouds;
|
static CloudsDefinition _clouds;
|
||||||
static LightingDefinition _lighting;
|
static LightingDefinition _lighting;
|
||||||
static TerrainDefinition _terrain;
|
static TerrainDefinition* _terrain;
|
||||||
static TexturesDefinition _textures;
|
static TexturesDefinition _textures;
|
||||||
static WaterDefinition _water;
|
static WaterDefinition _water;
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@ void sceneryInit()
|
||||||
_camera = cameraCreateDefinition();
|
_camera = cameraCreateDefinition();
|
||||||
_clouds = cloudsCreateDefinition();
|
_clouds = cloudsCreateDefinition();
|
||||||
_lighting = lightingCreateDefinition();
|
_lighting = lightingCreateDefinition();
|
||||||
_terrain = terrainCreateDefinition();
|
_terrain = TerrainDefinitionClass.create();
|
||||||
_textures = texturesCreateDefinition();
|
_textures = texturesCreateDefinition();
|
||||||
_water = waterCreateDefinition();
|
_water = waterCreateDefinition();
|
||||||
|
|
||||||
_custom_save = NULL;
|
_custom_save = NULL;
|
||||||
_custom_load = NULL;
|
_custom_load = NULL;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ void sceneryQuit()
|
||||||
cameraDeleteDefinition(&_camera);
|
cameraDeleteDefinition(&_camera);
|
||||||
cloudsDeleteDefinition(&_clouds);
|
cloudsDeleteDefinition(&_clouds);
|
||||||
lightingDeleteDefinition(&_lighting);
|
lightingDeleteDefinition(&_lighting);
|
||||||
terrainDeleteDefinition(&_terrain);
|
TerrainDefinitionClass.destroy(_terrain);
|
||||||
texturesDeleteDefinition(&_textures);
|
texturesDeleteDefinition(&_textures);
|
||||||
waterDeleteDefinition(&_water);
|
waterDeleteDefinition(&_water);
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ void scenerySave(PackStream* stream)
|
||||||
cameraSave(stream, &_camera);
|
cameraSave(stream, &_camera);
|
||||||
cloudsSave(stream, &_clouds);
|
cloudsSave(stream, &_clouds);
|
||||||
lightingSave(stream, &_lighting);
|
lightingSave(stream, &_lighting);
|
||||||
terrainSave(stream, &_terrain);
|
TerrainDefinitionClass.save(stream, _terrain);
|
||||||
texturesSave(stream, &_textures);
|
texturesSave(stream, &_textures);
|
||||||
waterSave(stream, &_water);
|
waterSave(stream, &_water);
|
||||||
|
|
||||||
if (_custom_save)
|
if (_custom_save)
|
||||||
{
|
{
|
||||||
_custom_save(stream, _custom_data);
|
_custom_save(stream, _custom_data);
|
||||||
|
@ -82,17 +82,16 @@ void sceneryLoad(PackStream* stream)
|
||||||
cameraLoad(stream, &_camera);
|
cameraLoad(stream, &_camera);
|
||||||
cloudsLoad(stream, &_clouds);
|
cloudsLoad(stream, &_clouds);
|
||||||
lightingLoad(stream, &_lighting);
|
lightingLoad(stream, &_lighting);
|
||||||
terrainLoad(stream, &_terrain);
|
TerrainDefinitionClass.load(stream, _terrain);
|
||||||
texturesLoad(stream, &_textures);
|
texturesLoad(stream, &_textures);
|
||||||
waterLoad(stream, &_water);
|
waterLoad(stream, &_water);
|
||||||
|
|
||||||
cameraValidateDefinition(&_camera, 0);
|
cameraValidateDefinition(&_camera, 0);
|
||||||
cloudsValidateDefinition(&_clouds);
|
cloudsValidateDefinition(&_clouds);
|
||||||
lightingValidateDefinition(&_lighting);
|
lightingValidateDefinition(&_lighting);
|
||||||
terrainValidateDefinition(&_terrain);
|
|
||||||
texturesValidateDefinition(&_textures);
|
texturesValidateDefinition(&_textures);
|
||||||
waterValidateDefinition(&_water);
|
waterValidateDefinition(&_water);
|
||||||
|
|
||||||
if (_custom_load)
|
if (_custom_load)
|
||||||
{
|
{
|
||||||
_custom_load(stream, _custom_data);
|
_custom_load(stream, _custom_data);
|
||||||
|
@ -102,7 +101,6 @@ void sceneryLoad(PackStream* stream)
|
||||||
void scenerySetAtmosphere(AtmosphereDefinition* atmosphere)
|
void scenerySetAtmosphere(AtmosphereDefinition* atmosphere)
|
||||||
{
|
{
|
||||||
AtmosphereDefinitionClass.copy(atmosphere, _atmosphere);
|
AtmosphereDefinitionClass.copy(atmosphere, _atmosphere);
|
||||||
AtmosphereDefinitionClass.validate(_atmosphere);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere)
|
void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere)
|
||||||
|
@ -145,15 +143,14 @@ void sceneryGetLighting(LightingDefinition* lighting)
|
||||||
|
|
||||||
void scenerySetTerrain(TerrainDefinition* terrain)
|
void scenerySetTerrain(TerrainDefinition* terrain)
|
||||||
{
|
{
|
||||||
terrainCopyDefinition(terrain, &_terrain);
|
TerrainDefinitionClass.copy(terrain, _terrain);
|
||||||
terrainValidateDefinition(&_terrain);
|
|
||||||
|
|
||||||
cameraValidateDefinition(&_camera, 1);
|
cameraValidateDefinition(&_camera, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sceneryGetTerrain(TerrainDefinition* terrain)
|
void sceneryGetTerrain(TerrainDefinition* terrain)
|
||||||
{
|
{
|
||||||
terrainCopyDefinition(&_terrain, terrain);
|
TerrainDefinitionClass.copy(_terrain, terrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scenerySetTextures(TexturesDefinition* textures)
|
void scenerySetTextures(TexturesDefinition* textures)
|
||||||
|
@ -182,7 +179,7 @@ void sceneryGetWater(WaterDefinition* water)
|
||||||
|
|
||||||
void sceneryRenderFirstPass(Renderer* renderer)
|
void sceneryRenderFirstPass(Renderer* renderer)
|
||||||
{
|
{
|
||||||
terrainRender(&_terrain, renderer);
|
terrainRenderSurface(renderer);
|
||||||
waterRender(&_water, renderer);
|
waterRender(&_water, renderer);
|
||||||
atmosphereRenderSkydome(renderer);
|
atmosphereRenderSkydome(renderer);
|
||||||
}
|
}
|
||||||
|
@ -197,10 +194,10 @@ static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 loca
|
||||||
{
|
{
|
||||||
Vector3 light_location;
|
Vector3 light_location;
|
||||||
Vector3 direction_to_light;
|
Vector3 direction_to_light;
|
||||||
|
|
||||||
direction_to_light = v3Normalize(v3Scale(light->direction, -1.0));
|
direction_to_light = v3Normalize(v3Scale(light->direction, -1.0));
|
||||||
light_location = v3Add(location, v3Scale(direction_to_light, 1000.0));
|
light_location = v3Add(location, v3Scale(direction_to_light, 1000.0));
|
||||||
|
|
||||||
if (light->filtered)
|
if (light->filtered)
|
||||||
{
|
{
|
||||||
// TODO atmosphere filter
|
// TODO atmosphere filter
|
||||||
|
@ -208,7 +205,7 @@ static void _alterLight(Renderer* renderer, LightDefinition* light, Vector3 loca
|
||||||
}
|
}
|
||||||
if (light->masked)
|
if (light->masked)
|
||||||
{
|
{
|
||||||
light->color = terrainLightFilter(&_terrain, renderer, light->color, location, light_location, direction_to_light);
|
*light = renderer->terrain->alterLight(renderer, light, location);
|
||||||
light->color = cloudsFilterLight(&_clouds, renderer, light->color, location, light_location, direction_to_light);
|
light->color = cloudsFilterLight(&_clouds, renderer, light->color, location, light_location, direction_to_light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,22 +225,19 @@ static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector
|
||||||
RayCastingResult result;
|
RayCastingResult result;
|
||||||
Color sky_color;
|
Color sky_color;
|
||||||
|
|
||||||
if (!terrainProjectRay(&_terrain, renderer, location, direction, &result.hit_location, &result.hit_color))
|
result = renderer->terrain->castRay(renderer, location, direction);
|
||||||
|
if (!result.hit)
|
||||||
{
|
{
|
||||||
sky_color = renderer->atmosphere->getSkyColor(renderer, direction);
|
sky_color = renderer->atmosphere->getSkyColor(renderer, direction);
|
||||||
|
|
||||||
|
result.hit = 1;
|
||||||
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
||||||
result.hit_color = renderer->applyClouds(renderer, sky_color, location, result.hit_location);
|
result.hit_color = renderer->applyClouds(renderer, sky_color, location, result.hit_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.hit = 1;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double _getTerrainHeight(Renderer* renderer, double x, double z)
|
|
||||||
{
|
|
||||||
return terrainGetHeight(&_terrain, x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HeightInfo _getWaterHeightInfo(Renderer* renderer)
|
static HeightInfo _getWaterHeightInfo(Renderer* renderer)
|
||||||
{
|
{
|
||||||
return waterGetHeightInfo(&_water);
|
return waterGetHeightInfo(&_water);
|
||||||
|
@ -283,7 +277,7 @@ static double _getPrecision(Renderer* renderer, Vector3 location)
|
||||||
Renderer sceneryCreateStandardRenderer()
|
Renderer sceneryCreateStandardRenderer()
|
||||||
{
|
{
|
||||||
Renderer result;
|
Renderer result;
|
||||||
|
|
||||||
result = rendererCreate();
|
result = rendererCreate();
|
||||||
|
|
||||||
cameraCopyDefinition(&_camera, &result.render_camera);
|
cameraCopyDefinition(&_camera, &result.render_camera);
|
||||||
|
@ -293,15 +287,15 @@ Renderer sceneryCreateStandardRenderer()
|
||||||
result.getLightStatus = _getLightStatus;
|
result.getLightStatus = _getLightStatus;
|
||||||
result.applyLightStatus = _applyLightStatus;
|
result.applyLightStatus = _applyLightStatus;
|
||||||
result.rayWalking = _rayWalking;
|
result.rayWalking = _rayWalking;
|
||||||
result.getTerrainHeight = _getTerrainHeight;
|
|
||||||
result.getWaterHeightInfo = _getWaterHeightInfo;
|
result.getWaterHeightInfo = _getWaterHeightInfo;
|
||||||
result.applyTextures = _applyTextures;
|
result.applyTextures = _applyTextures;
|
||||||
result.applyClouds = _applyClouds;
|
result.applyClouds = _applyClouds;
|
||||||
result.projectPoint = _projectPoint;
|
result.projectPoint = _projectPoint;
|
||||||
result.unprojectPoint = _unprojectPoint;
|
result.unprojectPoint = _unprojectPoint;
|
||||||
result.getPrecision = _getPrecision;
|
result.getPrecision = _getPrecision;
|
||||||
|
|
||||||
AtmosphereRendererClass.bind(result.atmosphere, _atmosphere);
|
AtmosphereRendererClass.bind(result.atmosphere, _atmosphere);
|
||||||
|
TerrainRendererClass.bind(result.terrain, _terrain);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "atmosphere/public.h"
|
#include "atmosphere/public.h"
|
||||||
|
#include "terrain/public.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "clouds.h"
|
#include "clouds.h"
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include "terrain.h"
|
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "water.h"
|
#include "water.h"
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
|
|
@ -51,7 +51,7 @@ typedef struct
|
||||||
Color hit_color;
|
Color hit_color;
|
||||||
Vector3 hit_location;
|
Vector3 hit_location;
|
||||||
} RayCastingResult;
|
} RayCastingResult;
|
||||||
typedef RayCastingResult (*RayCastingFunction)(Vector3 start, Vector3 direction);
|
typedef RayCastingResult (*FuncGeneralCastRay)(Renderer* renderer, Vector3 start, Vector3 direction);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -66,23 +66,46 @@ typedef struct
|
||||||
double yaw;
|
double yaw;
|
||||||
double pitch;
|
double pitch;
|
||||||
double roll;
|
double roll;
|
||||||
|
|
||||||
Vector3 target;
|
Vector3 target;
|
||||||
Vector3 forward;
|
Vector3 forward;
|
||||||
Vector3 right;
|
Vector3 right;
|
||||||
Vector3 up;
|
Vector3 up;
|
||||||
|
|
||||||
double width;
|
double width;
|
||||||
double height;
|
double height;
|
||||||
double yfov;
|
double yfov;
|
||||||
double xratio;
|
double xratio;
|
||||||
double znear;
|
double znear;
|
||||||
double zfar;
|
double zfar;
|
||||||
|
|
||||||
Matrix4 project;
|
Matrix4 project;
|
||||||
Matrix4 unproject;
|
Matrix4 unproject;
|
||||||
} CameraDefinition;
|
} CameraDefinition;
|
||||||
|
|
||||||
|
typedef void* (*FuncObjectCreate)();
|
||||||
|
typedef void (*FuncObjectDelete)(void* object);
|
||||||
|
typedef void (*FuncObjectCopy)(void* source, void* destination);
|
||||||
|
typedef void (*FuncObjectValidate)(void* object);
|
||||||
|
typedef void (*FuncObjectSave)(PackStream* stream, void* object);
|
||||||
|
typedef void (*FuncObjectLoad)(PackStream* stream, void* object);
|
||||||
|
typedef void (*FuncObjectBind)(void* base, void* sub);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FuncObjectCreate create;
|
||||||
|
FuncObjectDelete destroy;
|
||||||
|
FuncObjectCopy copy;
|
||||||
|
FuncObjectValidate validate;
|
||||||
|
FuncObjectSave save;
|
||||||
|
FuncObjectLoad load;
|
||||||
|
} StandardDefinition;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FuncObjectCreate create;
|
||||||
|
FuncObjectDelete destroy;
|
||||||
|
FuncObjectBind bind;
|
||||||
|
} StandardRenderer;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,390 +0,0 @@
|
||||||
#include "terrain.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "shared/types.h"
|
|
||||||
#include "euclid.h"
|
|
||||||
#include "render.h"
|
|
||||||
#include "textures.h"
|
|
||||||
#include "water.h"
|
|
||||||
#include "tools.h"
|
|
||||||
#include "layers.h"
|
|
||||||
#include "terraincanvas.h"
|
|
||||||
|
|
||||||
void terrainSave(PackStream* stream, TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
noiseSaveGenerator(stream, definition->height_noise);
|
|
||||||
packWriteDouble(stream, &definition->height_factor);
|
|
||||||
packWriteDouble(stream, &definition->scaling);
|
|
||||||
layersSave(stream, definition->canvases);
|
|
||||||
packWriteDouble(stream, &definition->shadow_smoothing);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainLoad(PackStream* stream, TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
noiseLoadGenerator(stream, definition->height_noise);
|
|
||||||
packReadDouble(stream, &definition->height_factor);
|
|
||||||
packReadDouble(stream, &definition->scaling);
|
|
||||||
layersLoad(stream, definition->canvases);
|
|
||||||
packReadDouble(stream, &definition->shadow_smoothing);
|
|
||||||
|
|
||||||
terrainValidateDefinition(definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
TerrainDefinition terrainCreateDefinition()
|
|
||||||
{
|
|
||||||
TerrainDefinition definition;
|
|
||||||
|
|
||||||
definition.height_noise = noiseCreateGenerator();
|
|
||||||
definition.height_factor = 0.0;
|
|
||||||
definition.scaling = 1.0;
|
|
||||||
definition.canvases = layersCreate(terrainCanvasGetLayerType(), 50);
|
|
||||||
definition.shadow_smoothing = 0.0;
|
|
||||||
|
|
||||||
terrainValidateDefinition(&definition);
|
|
||||||
|
|
||||||
return definition;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainDeleteDefinition(TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
noiseDeleteGenerator(definition->height_noise);
|
|
||||||
layersDelete(definition->canvases);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCopyDefinition(TerrainDefinition* source, TerrainDefinition* destination)
|
|
||||||
{
|
|
||||||
noiseCopy(source->height_noise, destination->height_noise);
|
|
||||||
destination->height_factor = source->height_factor;
|
|
||||||
destination->scaling = source->scaling;
|
|
||||||
layersCopy(source->canvases, destination->canvases);
|
|
||||||
destination->shadow_smoothing = source->shadow_smoothing;
|
|
||||||
|
|
||||||
terrainValidateDefinition(destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainValidateDefinition(TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
int i, n;
|
|
||||||
TerrainCanvas* canvas;
|
|
||||||
double min, max;
|
|
||||||
|
|
||||||
noiseValidate(definition->height_noise);
|
|
||||||
layersValidate(definition->canvases);
|
|
||||||
|
|
||||||
/* Get minimal and maximal height */
|
|
||||||
definition->_min_height = -noiseGetMaxValue(definition->height_noise) * definition->height_factor;
|
|
||||||
definition->_max_height = noiseGetMaxValue(definition->height_noise) * definition->height_factor;
|
|
||||||
|
|
||||||
n = layersCount(definition->canvases);
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
canvas = layersGetLayer(definition->canvases, i);
|
|
||||||
terrainCanvasGetLimits(canvas, &min, &max);
|
|
||||||
if (min < definition->_min_height)
|
|
||||||
{
|
|
||||||
definition->_min_height = min;
|
|
||||||
}
|
|
||||||
if (max > definition->_max_height)
|
|
||||||
{
|
|
||||||
definition->_max_height = max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double _getHeight(TerrainDefinition* definition, double x, double z)
|
|
||||||
{
|
|
||||||
TerrainCanvas* canvas;
|
|
||||||
Vector3 location;
|
|
||||||
int i, n;
|
|
||||||
|
|
||||||
location.x = x;
|
|
||||||
location.y = noiseGet2DTotal(definition->height_noise, x / definition->scaling, z / definition->scaling) * definition->height_factor;
|
|
||||||
location.z = z;
|
|
||||||
|
|
||||||
n = layersCount(definition->canvases);
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
canvas = layersGetLayer(definition->canvases, i);
|
|
||||||
location = terrainCanvasApply(canvas, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO Apply modifiers */
|
|
||||||
|
|
||||||
return location.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double _getHeightDetail(TerrainDefinition* definition, double x, double z, double detail)
|
|
||||||
{
|
|
||||||
TerrainCanvas* canvas;
|
|
||||||
Vector3 location;
|
|
||||||
int i, n;
|
|
||||||
|
|
||||||
location.x = x;
|
|
||||||
location.y = noiseGet2DDetail(definition->height_noise, x / definition->scaling, z / definition->scaling, detail / definition->height_factor) * definition->height_factor;
|
|
||||||
location.z = z;
|
|
||||||
|
|
||||||
n = layersCount(definition->canvases);
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
canvas = layersGetLayer(definition->canvases, i);
|
|
||||||
location = terrainCanvasApply(canvas, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO Apply modifiers */
|
|
||||||
|
|
||||||
return location.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Vector3 _getPoint(TerrainDefinition* definition, double x, double z)
|
|
||||||
{
|
|
||||||
Vector3 result;
|
|
||||||
|
|
||||||
result.x = x;
|
|
||||||
result.y = _getHeight(definition, x, z);
|
|
||||||
result.z = z;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color terrainLightFilter(TerrainDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light)
|
|
||||||
{
|
|
||||||
Vector3 inc_vector;
|
|
||||||
double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length;
|
|
||||||
|
|
||||||
direction_to_light = v3Normalize(direction_to_light);
|
|
||||||
if ((fabs(direction_to_light.x) < 0.0001 && fabs(direction_to_light.z) < 0.0001) || definition->height_factor < 0.001)
|
|
||||||
{
|
|
||||||
return light;
|
|
||||||
}
|
|
||||||
else if (direction_to_light.y < 0.05)
|
|
||||||
{
|
|
||||||
return COLOR_BLACK;
|
|
||||||
}
|
|
||||||
else if (direction_to_light.y < 0.0000)
|
|
||||||
{
|
|
||||||
light.r *= (0.05 + direction_to_light.y) / 0.05;
|
|
||||||
light.g *= (0.05 + direction_to_light.y) / 0.05;
|
|
||||||
light.b *= (0.05 + direction_to_light.y) / 0.05;
|
|
||||||
}
|
|
||||||
|
|
||||||
inc_factor = (double)renderer->render_quality;
|
|
||||||
inc_base = definition->height_factor / definition->scaling;
|
|
||||||
inc_value = inc_base / inc_factor;
|
|
||||||
smoothing = definition->shadow_smoothing;
|
|
||||||
|
|
||||||
light_factor = 1.0;
|
|
||||||
length = 0.0;
|
|
||||||
diff = 0.0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
inc_vector = v3Scale(direction_to_light, inc_value);
|
|
||||||
length += v3Norm(inc_vector);
|
|
||||||
location = v3Add(location, inc_vector);
|
|
||||||
height = _getHeightDetail(definition, location.x, location.z, diff / inc_factor);
|
|
||||||
diff = location.y - height;
|
|
||||||
if (diff < 0.0)
|
|
||||||
{
|
|
||||||
if (length * smoothing > 0.000001)
|
|
||||||
{
|
|
||||||
light_factor += diff * v3Norm(inc_vector) / (length * smoothing);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
light_factor = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (diff < inc_base / inc_factor)
|
|
||||||
{
|
|
||||||
inc_value = inc_base / inc_factor;
|
|
||||||
}
|
|
||||||
else if (diff > inc_base)
|
|
||||||
{
|
|
||||||
inc_value = inc_base;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inc_value = diff;
|
|
||||||
}
|
|
||||||
} while (light_factor > 0.0 && length < (10.0 * inc_factor) && location.y <= definition->_max_height);
|
|
||||||
|
|
||||||
if (light_factor <= 0.0)
|
|
||||||
{
|
|
||||||
return COLOR_BLACK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
light.r *= light_factor;
|
|
||||||
light.g *= light_factor;
|
|
||||||
light.b *= light_factor;
|
|
||||||
|
|
||||||
return light;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _getColor(TerrainDefinition* definition, Renderer* renderer, Vector3 point, double precision)
|
|
||||||
{
|
|
||||||
Color color;
|
|
||||||
|
|
||||||
color = renderer->applyTextures(renderer, point, precision);
|
|
||||||
color = renderer->atmosphere->applyAerialPerspective(renderer, point, color);
|
|
||||||
color = renderer->applyClouds(renderer, color, renderer->camera_location, point);
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
int terrainProjectRay(TerrainDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color)
|
|
||||||
{
|
|
||||||
Vector3 inc_vector;
|
|
||||||
double inc_value, inc_base, inc_factor, height, diff, lastdiff, length;
|
|
||||||
|
|
||||||
direction = v3Normalize(direction);
|
|
||||||
inc_factor = (double)renderer->render_quality;
|
|
||||||
inc_base = 1.0;
|
|
||||||
inc_value = inc_base / inc_factor;
|
|
||||||
lastdiff = start.y - _getHeight(definition, start.x, start.z);
|
|
||||||
|
|
||||||
length = 0.0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
inc_vector = v3Scale(direction, inc_value);
|
|
||||||
length += v3Norm(inc_vector);
|
|
||||||
start = v3Add(start, inc_vector);
|
|
||||||
height = _getHeight(definition, start.x, start.z);
|
|
||||||
diff = start.y - height;
|
|
||||||
if (diff < 0.0)
|
|
||||||
{
|
|
||||||
if (fabs(diff - lastdiff) > 0.00001)
|
|
||||||
{
|
|
||||||
start = v3Add(start, v3Scale(inc_vector, -diff / (diff - lastdiff)));
|
|
||||||
start.y = _getHeight(definition, start.x, start.z);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start.y = height;
|
|
||||||
}
|
|
||||||
*hit_point = start;
|
|
||||||
*hit_color = _getColor(definition, renderer, start, renderer->getPrecision(renderer, start));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (diff < inc_base / inc_factor)
|
|
||||||
{
|
|
||||||
inc_value = inc_base / inc_factor;
|
|
||||||
}
|
|
||||||
else if (diff > inc_base)
|
|
||||||
{
|
|
||||||
inc_value = inc_base;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inc_value = diff;
|
|
||||||
}
|
|
||||||
lastdiff = diff;
|
|
||||||
} while (length < 50.0 && start.y <= definition->_max_height);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Color _postProcessFragment(Renderer* renderer, Vector3 point, void* data)
|
|
||||||
{
|
|
||||||
double precision;
|
|
||||||
TerrainDefinition* definition;
|
|
||||||
|
|
||||||
definition = (TerrainDefinition*)data;
|
|
||||||
|
|
||||||
point = _getPoint(definition, point.x, point.z);
|
|
||||||
|
|
||||||
precision = renderer->getPrecision(renderer, point);
|
|
||||||
return _getColor(definition, renderer, point, precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, double x, double z, double size, double water_height)
|
|
||||||
{
|
|
||||||
Vector3 v1, v2, v3, v4;
|
|
||||||
|
|
||||||
v1 = _getPoint(definition, x, z);
|
|
||||||
v2 = _getPoint(definition, x, z + size);
|
|
||||||
v3 = _getPoint(definition, x + size, z + size);
|
|
||||||
v4 = _getPoint(definition, x + size, z);
|
|
||||||
|
|
||||||
if (v1.y > water_height || v2.y > water_height || v3.y > water_height || v4.y > water_height)
|
|
||||||
{
|
|
||||||
renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, definition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double terrainGetHeight(TerrainDefinition* definition, double x, double z)
|
|
||||||
{
|
|
||||||
return _getHeight(definition, x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
double terrainGetHeightNormalized(TerrainDefinition* definition, double x, double z)
|
|
||||||
{
|
|
||||||
if (definition->_max_height - definition->_min_height <= 0.0000001)
|
|
||||||
{
|
|
||||||
return 0.5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (_getHeight(definition, x, z) - definition->_min_height) / (definition->_max_height - definition->_min_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Color terrainGetColor(TerrainDefinition* definition, Renderer* renderer, double x, double z, double detail)
|
|
||||||
{
|
|
||||||
Vector3 point = _getPoint(definition, x, z);
|
|
||||||
return _getColor(definition, renderer, point, detail);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainRender(TerrainDefinition* definition, Renderer* renderer)
|
|
||||||
{
|
|
||||||
int chunk_factor, chunk_count, i;
|
|
||||||
double cx = renderer->camera_location.x;
|
|
||||||
double cz = renderer->camera_location.z;
|
|
||||||
double min_chunk_size, visible_chunk_size;
|
|
||||||
double radius_int, radius_ext, chunk_size;
|
|
||||||
double water_height;
|
|
||||||
|
|
||||||
min_chunk_size = 0.1 / (double)renderer->render_quality;
|
|
||||||
visible_chunk_size = 0.05 / (double)renderer->render_quality;
|
|
||||||
|
|
||||||
chunk_factor = 1;
|
|
||||||
chunk_count = 2;
|
|
||||||
radius_int = 0.0;
|
|
||||||
radius_ext = min_chunk_size;
|
|
||||||
chunk_size = min_chunk_size;
|
|
||||||
|
|
||||||
water_height = renderer->getWaterHeightInfo(renderer).max_height;
|
|
||||||
|
|
||||||
while (radius_ext < 1000.0)
|
|
||||||
{
|
|
||||||
if (!renderer->addRenderProgress(renderer, 0.0))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < chunk_count - 1; i++)
|
|
||||||
{
|
|
||||||
_renderQuad(definition, renderer, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size, water_height);
|
|
||||||
_renderQuad(definition, renderer, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size, water_height);
|
|
||||||
_renderQuad(definition, renderer, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size, water_height);
|
|
||||||
_renderQuad(definition, renderer, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size, water_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunk_count % 64 == 0 && chunk_size / radius_int < visible_chunk_size)
|
|
||||||
{
|
|
||||||
chunk_count /= 2;
|
|
||||||
chunk_factor *= 2;
|
|
||||||
/* TODO Fill in gaps with triangles */
|
|
||||||
}
|
|
||||||
chunk_count += 2;
|
|
||||||
chunk_size = min_chunk_size * chunk_factor;
|
|
||||||
radius_int = radius_ext;
|
|
||||||
radius_ext += chunk_size;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
#ifndef _PAYSAGES_TERRAIN_H_
|
|
||||||
#define _PAYSAGES_TERRAIN_H_
|
|
||||||
|
|
||||||
#include "shared/types.h"
|
|
||||||
#include "modifiers.h"
|
|
||||||
#include "noise.h"
|
|
||||||
#include "lighting.h"
|
|
||||||
#include "pack.h"
|
|
||||||
#include "layers.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TERRAIN_MAX_MODIFIERS 50
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
NoiseGenerator* height_noise;
|
|
||||||
double height_factor;
|
|
||||||
double scaling;
|
|
||||||
Layers* canvases;
|
|
||||||
double shadow_smoothing;
|
|
||||||
|
|
||||||
double _min_height;
|
|
||||||
double _max_height;
|
|
||||||
} TerrainDefinition;
|
|
||||||
|
|
||||||
void terrainSave(PackStream* stream, TerrainDefinition* definition);
|
|
||||||
void terrainLoad(PackStream* stream, TerrainDefinition* definition);
|
|
||||||
|
|
||||||
TerrainDefinition terrainCreateDefinition();
|
|
||||||
void terrainDeleteDefinition(TerrainDefinition* definition);
|
|
||||||
void terrainCopyDefinition(TerrainDefinition* source, TerrainDefinition* destination);
|
|
||||||
void terrainValidateDefinition(TerrainDefinition* definition);
|
|
||||||
|
|
||||||
Color terrainLightFilter(TerrainDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light);
|
|
||||||
int terrainProjectRay(TerrainDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color);
|
|
||||||
double terrainGetHeight(TerrainDefinition* definition, double x, double z);
|
|
||||||
double terrainGetHeightNormalized(TerrainDefinition* definition, double x, double z);
|
|
||||||
Color terrainGetColor(TerrainDefinition* definition, Renderer* renderer, double x, double z, double detail);
|
|
||||||
void terrainRender(TerrainDefinition* definition, Renderer* renderer);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
300
lib_paysages/terrain/main.c
Normal file
300
lib_paysages/terrain/main.c
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
#include "public.h"
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "../tools.h"
|
||||||
|
#include "../lighting.h"
|
||||||
|
#include "../renderer.h"
|
||||||
|
|
||||||
|
/******************** Definition ********************/
|
||||||
|
static void _validateDefinition(TerrainDefinition* definition)
|
||||||
|
{
|
||||||
|
noiseValidate(definition->_height_noise);
|
||||||
|
|
||||||
|
/* Get minimal and maximal height */
|
||||||
|
definition->_min_height = -noiseGetMaxValue(definition->_height_noise) * definition->height;
|
||||||
|
definition->_max_height = noiseGetMaxValue(definition->_height_noise) * definition->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TerrainDefinition* _createDefinition()
|
||||||
|
{
|
||||||
|
TerrainDefinition* definition = malloc(sizeof(TerrainDefinition));
|
||||||
|
|
||||||
|
definition->height = 0.0;
|
||||||
|
definition->scaling = 1.0;
|
||||||
|
definition->shadow_smoothing = 0.0;
|
||||||
|
definition->_height_noise = noiseCreateGenerator();
|
||||||
|
|
||||||
|
terrainAutoPreset(definition, TERRAIN_PRESET_STANDARD);
|
||||||
|
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _deleteDefinition(TerrainDefinition* definition)
|
||||||
|
{
|
||||||
|
noiseDeleteGenerator(definition->_height_noise);
|
||||||
|
free(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _copyDefinition(TerrainDefinition* source, TerrainDefinition* destination)
|
||||||
|
{
|
||||||
|
destination->height = source->height;
|
||||||
|
destination->scaling = source->scaling;
|
||||||
|
destination->shadow_smoothing = source->shadow_smoothing;
|
||||||
|
|
||||||
|
_validateDefinition(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _saveDefinition(PackStream* stream, TerrainDefinition* definition)
|
||||||
|
{
|
||||||
|
packWriteDouble(stream, &definition->height);
|
||||||
|
packWriteDouble(stream, &definition->scaling);
|
||||||
|
packWriteDouble(stream, &definition->shadow_smoothing);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _loadDefinition(PackStream* stream, TerrainDefinition* definition)
|
||||||
|
{
|
||||||
|
packReadDouble(stream, &definition->height);
|
||||||
|
packReadDouble(stream, &definition->scaling);
|
||||||
|
packReadDouble(stream, &definition->shadow_smoothing);
|
||||||
|
|
||||||
|
_validateDefinition(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardDefinition TerrainDefinitionClass = {
|
||||||
|
(FuncObjectCreate)_createDefinition,
|
||||||
|
(FuncObjectDelete)_deleteDefinition,
|
||||||
|
(FuncObjectCopy)_copyDefinition,
|
||||||
|
(FuncObjectValidate)_validateDefinition,
|
||||||
|
(FuncObjectSave)_saveDefinition,
|
||||||
|
(FuncObjectLoad)_loadDefinition
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************** Binding ********************/
|
||||||
|
static double _fakeGetHeight(Renderer* renderer, double x, double z)
|
||||||
|
{
|
||||||
|
UNUSED(renderer);
|
||||||
|
UNUSED(x);
|
||||||
|
UNUSED(z);
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double _getHeight(Renderer* renderer, double x, double z)
|
||||||
|
{
|
||||||
|
TerrainDefinition* definition = renderer->terrain->definition;
|
||||||
|
return noiseGet2DTotal(definition->_height_noise, x / definition->scaling, z / definition->scaling) * definition->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color _fakeGetFinalColor(Renderer* renderer, Vector3 location, double precision)
|
||||||
|
{
|
||||||
|
return COLOR_GREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color _getFinalColor(Renderer* renderer, Vector3 location, double precision)
|
||||||
|
{
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
color = renderer->applyTextures(renderer, location, precision);
|
||||||
|
|
||||||
|
/* TODO Factorize this in scenery renderer */
|
||||||
|
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
|
||||||
|
color = renderer->applyClouds(renderer, color, renderer->camera_location, location);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
RayCastingResult _fakeCastRay(Renderer* renderer, Vector3 start, Vector3 direction)
|
||||||
|
{
|
||||||
|
UNUSED(renderer);
|
||||||
|
UNUSED(start);
|
||||||
|
UNUSED(direction);
|
||||||
|
|
||||||
|
RayCastingResult result;
|
||||||
|
result.hit = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
RayCastingResult _castRay(Renderer* renderer, Vector3 start, Vector3 direction)
|
||||||
|
{
|
||||||
|
RayCastingResult result;
|
||||||
|
TerrainDefinition* definition = renderer->terrain->definition;
|
||||||
|
Vector3 inc_vector;
|
||||||
|
double inc_value, inc_base, inc_factor, height, diff, lastdiff, length;
|
||||||
|
|
||||||
|
direction = v3Normalize(direction);
|
||||||
|
inc_factor = (double)renderer->render_quality;
|
||||||
|
inc_base = 1.0;
|
||||||
|
inc_value = inc_base / inc_factor;
|
||||||
|
lastdiff = start.y - _getHeight(renderer, start.x, start.z);
|
||||||
|
|
||||||
|
length = 0.0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
inc_vector = v3Scale(direction, inc_value);
|
||||||
|
length += v3Norm(inc_vector);
|
||||||
|
start = v3Add(start, inc_vector);
|
||||||
|
height = _getHeight(renderer, start.x, start.z);
|
||||||
|
diff = start.y - height;
|
||||||
|
if (diff < 0.0)
|
||||||
|
{
|
||||||
|
if (fabs(diff - lastdiff) > 0.00001)
|
||||||
|
{
|
||||||
|
start = v3Add(start, v3Scale(inc_vector, -diff / (diff - lastdiff)));
|
||||||
|
start.y = _getHeight(renderer, start.x, start.z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start.y = height;
|
||||||
|
}
|
||||||
|
result.hit = 1;
|
||||||
|
result.hit_location = start;
|
||||||
|
result.hit_color = _getFinalColor(renderer, start, renderer->getPrecision(renderer, result.hit_location));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff < inc_base / inc_factor)
|
||||||
|
{
|
||||||
|
inc_value = inc_base / inc_factor;
|
||||||
|
}
|
||||||
|
else if (diff > inc_base)
|
||||||
|
{
|
||||||
|
inc_value = inc_base;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inc_value = diff;
|
||||||
|
}
|
||||||
|
lastdiff = diff;
|
||||||
|
} while (length < 50.0 && start.y <= definition->_max_height);
|
||||||
|
|
||||||
|
result.hit = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LightDefinition _fakeAlterLight(Renderer* renderer, LightDefinition* light, Vector3 at)
|
||||||
|
{
|
||||||
|
UNUSED(renderer);
|
||||||
|
UNUSED(at);
|
||||||
|
|
||||||
|
return *light;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LightDefinition _alterLight(Renderer* renderer, LightDefinition* light, Vector3 location)
|
||||||
|
{
|
||||||
|
TerrainDefinition* definition = renderer->terrain->definition;
|
||||||
|
LightDefinition result = *light;
|
||||||
|
Vector3 inc_vector, direction_to_light;
|
||||||
|
double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length;
|
||||||
|
|
||||||
|
direction_to_light = v3Scale(light->direction, -1.0);
|
||||||
|
if ((fabs(direction_to_light.x) < 0.0001 && fabs(direction_to_light.z) < 0.0001) || definition->height < 0.001)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (direction_to_light.y < 0.05)
|
||||||
|
{
|
||||||
|
result.color = COLOR_BLACK;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (direction_to_light.y < 0.0000)
|
||||||
|
{
|
||||||
|
result.color.r *= (0.05 + direction_to_light.y) / 0.05;
|
||||||
|
result.color.g *= (0.05 + direction_to_light.y) / 0.05;
|
||||||
|
result.color.b *= (0.05 + direction_to_light.y) / 0.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
inc_factor = (double)renderer->render_quality;
|
||||||
|
inc_base = definition->height / definition->scaling;
|
||||||
|
inc_value = inc_base / inc_factor;
|
||||||
|
smoothing = definition->shadow_smoothing;
|
||||||
|
|
||||||
|
light_factor = 1.0;
|
||||||
|
length = 0.0;
|
||||||
|
diff = 0.0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
inc_vector = v3Scale(direction_to_light, inc_value);
|
||||||
|
length += v3Norm(inc_vector);
|
||||||
|
location = v3Add(location, inc_vector);
|
||||||
|
height = _getHeight(renderer, location.x, location.z);
|
||||||
|
diff = location.y - height;
|
||||||
|
if (diff < 0.0)
|
||||||
|
{
|
||||||
|
if (length * smoothing > 0.000001)
|
||||||
|
{
|
||||||
|
light_factor += diff * v3Norm(inc_vector) / (length * smoothing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
light_factor = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff < inc_base / inc_factor)
|
||||||
|
{
|
||||||
|
inc_value = inc_base / inc_factor;
|
||||||
|
}
|
||||||
|
else if (diff > inc_base)
|
||||||
|
{
|
||||||
|
inc_value = inc_base;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inc_value = diff;
|
||||||
|
}
|
||||||
|
} while (light_factor > 0.0 && length < (10.0 * inc_factor) && location.y <= definition->_max_height);
|
||||||
|
|
||||||
|
if (light_factor <= 0.0)
|
||||||
|
{
|
||||||
|
result.color = COLOR_BLACK;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.color.r *= light_factor;
|
||||||
|
result.color.g *= light_factor;
|
||||||
|
result.color.b *= light_factor;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************** Renderer ********************/
|
||||||
|
static TerrainRenderer* _createRenderer()
|
||||||
|
{
|
||||||
|
TerrainRenderer* result;
|
||||||
|
|
||||||
|
result = malloc(sizeof(TerrainRenderer));
|
||||||
|
result->definition = TerrainDefinitionClass.create();
|
||||||
|
|
||||||
|
result->castRay = _fakeCastRay;
|
||||||
|
result->alterLight = _fakeAlterLight;
|
||||||
|
result->getHeight = _fakeGetHeight;
|
||||||
|
result->getFinalColor = _fakeGetFinalColor;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _deleteRenderer(TerrainRenderer* renderer)
|
||||||
|
{
|
||||||
|
TerrainDefinitionClass.destroy(renderer->definition);
|
||||||
|
free(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _bindRenderer(TerrainRenderer* renderer, TerrainDefinition* definition)
|
||||||
|
{
|
||||||
|
TerrainDefinitionClass.copy(definition, renderer->definition);
|
||||||
|
|
||||||
|
renderer->castRay = _castRay;
|
||||||
|
renderer->alterLight = _alterLight;
|
||||||
|
renderer->getHeight = _getHeight;
|
||||||
|
renderer->getFinalColor = _getFinalColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardRenderer TerrainRendererClass = {
|
||||||
|
(FuncObjectCreate)_createRenderer,
|
||||||
|
(FuncObjectDelete)_deleteRenderer,
|
||||||
|
(FuncObjectBind)_bindRenderer
|
||||||
|
};
|
25
lib_paysages/terrain/presets.c
Normal file
25
lib_paysages/terrain/presets.c
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include "public.h"
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Terrain presets.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset)
|
||||||
|
{
|
||||||
|
switch (preset)
|
||||||
|
{
|
||||||
|
case TERRAIN_PRESET_STANDARD:
|
||||||
|
noiseClearLevels(definition->_height_noise);
|
||||||
|
noiseAddLevelsSimple(definition->_height_noise, 10, 1.0, 1.0);
|
||||||
|
noiseSetFunctionParams(definition->_height_noise, NOISE_FUNCTION_SIMPLEX, -0.2);
|
||||||
|
definition->height = 12.0 / noiseGetMaxValue(definition->_height_noise);
|
||||||
|
definition->scaling = 80.0;
|
||||||
|
definition->shadow_smoothing = 0.03;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
TerrainDefinitionClass.validate(definition);
|
||||||
|
}
|
4
lib_paysages/terrain/private.h
Normal file
4
lib_paysages/terrain/private.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#ifndef _PAYSAGES_TERRAIN_PRIVATE_H_
|
||||||
|
#define _PAYSAGES_TERRAIN_PRIVATE_H_
|
||||||
|
|
||||||
|
#endif
|
56
lib_paysages/terrain/public.h
Normal file
56
lib_paysages/terrain/public.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef _PAYSAGES_TERRAIN_PUBLIC_H_
|
||||||
|
#define _PAYSAGES_TERRAIN_PUBLIC_H_
|
||||||
|
|
||||||
|
#include "../shared/types.h"
|
||||||
|
#include "../noise.h"
|
||||||
|
#include "../lighting.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TERRAIN_PRESET_STANDARD
|
||||||
|
} TerrainPreset;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
double height;
|
||||||
|
double scaling;
|
||||||
|
double shadow_smoothing;
|
||||||
|
|
||||||
|
double _detail;
|
||||||
|
NoiseGenerator* _height_noise;
|
||||||
|
double _min_height;
|
||||||
|
double _max_height;
|
||||||
|
} TerrainDefinition;
|
||||||
|
|
||||||
|
typedef double (*FuncTerrainGetHeight)(Renderer* renderer, double x, double z);
|
||||||
|
typedef Color (*FuncTerrainGetFinalColor)(Renderer* renderer, Vector3 location, double precision);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
TerrainDefinition* definition;
|
||||||
|
|
||||||
|
FuncGeneralCastRay castRay;
|
||||||
|
FuncLightingAlterLight alterLight;
|
||||||
|
FuncTerrainGetHeight getHeight;
|
||||||
|
FuncTerrainGetFinalColor getFinalColor;
|
||||||
|
|
||||||
|
void* _internal_data;
|
||||||
|
} TerrainRenderer;
|
||||||
|
|
||||||
|
extern StandardDefinition TerrainDefinitionClass;
|
||||||
|
extern StandardRenderer TerrainRendererClass;
|
||||||
|
|
||||||
|
void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset);
|
||||||
|
void terrainRenderSurface(Renderer* renderer);
|
||||||
|
/*Renderer terrainCreatePreviewRenderer();
|
||||||
|
Color terrainGetPreview(Renderer* renderer, double x, double y);*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
94
lib_paysages/terrain/raster.c
Normal file
94
lib_paysages/terrain/raster.c
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#include "public.h"
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../renderer.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Terrain rasterization.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline Vector3 _getPoint(TerrainDefinition* definition, Renderer* renderer, double x, double z)
|
||||||
|
{
|
||||||
|
Vector3 result;
|
||||||
|
|
||||||
|
result.x = x;
|
||||||
|
result.y = renderer->terrain->getHeight(renderer, x, z);
|
||||||
|
result.z = z;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color _postProcessFragment(Renderer* renderer, Vector3 point, void* data)
|
||||||
|
{
|
||||||
|
double precision;
|
||||||
|
|
||||||
|
point = _getPoint(renderer->terrain->definition, renderer, point.x, point.z);
|
||||||
|
|
||||||
|
precision = renderer->getPrecision(renderer, point);
|
||||||
|
return renderer->terrain->getFinalColor(renderer, point, precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, double x, double z, double size, double water_height)
|
||||||
|
{
|
||||||
|
Vector3 v1, v2, v3, v4;
|
||||||
|
|
||||||
|
v1 = _getPoint(definition, renderer, x, z);
|
||||||
|
v2 = _getPoint(definition, renderer, x, z + size);
|
||||||
|
v3 = _getPoint(definition, renderer, x + size, z + size);
|
||||||
|
v4 = _getPoint(definition, renderer, x + size, z);
|
||||||
|
|
||||||
|
if (v1.y > water_height || v2.y > water_height || v3.y > water_height || v4.y > water_height)
|
||||||
|
{
|
||||||
|
renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void terrainRenderSurface(Renderer* renderer)
|
||||||
|
{
|
||||||
|
int chunk_factor, chunk_count, i;
|
||||||
|
double cx = renderer->camera_location.x;
|
||||||
|
double cz = renderer->camera_location.z;
|
||||||
|
double min_chunk_size, visible_chunk_size;
|
||||||
|
double radius_int, radius_ext, chunk_size;
|
||||||
|
double water_height;
|
||||||
|
TerrainDefinition* definition = renderer->terrain->definition;
|
||||||
|
|
||||||
|
min_chunk_size = 0.1 / (double)renderer->render_quality;
|
||||||
|
visible_chunk_size = 0.05 / (double)renderer->render_quality;
|
||||||
|
|
||||||
|
chunk_factor = 1;
|
||||||
|
chunk_count = 2;
|
||||||
|
radius_int = 0.0;
|
||||||
|
radius_ext = min_chunk_size;
|
||||||
|
chunk_size = min_chunk_size;
|
||||||
|
|
||||||
|
water_height = renderer->getWaterHeightInfo(renderer).max_height;
|
||||||
|
|
||||||
|
while (radius_ext < 1000.0)
|
||||||
|
{
|
||||||
|
if (!renderer->addRenderProgress(renderer, 0.0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < chunk_count - 1; i++)
|
||||||
|
{
|
||||||
|
_renderQuad(definition, renderer, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size, water_height);
|
||||||
|
_renderQuad(definition, renderer, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size, water_height);
|
||||||
|
_renderQuad(definition, renderer, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size, water_height);
|
||||||
|
_renderQuad(definition, renderer, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size, water_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunk_count % 64 == 0 && chunk_size / radius_int < visible_chunk_size)
|
||||||
|
{
|
||||||
|
chunk_count /= 2;
|
||||||
|
chunk_factor *= 2;
|
||||||
|
/* TODO Fill in gaps with triangles */
|
||||||
|
}
|
||||||
|
chunk_count += 2;
|
||||||
|
chunk_size = min_chunk_size * chunk_factor;
|
||||||
|
radius_int = radius_ext;
|
||||||
|
radius_ext += chunk_size;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,175 +0,0 @@
|
||||||
#include "terraincanvas.h"
|
|
||||||
#include "scenery.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
TerrainCanvas* terrainCanvasCreate()
|
|
||||||
{
|
|
||||||
TerrainCanvas* result = malloc(sizeof(TerrainCanvas));
|
|
||||||
|
|
||||||
result->area = geoareaCreate();
|
|
||||||
result->offset_y = 0.0;
|
|
||||||
result->height_map = heightmapCreate();
|
|
||||||
heightmapChangeResolution(&result->height_map, 256, 256);
|
|
||||||
result->height_factor = 1.0;
|
|
||||||
result->detail_noise = noiseCreateGenerator();
|
|
||||||
noiseAddLevelsSimple(result->detail_noise, 5, 1.0, 1.0);
|
|
||||||
result->detail_height_factor = 0.2;
|
|
||||||
result->detail_scaling = 0.4;
|
|
||||||
result->mask.mode = INTEGRATIONMASK_MODE_CIRCLE;
|
|
||||||
result->mask.smoothing = 0.1;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCanvasDelete(TerrainCanvas* canvas)
|
|
||||||
{
|
|
||||||
heightmapDelete(&canvas->height_map);
|
|
||||||
noiseDeleteGenerator(canvas->detail_noise);
|
|
||||||
free(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination)
|
|
||||||
{
|
|
||||||
geoareaCopy(&source->area, &destination->area);
|
|
||||||
destination->offset_y = source->offset_y;
|
|
||||||
destination->height_factor = source->height_factor;
|
|
||||||
heightmapCopy(&source->height_map, &destination->height_map);
|
|
||||||
noiseCopy(source->detail_noise, destination->detail_noise);
|
|
||||||
destination->detail_height_factor = source->detail_height_factor;
|
|
||||||
destination->detail_scaling = source->detail_scaling;
|
|
||||||
destination->mask = source->mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCanvasValidate(TerrainCanvas* canvas)
|
|
||||||
{
|
|
||||||
if (canvas->detail_scaling < 0.00001)
|
|
||||||
{
|
|
||||||
canvas->detail_scaling = 0.00001;
|
|
||||||
}
|
|
||||||
geoareaValidate(&canvas->area);
|
|
||||||
heightmapValidate(&canvas->height_map);
|
|
||||||
noiseValidate(canvas->detail_noise);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerType terrainCanvasGetLayerType()
|
|
||||||
{
|
|
||||||
LayerType result;
|
|
||||||
|
|
||||||
result.callback_create = (LayerCallbackCreate)terrainCanvasCreate;
|
|
||||||
result.callback_delete = (LayerCallbackDelete)terrainCanvasDelete;
|
|
||||||
result.callback_copy = (LayerCallbackCopy)terrainCanvasCopy;
|
|
||||||
result.callback_validate = (LayerCallbackValidate)terrainCanvasValidate;
|
|
||||||
result.callback_save = (LayerCallbackSave)terrainCanvasSave;
|
|
||||||
result.callback_load = (LayerCallbackLoad)terrainCanvasLoad;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas)
|
|
||||||
{
|
|
||||||
geoareaSave(stream, &canvas->area);
|
|
||||||
packWriteDouble(stream, &canvas->offset_y);
|
|
||||||
heightmapSave(stream, &canvas->height_map);
|
|
||||||
packWriteDouble(stream, &canvas->height_factor);
|
|
||||||
noiseSaveGenerator(stream, canvas->detail_noise);
|
|
||||||
packWriteDouble(stream, &canvas->detail_height_factor);
|
|
||||||
packWriteDouble(stream, &canvas->detail_scaling);
|
|
||||||
packWriteInt(stream, &canvas->mask.mode);
|
|
||||||
packWriteDouble(stream, &canvas->mask.smoothing);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCanvasLoad(PackStream* stream, TerrainCanvas* canvas)
|
|
||||||
{
|
|
||||||
geoareaLoad(stream, &canvas->area);
|
|
||||||
packReadDouble(stream, &canvas->offset_y);
|
|
||||||
heightmapLoad(stream, &canvas->height_map);
|
|
||||||
packReadDouble(stream, &canvas->height_factor);
|
|
||||||
noiseLoadGenerator(stream, canvas->detail_noise);
|
|
||||||
packReadDouble(stream, &canvas->detail_height_factor);
|
|
||||||
packReadDouble(stream, &canvas->detail_scaling);
|
|
||||||
packReadInt(stream, &canvas->mask.mode);
|
|
||||||
packReadDouble(stream, &canvas->mask.smoothing);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCanvasGetLimits(TerrainCanvas* canvas, double* ymin, double* ymax)
|
|
||||||
{
|
|
||||||
double noise_max = noiseGetMaxValue(canvas->detail_noise) * canvas->detail_height_factor;
|
|
||||||
heightmapGetLimits(&canvas->height_map, ymin, ymax);
|
|
||||||
*ymin -= noise_max;
|
|
||||||
*ymax += noise_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainCanvasRevertToTerrain(TerrainCanvas* canvas)
|
|
||||||
{
|
|
||||||
TerrainDefinition terrain;
|
|
||||||
|
|
||||||
terrain = terrainCreateDefinition();
|
|
||||||
sceneryGetTerrain(&terrain);
|
|
||||||
|
|
||||||
heightmapRevertToTerrain(&canvas->height_map, &terrain, &canvas->area);
|
|
||||||
|
|
||||||
terrainDeleteDefinition(&terrain);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location)
|
|
||||||
{
|
|
||||||
if (location.x >= canvas->area.location_x &&
|
|
||||||
location.z >= canvas->area.location_z &&
|
|
||||||
location.x <= canvas->area.location_x + canvas->area.size_x &&
|
|
||||||
location.z <= canvas->area.location_z + canvas->area.size_z)
|
|
||||||
{
|
|
||||||
double inside_x, inside_z;
|
|
||||||
double height;
|
|
||||||
|
|
||||||
/* Get height map displacement */
|
|
||||||
geoareaToLocal(&canvas->area, location.x, location.z, &inside_x, &inside_z);
|
|
||||||
height = heightmapGetValue(&canvas->height_map, inside_x, inside_z);
|
|
||||||
|
|
||||||
/* Apply factor */
|
|
||||||
height = height * canvas->height_factor + canvas->offset_y;
|
|
||||||
|
|
||||||
/* Apply detail noise */
|
|
||||||
height += noiseGet2DTotal(canvas->detail_noise, location.x / canvas->detail_scaling, location.z / canvas->detail_scaling) * canvas->detail_height_factor;
|
|
||||||
|
|
||||||
/* Apply integration mask */
|
|
||||||
double influence = terrainCanvasGetMaskValue(canvas, inside_x, inside_z);
|
|
||||||
location.y = influence * height + (1.0 - influence) * location.y;
|
|
||||||
|
|
||||||
}
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
double terrainCanvasGetMaskValue(TerrainCanvas* canvas, double local_x, double local_z)
|
|
||||||
{
|
|
||||||
double distance;
|
|
||||||
|
|
||||||
local_x = (local_x - 0.5) * 2.0;
|
|
||||||
local_z = (local_z - 0.5) * 2.0;
|
|
||||||
|
|
||||||
if (canvas->mask.mode == INTEGRATIONMASK_MODE_SQUARE)
|
|
||||||
{
|
|
||||||
local_x = fabs(local_x);
|
|
||||||
local_z = fabs(local_z);
|
|
||||||
distance = local_x > local_z ? local_x : local_z;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
distance = sqrt(local_x * local_x + local_z * local_z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance <= 1.0 - canvas->mask.smoothing)
|
|
||||||
{
|
|
||||||
return 1.0;
|
|
||||||
}
|
|
||||||
else if (distance <= 1.0)
|
|
||||||
{
|
|
||||||
return (1.0 - distance) / canvas->mask.smoothing;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
#ifndef _PAYSAGES_TERRAINCANVAS_H_
|
|
||||||
#define _PAYSAGES_TERRAINCANVAS_H_
|
|
||||||
|
|
||||||
/* Terrain edition by painting over an area */
|
|
||||||
|
|
||||||
#include "pack.h"
|
|
||||||
#include "noise.h"
|
|
||||||
#include "terrain.h"
|
|
||||||
#include "layers.h"
|
|
||||||
#include "heightmap.h"
|
|
||||||
#include "geoarea.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int mode;
|
|
||||||
double smoothing;
|
|
||||||
} IntegrationMask;
|
|
||||||
|
|
||||||
#define INTEGRATIONMASK_MODE_SQUARE 0
|
|
||||||
#define INTEGRATIONMASK_MODE_CIRCLE 1
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GeoArea area;
|
|
||||||
double offset_y;
|
|
||||||
HeightMap height_map;
|
|
||||||
double height_factor;
|
|
||||||
NoiseGenerator* detail_noise;
|
|
||||||
double detail_height_factor;
|
|
||||||
double detail_scaling;
|
|
||||||
IntegrationMask mask;
|
|
||||||
} TerrainCanvas;
|
|
||||||
|
|
||||||
TerrainCanvas* terrainCanvasCreate();
|
|
||||||
void terrainCanvasDelete(TerrainCanvas* canvas);
|
|
||||||
void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination);
|
|
||||||
void terrainCanvasValidate(TerrainCanvas* canvas);
|
|
||||||
LayerType terrainCanvasGetLayerType();
|
|
||||||
|
|
||||||
void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas);
|
|
||||||
void terrainCanvasLoad(PackStream* stream, TerrainCanvas* canvas);
|
|
||||||
|
|
||||||
void terrainCanvasGetLimits(TerrainCanvas* canvas, double* ymin, double* ymax);
|
|
||||||
void terrainCanvasRevertToTerrain(TerrainCanvas* canvas);
|
|
||||||
Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location);
|
|
||||||
double terrainCanvasGetMaskValue(TerrainCanvas* canvas, double local_x, double local_z);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -6,10 +6,11 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
|
#include "terrain/public.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "euclid.h"
|
#include "euclid.h"
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include "terrain.h"
|
#include "renderer.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define TEXTURES_MAX_LAYERS 50
|
#define TEXTURES_MAX_LAYERS 50
|
||||||
|
@ -61,7 +62,7 @@ TextureLayerDefinition* texturesLayerCreateDefinition()
|
||||||
TextureLayerDefinition* result;
|
TextureLayerDefinition* result;
|
||||||
|
|
||||||
result = malloc(sizeof(TextureLayerDefinition));
|
result = malloc(sizeof(TextureLayerDefinition));
|
||||||
|
|
||||||
result->zone = zoneCreate();
|
result->zone = zoneCreate();
|
||||||
result->bump_noise = noiseCreateGenerator();
|
result->bump_noise = noiseCreateGenerator();
|
||||||
noiseAddLevelsSimple(result->bump_noise, 8, 1.0, 1.0);
|
noiseAddLevelsSimple(result->bump_noise, 8, 1.0, 1.0);
|
||||||
|
@ -135,31 +136,31 @@ static void _texturesLayerLoad(PackStream* stream, TextureLayerDefinition* layer
|
||||||
LayerType texturesGetLayerType()
|
LayerType texturesGetLayerType()
|
||||||
{
|
{
|
||||||
LayerType result;
|
LayerType result;
|
||||||
|
|
||||||
result.callback_create = (LayerCallbackCreate)texturesLayerCreateDefinition;
|
result.callback_create = (LayerCallbackCreate)texturesLayerCreateDefinition;
|
||||||
result.callback_delete = (LayerCallbackDelete)texturesLayerDeleteDefinition;
|
result.callback_delete = (LayerCallbackDelete)texturesLayerDeleteDefinition;
|
||||||
result.callback_copy = (LayerCallbackCopy)texturesLayerCopyDefinition;
|
result.callback_copy = (LayerCallbackCopy)texturesLayerCopyDefinition;
|
||||||
result.callback_validate = (LayerCallbackValidate)texturesLayerValidateDefinition;
|
result.callback_validate = (LayerCallbackValidate)texturesLayerValidateDefinition;
|
||||||
result.callback_save = (LayerCallbackSave)_texturesLayerSave;
|
result.callback_save = (LayerCallbackSave)_texturesLayerSave;
|
||||||
result.callback_load = (LayerCallbackLoad)_texturesLayerLoad;
|
result.callback_load = (LayerCallbackLoad)_texturesLayerLoad;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
|
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
|
||||||
{
|
{
|
||||||
Vector3 dnorth, deast, dsouth, dwest, normal;
|
Vector3 dnorth, deast, dsouth, dwest, normal;
|
||||||
|
|
||||||
dnorth = v3Sub(north, center);
|
dnorth = v3Sub(north, center);
|
||||||
deast = v3Sub(east, center);
|
deast = v3Sub(east, center);
|
||||||
dsouth = v3Sub(south, center);
|
dsouth = v3Sub(south, center);
|
||||||
dwest = v3Sub(west, center);
|
dwest = v3Sub(west, center);
|
||||||
|
|
||||||
normal = v3Cross(deast, dnorth);
|
normal = v3Cross(deast, dnorth);
|
||||||
normal = v3Add(normal, v3Cross(dsouth, deast));
|
normal = v3Add(normal, v3Cross(dsouth, deast));
|
||||||
normal = v3Add(normal, v3Cross(dwest, dsouth));
|
normal = v3Add(normal, v3Cross(dwest, dsouth));
|
||||||
normal = v3Add(normal, v3Cross(dnorth, dwest));
|
normal = v3Add(normal, v3Cross(dnorth, dwest));
|
||||||
|
|
||||||
return v3Normalize(normal);
|
return v3Normalize(normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,30 +173,30 @@ static inline TextureResult _getTerrainResult(Renderer* renderer, double x, doub
|
||||||
{
|
{
|
||||||
TextureResult result;
|
TextureResult result;
|
||||||
Vector3 center, north, east, south, west;
|
Vector3 center, north, east, south, west;
|
||||||
|
|
||||||
/* TODO This method is better suited in terrain.c */
|
/* TODO This method is better suited in terrain.c */
|
||||||
|
|
||||||
center.x = x;
|
center.x = x;
|
||||||
center.z = z;
|
center.z = z;
|
||||||
center.y = renderer->getTerrainHeight(renderer, center.x, center.z);
|
center.y = renderer->terrain->getHeight(renderer, center.x, center.z);
|
||||||
|
|
||||||
east.x = x + detail;
|
east.x = x + detail;
|
||||||
east.z = z;
|
east.z = z;
|
||||||
east.y = renderer->getTerrainHeight(renderer, east.x, east.z);
|
east.y = renderer->terrain->getHeight(renderer, east.x, east.z);
|
||||||
|
|
||||||
south.x = x;
|
south.x = x;
|
||||||
south.z = z + detail;
|
south.z = z + detail;
|
||||||
south.y = renderer->getTerrainHeight(renderer, south.x, south.z);
|
south.y = renderer->terrain->getHeight(renderer, south.x, south.z);
|
||||||
|
|
||||||
if (renderer->render_quality > 5)
|
if (renderer->render_quality > 5)
|
||||||
{
|
{
|
||||||
west.x = x - detail;
|
west.x = x - detail;
|
||||||
west.z = z;
|
west.z = z;
|
||||||
west.y = renderer->getTerrainHeight(renderer, west.x, west.z);
|
west.y = renderer->terrain->getHeight(renderer, west.x, west.z);
|
||||||
|
|
||||||
north.x = x;
|
north.x = x;
|
||||||
north.z = z - detail;
|
north.z = z - detail;
|
||||||
north.y = renderer->getTerrainHeight(renderer, north.x, north.z);
|
north.y = renderer->terrain->getHeight(renderer, north.x, north.z);
|
||||||
|
|
||||||
result.normal = _getNormal4(center, north, east, south, west);
|
result.normal = _getNormal4(center, north, east, south, west);
|
||||||
}
|
}
|
||||||
|
@ -207,7 +208,7 @@ static inline TextureResult _getTerrainResult(Renderer* renderer, double x, doub
|
||||||
result.location = center;
|
result.location = center;
|
||||||
result.thickness = -100.0;
|
result.thickness = -100.0;
|
||||||
result.definition = NULL;
|
result.definition = NULL;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,25 +236,25 @@ static inline void _getLayerThickness(TextureLayerDefinition* definition, Render
|
||||||
static inline TextureResult _getLayerResult(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, double detail)
|
static inline TextureResult _getLayerResult(TextureLayerDefinition* definition, Renderer* renderer, double x, double z, double detail)
|
||||||
{
|
{
|
||||||
TextureResult result_center, result_north, result_east, result_south, result_west;
|
TextureResult result_center, result_north, result_east, result_south, result_west;
|
||||||
|
|
||||||
_getLayerThickness(definition, renderer, x, z, &result_center);
|
_getLayerThickness(definition, renderer, x, z, &result_center);
|
||||||
_getLayerThickness(definition, renderer, x + detail, z, &result_east);
|
_getLayerThickness(definition, renderer, x + detail, z, &result_east);
|
||||||
_getLayerThickness(definition, renderer, x, z + detail, &result_south);
|
_getLayerThickness(definition, renderer, x, z + detail, &result_south);
|
||||||
|
|
||||||
if (renderer->render_quality > 5)
|
if (renderer->render_quality > 5)
|
||||||
{
|
{
|
||||||
_getLayerThickness(definition, renderer, x - detail, z, &result_west);
|
_getLayerThickness(definition, renderer, x - detail, z, &result_west);
|
||||||
_getLayerThickness(definition, renderer, x, z - detail, &result_north);
|
_getLayerThickness(definition, renderer, x, z - detail, &result_north);
|
||||||
|
|
||||||
result_center.normal = _getNormal4(result_center.location, result_north.location, result_east.location, result_south.location, result_west.location);
|
result_center.normal = _getNormal4(result_center.location, result_north.location, result_east.location, result_south.location, result_west.location);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result_center.normal = _getNormal2(result_center.location, result_east.location, result_south.location);
|
result_center.normal = _getNormal2(result_center.location, result_east.location, result_south.location);
|
||||||
}
|
}
|
||||||
|
|
||||||
result_center.definition = definition;
|
result_center.definition = definition;
|
||||||
|
|
||||||
return result_center;
|
return result_center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +290,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl
|
||||||
int i, start, nblayers;
|
int i, start, nblayers;
|
||||||
|
|
||||||
detail *= 0.1;
|
detail *= 0.1;
|
||||||
|
|
||||||
results[0] = _getTerrainResult(renderer, x, z, detail);
|
results[0] = _getTerrainResult(renderer, x, z, detail);
|
||||||
|
|
||||||
nblayers = layersCount(definition->layers);
|
nblayers = layersCount(definition->layers);
|
||||||
|
@ -297,7 +298,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl
|
||||||
{
|
{
|
||||||
results[i + 1] = _getLayerResult(layersGetLayer(definition->layers, i), renderer, x, z, detail);
|
results[i + 1] = _getLayerResult(layersGetLayer(definition->layers, i), renderer, x, z, detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(results, nblayers + 1, sizeof(TextureResult), _cmpResults);
|
qsort(results, nblayers + 1, sizeof(TextureResult), _cmpResults);
|
||||||
|
|
||||||
/* Pre compute alpha channel */
|
/* Pre compute alpha channel */
|
||||||
|
@ -308,7 +309,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl
|
||||||
{
|
{
|
||||||
thickness = results[i].thickness - last_height;
|
thickness = results[i].thickness - last_height;
|
||||||
last_height = results[i].thickness;
|
last_height = results[i].thickness;
|
||||||
|
|
||||||
if (results[i].definition)
|
if (results[i].definition)
|
||||||
{
|
{
|
||||||
if (thickness < results[i].definition->thickness_transparency)
|
if (thickness < results[i].definition->thickness_transparency)
|
||||||
|
@ -324,7 +325,7 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl
|
||||||
{
|
{
|
||||||
results[i].thickness = 1.0;
|
results[i].thickness = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results[i].thickness >= 0.999999)
|
if (results[i].thickness >= 0.999999)
|
||||||
{
|
{
|
||||||
start = i;
|
start = i;
|
||||||
|
@ -359,6 +360,6 @@ Color texturesGetColor(TexturesDefinition* definition, Renderer* renderer, doubl
|
||||||
colorMask(&result, &color);
|
colorMask(&result, &color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "euclid.h"
|
#include "euclid.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "terrain.h"
|
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
|
@ -19,7 +18,7 @@ void waterSave(PackStream* stream, WaterDefinition* definition)
|
||||||
packWriteDouble(stream, &definition->transparency);
|
packWriteDouble(stream, &definition->transparency);
|
||||||
packWriteDouble(stream, &definition->reflection);
|
packWriteDouble(stream, &definition->reflection);
|
||||||
packWriteDouble(stream, &definition->lighting_depth);
|
packWriteDouble(stream, &definition->lighting_depth);
|
||||||
|
|
||||||
packWriteDouble(stream, &definition->scaling);
|
packWriteDouble(stream, &definition->scaling);
|
||||||
packWriteDouble(stream, &definition->waves_height);
|
packWriteDouble(stream, &definition->waves_height);
|
||||||
packWriteDouble(stream, &definition->detail_height);
|
packWriteDouble(stream, &definition->detail_height);
|
||||||
|
@ -27,7 +26,7 @@ void waterSave(PackStream* stream, WaterDefinition* definition)
|
||||||
|
|
||||||
packWriteDouble(stream, &definition->foam_coverage);
|
packWriteDouble(stream, &definition->foam_coverage);
|
||||||
materialSave(stream, &definition->foam_material);
|
materialSave(stream, &definition->foam_material);
|
||||||
|
|
||||||
noiseSaveGenerator(stream, definition->_waves_noise);
|
noiseSaveGenerator(stream, definition->_waves_noise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +59,9 @@ WaterDefinition waterCreateDefinition()
|
||||||
|
|
||||||
result.height = -4.0;
|
result.height = -4.0;
|
||||||
result._waves_noise = noiseCreateGenerator();
|
result._waves_noise = noiseCreateGenerator();
|
||||||
|
|
||||||
waterAutoPreset(&result, WATER_PRESET_LAKE);
|
waterAutoPreset(&result, WATER_PRESET_LAKE);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +119,7 @@ void waterAutoPreset(WaterDefinition* definition, WaterPreset preset)
|
||||||
definition->foam_material.base.a = 1.0;
|
definition->foam_material.base.a = 1.0;
|
||||||
definition->foam_material.reflection = 0.4;
|
definition->foam_material.reflection = 0.4;
|
||||||
definition->foam_material.shininess = 1.5;
|
definition->foam_material.shininess = 1.5;
|
||||||
|
|
||||||
waterValidateDefinition(definition);
|
waterValidateDefinition(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +158,7 @@ static inline Vector3 _getNormal(WaterDefinition* definition, Vector3 base, doub
|
||||||
{
|
{
|
||||||
Vector3 back, right;
|
Vector3 back, right;
|
||||||
double x, z;
|
double x, z;
|
||||||
|
|
||||||
x = base.x;
|
x = base.x;
|
||||||
z = base.z;
|
z = base.z;
|
||||||
|
|
||||||
|
@ -204,18 +203,18 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal)
|
||||||
HeightInfo waterGetHeightInfo(WaterDefinition* definition)
|
HeightInfo waterGetHeightInfo(WaterDefinition* definition)
|
||||||
{
|
{
|
||||||
HeightInfo info;
|
HeightInfo info;
|
||||||
|
|
||||||
info.base_height = definition->height;
|
info.base_height = definition->height;
|
||||||
info.min_height = definition->height - noiseGetMaxValue(definition->_waves_noise);
|
info.min_height = definition->height - noiseGetMaxValue(definition->_waves_noise);
|
||||||
info.max_height = definition->height + noiseGetMaxValue(definition->_waves_noise);
|
info.max_height = definition->height + noiseGetMaxValue(definition->_waves_noise);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light)
|
Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light)
|
||||||
{
|
{
|
||||||
double factor;
|
double factor;
|
||||||
|
|
||||||
UNUSED(renderer);
|
UNUSED(renderer);
|
||||||
UNUSED(light_location);
|
UNUSED(light_location);
|
||||||
|
|
||||||
|
@ -251,9 +250,9 @@ static inline void _applyFoam(WaterDefinition* definition, Vector3 location, Vec
|
||||||
{
|
{
|
||||||
Color result = definition->foam_material.base;
|
Color result = definition->foam_material.base;
|
||||||
double foam_factor, normal_diff, location_offset;
|
double foam_factor, normal_diff, location_offset;
|
||||||
|
|
||||||
location_offset = 2.0 * detail;
|
location_offset = 2.0 * detail;
|
||||||
|
|
||||||
foam_factor = 0.0;
|
foam_factor = 0.0;
|
||||||
location.x += location_offset;
|
location.x += location_offset;
|
||||||
normal_diff = 1.0 - v3Dot(normal, _getNormal(definition, location, detail));
|
normal_diff = 1.0 - v3Dot(normal, _getNormal(definition, location, detail));
|
||||||
|
@ -280,22 +279,22 @@ static inline void _applyFoam(WaterDefinition* definition, Vector3 location, Vec
|
||||||
{
|
{
|
||||||
foam_factor = normal_diff;
|
foam_factor = normal_diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
foam_factor *= 10.0;
|
foam_factor *= 10.0;
|
||||||
if (foam_factor > 1.0)
|
if (foam_factor > 1.0)
|
||||||
{
|
{
|
||||||
foam_factor = 1.0;
|
foam_factor = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foam_factor <= 1.0 - definition->foam_coverage)
|
if (foam_factor <= 1.0 - definition->foam_coverage)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foam_factor = (foam_factor - (1.0 - definition->foam_coverage)) * definition->foam_coverage;
|
foam_factor = (foam_factor - (1.0 - definition->foam_coverage)) * definition->foam_coverage;
|
||||||
|
|
||||||
material->reflection = foam_factor * definition->foam_material.reflection + (1.0 - foam_factor) * material->reflection;
|
material->reflection = foam_factor * definition->foam_material.reflection + (1.0 - foam_factor) * material->reflection;
|
||||||
material->shininess = foam_factor * definition->foam_material.shininess + (1.0 - foam_factor) * material->shininess;
|
material->shininess = foam_factor * definition->foam_material.shininess + (1.0 - foam_factor) * material->shininess;
|
||||||
|
|
||||||
/* TODO This should be configurable */
|
/* TODO This should be configurable */
|
||||||
if (foam_factor > 0.2)
|
if (foam_factor > 0.2)
|
||||||
{
|
{
|
||||||
|
@ -349,17 +348,17 @@ WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer,
|
||||||
color.g = definition->material.base.g * (1.0 - definition->transparency) + result.reflected.g * definition->reflection + result.refracted.g * definition->transparency;
|
color.g = definition->material.base.g * (1.0 - definition->transparency) + result.reflected.g * definition->reflection + result.refracted.g * definition->transparency;
|
||||||
color.b = definition->material.base.b * (1.0 - definition->transparency) + result.reflected.b * definition->reflection + result.refracted.b * definition->transparency;
|
color.b = definition->material.base.b * (1.0 - definition->transparency) + result.reflected.b * definition->reflection + result.refracted.b * definition->transparency;
|
||||||
color.a = 1.0;
|
color.a = 1.0;
|
||||||
|
|
||||||
material = definition->material;
|
material = definition->material;
|
||||||
material.base = color;
|
material.base = color;
|
||||||
|
|
||||||
_applyFoam(definition, location, normal, detail, &material);
|
_applyFoam(definition, location, normal, detail, &material);
|
||||||
|
|
||||||
renderer->getLightStatus(renderer, &light, location);
|
renderer->getLightStatus(renderer, &light, location);
|
||||||
color = renderer->applyLightStatus(renderer, &light, location, normal, material);
|
color = renderer->applyLightStatus(renderer, &light, location, normal, material);
|
||||||
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
|
color = renderer->atmosphere->applyAerialPerspective(renderer, location, color);
|
||||||
color = renderer->applyClouds(renderer, color, renderer->camera_location, location);
|
color = renderer->applyClouds(renderer, color, renderer->camera_location, location);
|
||||||
|
|
||||||
result.base = definition->material.base;
|
result.base = definition->material.base;
|
||||||
result.final = color;
|
result.final = color;
|
||||||
|
|
||||||
|
@ -395,7 +394,7 @@ static void _renderQuad(WaterDefinition* definition, Renderer* renderer, double
|
||||||
v2 = _getFirstPassVertex(definition, x, z + size, size);
|
v2 = _getFirstPassVertex(definition, x, z + size, size);
|
||||||
v3 = _getFirstPassVertex(definition, x + size, z + size, size);
|
v3 = _getFirstPassVertex(definition, x + size, z + size, size);
|
||||||
v4 = _getFirstPassVertex(definition, x + size, z, size);
|
v4 = _getFirstPassVertex(definition, x + size, z, size);
|
||||||
|
|
||||||
renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, definition);
|
renderer->pushQuad(renderer, v1, v2, v3, v4, _postProcessFragment, definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue