diff --git a/TODO b/TODO index 2d6c216..bc79486 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ Technology Preview 2 : - Finalize terrain editor. => Add a generation dialog for base noise (overwriting changes). - => Implement chunks merging (with max size control). - Get rid of noise dialogs, for simpler settings. - Finalize lighting/clouds refactoring => Restore cloud lighting @@ -14,10 +13,8 @@ Technology Preview 2 : - Translations. Technlogy Preview 3 : -- Start using unit testing. -- Improve terrain 3D editor: - => Add a map preview with edit area highlighted. - => Allow zooming and simplified camera control. +- Start an undo/redo system ? +- Add a map preview to terrain editor. - Better time selection widget for atmosphere. - Clouds should keep distance to ground. - Find a proper model for night sky (maybe Shirley). diff --git a/data/ui_pictures.qrc b/data/ui_pictures.qrc new file mode 100644 index 0000000..3c3d55b --- /dev/null +++ b/data/ui_pictures.qrc @@ -0,0 +1,7 @@ + + + images/apply.png + images/cancel.png + images/revert.png + + diff --git a/src/editing/common/widgetglobalformbuttons.cpp b/src/editing/common/widgetglobalformbuttons.cpp new file mode 100644 index 0000000..0e1083b --- /dev/null +++ b/src/editing/common/widgetglobalformbuttons.cpp @@ -0,0 +1,32 @@ +#include "widgetglobalformbuttons.h" +#include "ui_widgetglobalformbuttons.h" + +WidgetGlobalFormButtons::WidgetGlobalFormButtons(QWidget *parent) : + QWidget(parent), + ui(new Ui::WidgetGlobalFormButtons) +{ + QPushButton* button; + + ui->setupUi(this); + + button = findChild("button_ok"); + if (button) + { + connect(button, SIGNAL(clicked()), this, SIGNAL(okClicked())); + } + button = findChild("button_cancel"); + if (button) + { + connect(button, SIGNAL(clicked()), this, SIGNAL(cancelClicked())); + } + button = findChild("button_revert"); + if (button) + { + connect(button, SIGNAL(clicked()), this, SIGNAL(revertClicked())); + } +} + +WidgetGlobalFormButtons::~WidgetGlobalFormButtons() +{ + delete ui; +} diff --git a/src/editing/common/widgetglobalformbuttons.h b/src/editing/common/widgetglobalformbuttons.h new file mode 100644 index 0000000..0c00f66 --- /dev/null +++ b/src/editing/common/widgetglobalformbuttons.h @@ -0,0 +1,27 @@ +#ifndef WIDGETGLOBALFORMBUTTONS_H +#define WIDGETGLOBALFORMBUTTONS_H + +#include + +namespace Ui { +class WidgetGlobalFormButtons; +} + +class WidgetGlobalFormButtons : public QWidget +{ + Q_OBJECT + +public: + explicit WidgetGlobalFormButtons(QWidget *parent = 0); + ~WidgetGlobalFormButtons(); + +signals: + void okClicked(); + void revertClicked(); + void cancelClicked(); + +private: + Ui::WidgetGlobalFormButtons *ui; +}; + +#endif // WIDGETGLOBALFORMBUTTONS_H diff --git a/src/editing/common/widgetglobalformbuttons.ui b/src/editing/common/widgetglobalformbuttons.ui new file mode 100644 index 0000000..ff5bfdd --- /dev/null +++ b/src/editing/common/widgetglobalformbuttons.ui @@ -0,0 +1,85 @@ + + + WidgetGlobalFormButtons + + + + 0 + 0 + 560 + 43 + + + + + 16777215 + 50 + + + + Form + + + + + + + 0 + 25 + + + + Cancel + + + + :/buttons/logo/images/cancel.png:/buttons/logo/images/cancel.png + + + + + + + + 0 + 25 + + + + Revert modifications + + + + :/buttons/logo/images/revert.png:/buttons/logo/images/revert.png + + + + + + + + 0 + 25 + + + + Validate + + + + :/buttons/logo/images/apply.png:/buttons/logo/images/apply.png + + + + + + + + + + + applyClicked() + revertClicked() + cancelClicked() + + diff --git a/src/editing/dialogheightmap.cpp b/src/editing/dialogheightmap.cpp deleted file mode 100644 index 81fd5ab..0000000 --- a/src/editing/dialogheightmap.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "dialogheightmap.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rendering/scenery.h" -#include "widgetheightmap.h" - -/**************** Dialog form ****************/ -DialogHeightMap::DialogHeightMap(QWidget* parent, TerrainDefinition* terrain) : DialogWithPreview(parent) -{ - QWidget* mainarea; - QWidget* buttons; - QWidget* panel; - - QLabel* label; - QSlider* slider; - QPushButton* button; - QComboBox* combobox; - - _value_original = terrain; - _value_modified = (TerrainDefinition*)TerrainDefinitionClass.create(); - TerrainDefinitionClass.copy(_value_original, _value_modified); - setLayout(new QVBoxLayout()); - - // Dialog layout (main area + buttons) - mainarea = new QWidget(this); - mainarea->setLayout(new QHBoxLayout()); - this->layout()->addWidget(mainarea); - - buttons = new QWidget(this); - buttons->setLayout(new QHBoxLayout()); - buttons->layout()->setAlignment(buttons, Qt::AlignBottom); - this->layout()->addWidget(buttons); - - // Main area layout (viewer + panel) - _3dview = new WidgetHeightMap(mainarea, _value_modified); - connect(_3dview, SIGNAL(heightmapChanged()), this, SLOT(heightmapChanged())); - mainarea->layout()->addWidget(_3dview); - - panel = new QWidget(mainarea); - panel->setLayout(new QVBoxLayout()); - mainarea->layout()->addWidget(panel); - mainarea->layout()->setAlignment(panel, Qt::AlignTop); - - // Panel layout - _info_memory = new QLabel(panel); - panel->layout()->addWidget(_info_memory); - - /*button = new QPushButton(tr("Load from picture file"), panel); - connect(button, SIGNAL(clicked()), this, SLOT(loadFromFile())); - panel->layout()->addWidget(button);*/ - - combobox = new QComboBox(panel); - combobox->addItem(tr("Raise / lower")); - combobox->addItem(tr("Add noise / smooth")); - combobox->addItem(tr("Restore to original")); - connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(brushModeChanged(int))); - panel->layout()->addWidget(combobox); - - label = new QLabel(tr("Brush size"), panel); - panel->layout()->addWidget(label); - - slider = new QSlider(Qt::Horizontal, panel); - slider->setRange(6, 300); - connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSizeChanged(int))); - panel->layout()->addWidget(slider); - slider->setValue(60); - - label = new QLabel(tr("Brush smoothing"), panel); - panel->layout()->addWidget(label); - - slider = new QSlider(Qt::Horizontal, panel); - slider->setRange(0, 1000); - connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushSmoothingChanged(int))); - panel->layout()->addWidget(slider); - slider->setValue(600); - - label = new QLabel(tr("Brush strength"), panel); - panel->layout()->addWidget(label); - - slider = new QSlider(Qt::Horizontal, panel); - slider->setRange(0, 1000); - connect(slider, SIGNAL(valueChanged(int)), this, SLOT(brushStrengthChanged(int))); - panel->layout()->addWidget(slider); - slider->setValue(200); - - // Buttons layout - button = new QPushButton(tr("Cancel"), buttons); - button->setIcon(QIcon(getDataPath("images/cancel.png"))); - buttons->layout()->addWidget(button); - QObject::connect(button, SIGNAL(clicked()), this, SLOT(reject())); - - button = new QPushButton(tr("Revert"), buttons); - button->setIcon(QIcon(getDataPath("images/revert.png"))); - buttons->layout()->addWidget(button); - QObject::connect(button, SIGNAL(clicked()), this, SLOT(revert())); - - button = new QPushButton(tr("Validate"), buttons); - button->setIcon(QIcon(getDataPath("images/apply.png"))); - buttons->layout()->addWidget(button); - QObject::connect(button, SIGNAL(clicked()), this, SLOT(accept())); - - setWindowTitle(tr("Paysages 3D - Height map painting")); -} - -bool DialogHeightMap::editHeightMap(QWidget* parent, TerrainDefinition* terrain) -{ - int result; - - DialogHeightMap* dialog = new DialogHeightMap(parent, terrain); - result = dialog->exec(); - - delete dialog; - - return (result != 0) ? true : false; -} - -void DialogHeightMap::accept() -{ - TerrainDefinitionClass.copy(_value_modified, _value_original); - QDialog::accept(); -} - -void DialogHeightMap::revert() -{ - TerrainDefinitionClass.copy(_value_original, _value_modified); - _3dview->revert(); -} - -void DialogHeightMap::brushModeChanged(int value) -{ - _3dview->setBrushMode((HeightMapBrushMode)value); -} - -void DialogHeightMap::brushSizeChanged(int value) -{ - _3dview->setBrushSize((double)value / 10.0); -} - -void DialogHeightMap::brushSmoothingChanged(int value) -{ - _3dview->setBrushSmoothing((double)value / 1000.0); -} - -void DialogHeightMap::brushStrengthChanged(int value) -{ - _3dview->setBrushStrength((double)value / 2000.0); -} - -void DialogHeightMap::heightmapChanged() -{ - _info_memory->setText(tr("Memory used: %1").arg(_3dview->getMemoryStats())); -} - -/*void DialogHeightMap::loadFromFile() -{ - QString filepath = QFileDialog::getOpenFileName(this, tr("Paysages 3D - Choose a picture to load"), QString(), tr("Images (*.jpg *.jpeg *.bmp *.png)")); - if (!filepath.isNull()) - { - heightmapImportFromPicture(&_value_modified, (char*) filepath.toStdString().c_str()); - _3dview->revert(); - updateResolutionLabel(); - } -}*/ diff --git a/src/editing/dialogheightmap.h b/src/editing/dialogheightmap.h deleted file mode 100644 index 23c0c47..0000000 --- a/src/editing/dialogheightmap.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _PAYSAGES_QT_DIALOGHEIGHTMAP_H_ -#define _PAYSAGES_QT_DIALOGHEIGHTMAP_H_ - -#include -#include "rendering/terrain/public.h" -#include "tools.h" -#include "widgetheightmap.h" - -class DialogHeightMap : public DialogWithPreview -{ - Q_OBJECT -public: - explicit DialogHeightMap(QWidget* parent, TerrainDefinition* terrain); - static bool editHeightMap(QWidget* parent, TerrainDefinition* terrain); - -public slots: - virtual void accept(); - void revert(); - -private slots: - void brushModeChanged(int value); - void brushSizeChanged(int value); - void brushSmoothingChanged(int value); - void brushStrengthChanged(int value); - void heightmapChanged(); - //void loadFromFile(); - -private: - TerrainDefinition* _value_original; - TerrainDefinition* _value_modified; - QLabel* _info_memory; - WidgetHeightMap* _3dview; -}; - -#endif diff --git a/src/editing/formterrain.cpp b/src/editing/formterrain.cpp index eb25985..36579c3 100644 --- a/src/editing/formterrain.cpp +++ b/src/editing/formterrain.cpp @@ -4,6 +4,7 @@ #include #include "tools.h" #include "dialogheightmap.h" +#include "terrain/dialogterrainpainting.h" #include "rendering/scenery.h" static TerrainDefinition* _definition; @@ -76,8 +77,12 @@ void FormTerrain::configChangeEvent() void FormTerrain::startPainting() { - if (DialogHeightMap::editHeightMap(this, _definition)) + DialogTerrainPainting* dialog = new DialogTerrainPainting(this, _definition); + dialog->exec(); + delete dialog; + + /*if (DialogHeightMap::editHeightMap(this, _definition)) { configChangeEvent(); - } + }*/ } diff --git a/src/editing/paysages-qt.pro b/src/editing/paysages-qt.pro index e53dcaf..41f89b4 100644 --- a/src/editing/paysages-qt.pro +++ b/src/editing/paysages-qt.pro @@ -17,9 +17,104 @@ LIBS += -lGLU unix:LIBS += -L$$DESTDIR -lpaysages_rendering -lpaysages_exploring win32:LIBS += ../libpaysages.a ../libpaysages_exploring.a -lDevIL -lILU -lILUT -lglib-2.0 -lgthread-2.0 -HEADERS += $$files(*.h) $$files(../rendering/*.h) $$files(../rendering/shared/*.h) $$files(../exploring/*.h) -SOURCES += $$files(*.cpp) TRANSLATIONS = $$PROJECT_PATH/data/i18n/paysages_fr.ts #system(lupdate paysages-qt.pro) #system(lrelease $$TRANSLATIONS) + +HEADERS += \ + widgetheightmap.h \ + widgetexplorer.h \ + widgetcurveeditor.h \ + tools.h \ + previewosd.h \ + previewmaterial.h \ + previewcolorgradation.h \ + mainwindow.h \ + inputnoise.h \ + inputmaterial.h \ + inputlayers.h \ + inputint.h \ + inputenum.h \ + inputdouble.h \ + inputcurve.h \ + inputcolorgradation.h \ + inputcolor.h \ + inputcamera.h \ + inputboolean.h \ + formwater.h \ + formtextures.h \ + formterrain.h \ + formrender.h \ + formmaterial.h \ + formclouds.h \ + formatmosphere.h \ + explorerchunkterrain.h \ + explorerchunksky.h \ + dialogrender.h \ + dialognoise.h \ + dialogmaterial.h \ + dialoglayers.h \ + dialogexplorer.h \ + dialogcurve.h \ + dialogcolorgradation.h \ + basepreview.h \ + baseinput.h \ + baseformlayer.h \ + baseform.h \ + baseexplorerchunk.h \ + terrain/dialogterrainpainting.h \ + common/widgetglobalformbuttons.h \ + terrain/paintingbrush.h + +SOURCES += \ + widgetheightmap.cpp \ + widgetexplorer.cpp \ + widgetcurveeditor.cpp \ + tools.cpp \ + previewosd.cpp \ + previewmaterial.cpp \ + previewcolorgradation.cpp \ + mainwindow.cpp \ + inputnoise.cpp \ + inputmaterial.cpp \ + inputlayers.cpp \ + inputint.cpp \ + inputenum.cpp \ + inputdouble.cpp \ + inputcurve.cpp \ + inputcolorgradation.cpp \ + inputcolor.cpp \ + inputcamera.cpp \ + inputboolean.cpp \ + formwater.cpp \ + formtextures.cpp \ + formterrain.cpp \ + formrender.cpp \ + formmaterial.cpp \ + formclouds.cpp \ + formatmosphere.cpp \ + explorerchunkterrain.cpp \ + explorerchunksky.cpp \ + dialogrender.cpp \ + dialognoise.cpp \ + dialogmaterial.cpp \ + dialoglayers.cpp \ + dialogexplorer.cpp \ + dialogcurve.cpp \ + dialogcolorgradation.cpp \ + basepreview.cpp \ + baseinput.cpp \ + baseformlayer.cpp \ + baseform.cpp \ + baseexplorerchunk.cpp \ + terrain/dialogterrainpainting.cpp \ + common/widgetglobalformbuttons.cpp \ + terrain/paintingbrush.cpp + +FORMS += \ + terrain/dialogterrainpainting.ui \ + common/widgetglobalformbuttons.ui + +RESOURCES += \ + ../../data/ui_pictures.qrc diff --git a/src/editing/terrain/dialogterrainpainting.cpp b/src/editing/terrain/dialogterrainpainting.cpp new file mode 100644 index 0000000..5041ed7 --- /dev/null +++ b/src/editing/terrain/dialogterrainpainting.cpp @@ -0,0 +1,98 @@ +#include "dialogterrainpainting.h" +#include "ui_dialogterrainpainting.h" + +#include "tools.h" + +DialogTerrainPainting::DialogTerrainPainting(QWidget*parent, TerrainDefinition* terrain) : + QDialog(parent), + ui(new Ui::DialogTerrainPainting) +{ + ui->setupUi(this); + + _terrain_original = terrain; + _terrain_modified = (TerrainDefinition*)TerrainDefinitionClass.create(); + + revert(); + + brushConfigChanged(); +} + +DialogTerrainPainting::~DialogTerrainPainting() +{ + delete ui; +} + +void DialogTerrainPainting::accept() +{ + TerrainDefinitionClass.copy(_terrain_modified, _terrain_original); + QDialog::accept(); +} + +void DialogTerrainPainting::revert() +{ + TerrainDefinitionClass.copy(_terrain_original, _terrain_modified); + + WidgetHeightMap* heightmap = findChild("widget_heightmap"); + if (heightmap) + { + heightmap->setTerrain(_terrain_modified); + heightmap->setBrush(&_brush); + } +} + +void DialogTerrainPainting::brushConfigChanged() +{ + QComboBox* combobox; + QSlider* slider; + + // Fill brush object + combobox = findChild("input_brush_mode"); + if (combobox) + { + _brush.setMode((PaintingBrushMode)combobox->currentIndex()); + } + slider = findChild("input_brush_size"); + if (slider) + { + _brush.setSize(slider); + } + slider = findChild("input_brush_smoothing"); + if (slider) + { + _brush.setSmoothing(slider); + } + slider = findChild("input_brush_strength"); + if (slider) + { + _brush.setStrength(slider); + } + + // Update brush description + + // Update brush preview + + // Tell to 3D widget + WidgetHeightMap* heightmap = findChild("widget_heightmap"); + if (heightmap) + { + heightmap->setBrush(&_brush); + } +} + +void DialogTerrainPainting::heightmapChanged() +{ + QLabel* label = findChild("label_memory_consumption"); + if (label) + { + qint64 memused = terrainGetMemoryStats(_terrain_modified); + label->setText(tr("Memory used: %1").arg(getHumanMemory(memused))); + + // TODO Find available memory + QProgressBar* progress = findChild("progress_memory_consumption"); + if (progress) + { + progress->setMaximum(1024); + progress->setValue(memused / 1024); + } + } +} diff --git a/src/editing/terrain/dialogterrainpainting.h b/src/editing/terrain/dialogterrainpainting.h new file mode 100644 index 0000000..d45b9da --- /dev/null +++ b/src/editing/terrain/dialogterrainpainting.h @@ -0,0 +1,34 @@ +#ifndef DIALOGTERRAINPAINTING_H +#define DIALOGTERRAINPAINTING_H + +#include +#include "paintingbrush.h" +#include "rendering/terrain/public.h" + +namespace Ui { +class DialogTerrainPainting; +} + +class DialogTerrainPainting : public QDialog +{ + Q_OBJECT + +public: + explicit DialogTerrainPainting(QWidget *parent, TerrainDefinition* terrain); + ~DialogTerrainPainting(); + +public slots: + void brushConfigChanged(); + void heightmapChanged(); + virtual void accept(); + void revert(); + +private: + Ui::DialogTerrainPainting *ui; + + TerrainDefinition* _terrain_modified; + TerrainDefinition* _terrain_original; + PaintingBrush _brush; +}; + +#endif // DIALOGTERRAINPAINTING_H diff --git a/src/editing/terrain/dialogterrainpainting.ui b/src/editing/terrain/dialogterrainpainting.ui new file mode 100644 index 0000000..b1fb372 --- /dev/null +++ b/src/editing/terrain/dialogterrainpainting.ui @@ -0,0 +1,455 @@ + + + DialogTerrainPainting + + + + 0 + 0 + 912 + 619 + + + + + 0 + 0 + + + + Paysages 3D - Terrain painting + + + true + + + true + + + + + + + + + 1 + 0 + + + + + 400 + 400 + + + + + + + + + 450 + 16777215 + + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Brush Tool : + + + + + + + + Raise / Lower (F1) + + + + + Add noise / Smooth (F2) + + + + + Flatten terrain (F3) + + + + + Fix discontinuities (F11) + + + + + Restore to default (F12) + + + + + + + + Brush size : + + + + + + + 5 + + + 100 + + + 20 + + + Qt::Horizontal + + + + + + + Brush smoothing : + + + + + + + 100 + + + 80 + + + Qt::Horizontal + + + + + + + Brush strength : + + + + + + + 10 + + + 100 + + + 20 + + + Qt::Horizontal + + + + + + + + + { Brush information } + + + 20 + + + + + + + 8 + + + + + Brush preview : + + + + + + + + 200 + 200 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + QLayout::SetDefaultConstraint + + + + + + 150 + 16777215 + + + + 24 + + + false + + + + + + + { memory consumption } + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 30 + + + + + + + + + + + WidgetGlobalFormButtons + QWidget +
common/widgetglobalformbuttons.h
+ 1 + + okClicked() + revertClicked() + cancelClicked() + +
+ + WidgetHeightMap + QWidget +
widgetheightmap.h
+ 1 + + heightmapChanged() + +
+
+ + input_brush_mode + input_brush_size + input_brush_smoothing + input_brush_strength + + + + + input_brush_size + valueChanged(int) + DialogTerrainPainting + brushConfigChanged() + + + 676 + 67 + + + 437 + 72 + + + + + input_brush_smoothing + valueChanged(int) + DialogTerrainPainting + brushConfigChanged() + + + 728 + 97 + + + 437 + 102 + + + + + input_brush_strength + valueChanged(int) + DialogTerrainPainting + brushConfigChanged() + + + 762 + 135 + + + 437 + 132 + + + + + input_brush_mode + currentIndexChanged(int) + DialogTerrainPainting + brushConfigChanged() + + + 752 + 42 + + + 437 + 40 + + + + + widget_heightmap + heightmapChanged() + DialogTerrainPainting + heightmapChanged() + + + 396 + 566 + + + 445 + 618 + + + + + widget_4 + okClicked() + DialogTerrainPainting + accept() + + + 816 + 593 + + + 683 + 615 + + + + + widget_4 + cancelClicked() + DialogTerrainPainting + reject() + + + 870 + 600 + + + 711 + 618 + + + + + widget_4 + revertClicked() + DialogTerrainPainting + revert() + + + 827 + 606 + + + 747 + 618 + + + + + + brushConfigChanged() + heightmapChanged() + revert() + +
diff --git a/src/editing/terrain/paintingbrush.cpp b/src/editing/terrain/paintingbrush.cpp new file mode 100644 index 0000000..4ec7830 --- /dev/null +++ b/src/editing/terrain/paintingbrush.cpp @@ -0,0 +1,120 @@ +#include "paintingbrush.h" + +#include + +PaintingBrush::PaintingBrush() +{ + _mode = PAINTING_BRUSH_RAISE; + _size = 0.0; + _smoothing = 0.0; + _strength = 0.0; + _noise = noiseCreateGenerator(); + noiseAddLevelsSimple(_noise, 10, 1.0, -0.5, 0.5, 0.5); +} + +PaintingBrush::~PaintingBrush() +{ + noiseDeleteGenerator(_noise); +} + +void PaintingBrush::setMode(PaintingBrushMode mode) +{ + _mode = mode; +} + +void PaintingBrush::setSize(double value) +{ + _size = value; +} + +void PaintingBrush::setSize(QAbstractSlider* slider) +{ + setSize(20.0 * (double)slider->value() / (double)slider->maximum()); +} + +void PaintingBrush::setSmoothing(double value) +{ + _smoothing = value; +} + +void PaintingBrush::setSmoothing(QAbstractSlider* slider) +{ + setSmoothing((double)slider->value() / (double)slider->maximum()); +} + +void PaintingBrush::setStrength(double value) +{ + _strength = value; +} + +void PaintingBrush::setStrength(QAbstractSlider* slider) +{ + setStrength((double)slider->value() / (double)slider->maximum()); +} + +void PaintingBrush::randomizeNoise() +{ + noiseRandomizeOffsets(_noise); +} + +double PaintingBrush::getInfluence(double relative_x, double relative_z) +{ + double distance = sqrt(relative_x * relative_x + relative_z * relative_z); + if (distance > _size) + { + return 0.0; + } + else if (distance > _size * (1.0 - _smoothing)) + { + return 1.0 - (distance - _size * (1.0 - _smoothing)) / (_size * _smoothing); + } + else + { + return 1.0; + } +} + +void PaintingBrush::drawPreview(QWidget* widget) +{ + +} + +void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double z, double duration, bool reverse) +{ + double brush_strength; + TerrainBrush brush; + + brush.relative_x = x; + brush.relative_z = z; + brush.hard_radius = _size * (1.0 - _smoothing); + brush.smoothed_size = _size * _smoothing; + brush.total_radius = brush.hard_radius + brush.smoothed_size; + + brush_strength = 0.5 * _strength * duration / 0.1; + + switch (_mode) + { + case PAINTING_BRUSH_RAISE: + if (reverse) + { + brush_strength = -brush_strength; + } + terrainBrushElevation(terrain->height_map, &brush, brush_strength * 2.0); + break; + case PAINTING_BRUSH_SMOOTH: + if (reverse) + { + terrainBrushSmooth(terrain->height_map, &brush, brush_strength); + } + else + { + terrainBrushAddNoise(terrain->height_map, &brush, _noise, brush_strength * 0.5); + } + break; + case PAINTING_BRUSH_RESTORE: + terrainBrushReset(terrain->height_map, &brush, brush_strength); + break; + default: + return; + } +} diff --git a/src/editing/terrain/paintingbrush.h b/src/editing/terrain/paintingbrush.h new file mode 100644 index 0000000..dfcd51c --- /dev/null +++ b/src/editing/terrain/paintingbrush.h @@ -0,0 +1,46 @@ +#ifndef PAINTINGBRUSH_H +#define PAINTINGBRUSH_H + +#include +#include "rendering/noise.h" +#include "rendering/terrain/public.h" + +typedef enum +{ + PAINTING_BRUSH_RAISE = 0, + PAINTING_BRUSH_SMOOTH = 1, + PAINTING_BRUSH_FLATTEN = 2, + PAINTING_BRUSH_FIX_DISCONTINUITIES = 3, + PAINTING_BRUSH_RESTORE = 4 +} PaintingBrushMode; + +class PaintingBrush +{ +public: + PaintingBrush(); + ~PaintingBrush(); + + void setMode(PaintingBrushMode mode); + void setSize(double value); + void setSize(QAbstractSlider* slider); + void setSmoothing(double value); + void setSmoothing(QAbstractSlider* slider); + void setStrength(double value); + void setStrength(QAbstractSlider* slider); + void randomizeNoise(); + + double getInfluence(double relative_x, double relative_z); + + void drawPreview(QWidget* widget); + + void applyToTerrain(TerrainDefinition* terrain, double x, double z, double duration, bool reverse); + +private: + PaintingBrushMode _mode; + double _size; + double _smoothing; + double _strength; + NoiseGenerator* _noise; +}; + +#endif // PAINTINGBRUSH_H diff --git a/src/editing/tools.cpp b/src/editing/tools.cpp index 4136d0e..8680967 100644 --- a/src/editing/tools.cpp +++ b/src/editing/tools.cpp @@ -16,3 +16,32 @@ bool DialogWithPreview::event(QEvent* event) return QDialog::event(event); } + +QString getHumanMemory(qint64 memused) +{ + if (memused >= 1024) + { + memused /= 1024; + if (memused >= 1024) + { + memused /= 1024; + if (memused >= 1024) + { + memused /= 1024; + return QObject::tr("%1 GB").arg(memused); + } + else + { + return QObject::tr("%1 MB").arg(memused); + } + } + else + { + return QObject::tr("%1 kB").arg(memused); + } + } + else + { + return QObject::tr("%1 B").arg(memused); + } +} diff --git a/src/editing/tools.h b/src/editing/tools.h index e2c3dae..3c5104e 100644 --- a/src/editing/tools.h +++ b/src/editing/tools.h @@ -19,6 +19,8 @@ static inline QString getDataPath(QString path) return QDir("./data").absoluteFilePath(path); } +QString getHumanMemory(qint64 memused); + class DialogWithPreview:public QDialog { Q_OBJECT diff --git a/src/editing/widgetheightmap.cpp b/src/editing/widgetheightmap.cpp index d306980..74898da 100644 --- a/src/editing/widgetheightmap.cpp +++ b/src/editing/widgetheightmap.cpp @@ -10,7 +10,7 @@ #define HEIGHTMAP_RESOLUTION 256 -WidgetHeightMap::WidgetHeightMap(QWidget* parent, TerrainDefinition* terrain) : +WidgetHeightMap::WidgetHeightMap(QWidget* parent) : QGLWidget(parent) { setMinimumSize(500, 500); @@ -19,11 +19,8 @@ QGLWidget(parent) setCursor(Qt::CrossCursor); startTimer(100); - _memory_stats = terrainGetMemoryStats(terrain); - - _terrain = terrain; + _terrain = NULL; _renderer = rendererCreate(); - TerrainRendererClass.bind(_renderer, _terrain); _vertices = new _VertexInfo[HEIGHTMAP_RESOLUTION * HEIGHTMAP_RESOLUTION]; _dirty = true; @@ -59,14 +56,9 @@ QGLWidget(parent) cameraSetZoomToTarget(_top_camera, _zoom); cameraCopyDefinition(_current_camera, _top_camera); + _brush = NULL; _brush_x = 0.0; _brush_z = 0.0; - _brush_mode = HEIGHTMAP_BRUSH_RAISE; - _brush_size = 10.0; - _brush_smoothing = 0.5; - _brush_strength = 1.0; - _brush_noise = noiseCreateGenerator(); - noiseAddLevelsSimple(_brush_noise, 10, 1.0, -0.5, 0.5, 0.5); } WidgetHeightMap::~WidgetHeightMap() @@ -75,72 +67,23 @@ WidgetHeightMap::~WidgetHeightMap() cameraDeleteDefinition(_top_camera); cameraDeleteDefinition(_temp_camera); rendererDelete(_renderer); - noiseDeleteGenerator(_brush_noise); delete[] _vertices; } -void WidgetHeightMap::setBrushMode(HeightMapBrushMode mode) +void WidgetHeightMap::setTerrain(TerrainDefinition* terrain) { - _brush_mode = mode; - _brush_x = 0.0; - _brush_z = 0.0; - updateGL(); + _terrain = terrain; + TerrainRendererClass.bind(_renderer, _terrain); + + revert(); } -void WidgetHeightMap::setBrushSize(double size) +void WidgetHeightMap::setBrush(PaintingBrush* brush) { - _brush_size = size; - _brush_x = 0.0; - _brush_z = 0.0; + _brush = brush; updateGL(); } -void WidgetHeightMap::setBrushSmoothing(double smoothing) -{ - _brush_smoothing = smoothing; - _brush_x = 0.0; - _brush_z = 0.0; - updateGL(); -} - -void WidgetHeightMap::setBrushStrength(double strength) -{ - _brush_strength = strength; - _brush_x = 0.0; - _brush_z = 0.0; - updateGL(); -} - -QString WidgetHeightMap::getMemoryStats() -{ - qint64 memused = _memory_stats; - if (memused >= 1024) - { - memused /= 1024; - if (memused >= 1024) - { - memused /= 1024; - if (memused >= 1024) - { - memused /= 1024; - return tr("%1 GB").arg(memused); - } - else - { - return tr("%1 MB").arg(memused); - } - } - else - { - return tr("%1 kB").arg(memused); - } - } - else - { - return tr("%1 B").arg(memused); - } -} - void WidgetHeightMap::revert() { _dirty = true; @@ -205,7 +148,14 @@ void WidgetHeightMap::mousePressEvent(QMouseEvent* event) void WidgetHeightMap::mouseReleaseEvent(QMouseEvent*) { _last_brush_action = 0; - terrainEndBrushStroke(_terrain->height_map); + if (_terrain) + { + terrainEndBrushStroke(_terrain->height_map); + } + if (_brush) + { + _brush->randomizeNoise(); + } } void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event) @@ -230,6 +180,11 @@ void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event) void WidgetHeightMap::timerEvent(QTimerEvent*) { + if (not _terrain) + { + return; + } + QDateTime new_time = QDateTime::currentDateTime(); double duration = 0.001 * (double) _last_time.msecsTo(new_time); _last_time = new_time; @@ -258,40 +213,9 @@ void WidgetHeightMap::timerEvent(QTimerEvent*) } // Apply brush action - if (_last_brush_action != 0) + if (_last_brush_action != 0 && _brush) { - double brush_strength; - TerrainBrush brush; - - brush.relative_x = _brush_x + _target_x; - brush.relative_z = _brush_z + _target_z; - brush.hard_radius = _brush_size * (1.0 - _brush_smoothing); - brush.smoothed_size = _brush_size * _brush_smoothing; - brush.total_radius = brush.hard_radius + brush.smoothed_size; - - brush_strength = _brush_strength * duration / 0.1; - - switch (_brush_mode) - { - case HEIGHTMAP_BRUSH_RAISE: - terrainBrushElevation(_terrain->height_map, &brush, brush_strength * _last_brush_action * 3.0); - break; - case HEIGHTMAP_BRUSH_SMOOTH: - if (_last_brush_action < 0) - { - terrainBrushSmooth(_terrain->height_map, &brush, brush_strength); - } - else - { - terrainBrushAddNoise(_terrain->height_map, &brush, _brush_noise, brush_strength * 0.5); - } - break; - case HEIGHTMAP_BRUSH_RESTORE: - terrainBrushReset(_terrain->height_map, &brush, brush_strength); - break; - default: - return; - } + _brush->applyToTerrain(_terrain, _brush_x + _target_x, _brush_z + _target_z, duration, _last_brush_action < 0); // TODO Only mark dirty the updated area _dirty = true; @@ -378,6 +302,11 @@ void WidgetHeightMap::paintGL() double frame_time; int rx, rz; + if (not _terrain) + { + return; + } + rx = HEIGHTMAP_RESOLUTION; rz = HEIGHTMAP_RESOLUTION; @@ -444,24 +373,23 @@ void WidgetHeightMap::paintGL() for (int dx = 1; dx >= 0; dx--) { _VertexInfo* vertex = _vertices + z * rx + x + dx; - double diff_x, diff_z, diff; + double brush_influence; - diff_x = vertex->point.x - _target_x - _brush_x; - diff_z = vertex->point.z - _target_z - _brush_z; - diff = sqrt(diff_x * diff_x + diff_z * diff_z); - if (diff > _brush_size) + if (_brush) { - diff = 0.0; - } - else if (diff > _brush_size * (1.0 - _brush_smoothing)) - { - diff = 1.0 - (diff - _brush_size * (1.0 - _brush_smoothing)) / (_brush_size * _brush_smoothing); + double diff_x, diff_z; + + diff_x = vertex->point.x - _target_x - _brush_x; + diff_z = vertex->point.z - _target_z - _brush_z; + + brush_influence = _brush->getInfluence(diff_x, diff_z); } else { - diff = 1.0; + brush_influence = 0.0; } - glColor3f(0.8 + diff, vertex->painted ? 1.0 : 0.8, 0.8); + + glColor3f(0.8 + brush_influence, vertex->painted ? 1.0 : 0.8, 0.8); glNormal3f(vertex->normal.x, vertex->normal.y, vertex->normal.z); glVertex3f(vertex->point.x, vertex->point.y, vertex->point.z); } @@ -567,8 +495,6 @@ void WidgetHeightMap::updateVertexInfo() _vertices = new _VertexInfo[rx * rz]; delete[] old_vertices; - _memory_stats = terrainGetMemoryStats(_terrain); - _last_update_x = (int) (floor(_target_x)); _last_update_z = (int) (floor(_target_z)); diff --git a/src/editing/widgetheightmap.h b/src/editing/widgetheightmap.h index abf1336..f6ba181 100644 --- a/src/editing/widgetheightmap.h +++ b/src/editing/widgetheightmap.h @@ -3,6 +3,7 @@ #include #include +#include "terrain/paintingbrush.h" #include "rendering/camera.h" #include "rendering/tools/euclid.h" #include "rendering/renderer.h" @@ -26,15 +27,11 @@ class WidgetHeightMap : public QGLWidget { Q_OBJECT public: - WidgetHeightMap(QWidget* parent, TerrainDefinition* terrain); + WidgetHeightMap(QWidget* parent); ~WidgetHeightMap(); - void setBrushMode(HeightMapBrushMode mode); - void setBrushSize(double size); - void setBrushSmoothing(double smoothing); - void setBrushStrength(double smoothing); - - QString getMemoryStats(); + void setTerrain(TerrainDefinition* terrain); + void setBrush(PaintingBrush* brush); public slots: void revert(); @@ -67,7 +64,6 @@ private: _VertexInfo* _vertices; bool _dirty; - qint64 _memory_stats; double _water_height; bool _water; @@ -91,13 +87,9 @@ private: CameraDefinition* _current_camera; double _zoom; + PaintingBrush* _brush; double _brush_x; double _brush_z; - HeightMapBrushMode _brush_mode; - double _brush_size; - double _brush_smoothing; - double _brush_strength; - NoiseGenerator* _brush_noise; }; #endif diff --git a/src/rendering/camera.c b/src/rendering/camera.c index 11d3c83..3702eb9 100644 --- a/src/rendering/camera.c +++ b/src/rendering/camera.c @@ -30,7 +30,7 @@ struct CameraDefinition void cameraSave(PackStream* stream, CameraDefinition* camera) { v3Save(stream, &camera->location); - packWriteDouble(stream, &camera->direction.r); + packWriteDouble(stream , &camera->direction.r); packWriteDouble(stream, &camera->direction.phi); packWriteDouble(stream, &camera->direction.theta); packWriteDouble(stream, &camera->roll); diff --git a/src/rendering/rendering.pro b/src/rendering/rendering.pro new file mode 100644 index 0000000..9d3468e --- /dev/null +++ b/src/rendering/rendering.pro @@ -0,0 +1,126 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-05-01T12:27:33 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = rendering +TEMPLATE = lib + +DEFINES += RENDERING_LIBRARY + +SOURCES += \ + zone.c \ + tools.c \ + system.c \ + scenery.c \ + renderer.c \ + render.c \ + opencl.c \ + noisesimplex.c \ + noiseperlin.c \ + noisenaive.c \ + noise.c \ + main.c \ + layers.c \ + geoarea.c \ + camera.c \ + auto.c \ + atmosphere/atm_render.c \ + atmosphere/atm_raster.c \ + atmosphere/atm_preview.c \ + atmosphere/atm_presets.c \ + atmosphere/atm_definition.c \ + atmosphere/atm_bruneton.c \ + clouds/clo_tools.c \ + clouds/clo_rendering.c \ + clouds/clo_preview.c \ + clouds/clo_presets.c \ + clouds/clo_definition.c \ + shared/preview.c \ + terrain/ter_raster.c \ + terrain/ter_preview.c \ + terrain/ter_presets.c \ + terrain/ter_painting.c \ + terrain/ter_definition.c \ + textures/tex_tools.c \ + textures/tex_rendering.c \ + textures/tex_preview.c \ + textures/tex_presets.c \ + textures/tex_definition.c \ + tools/texture.c \ + tools/parallel.c \ + tools/pack.c \ + tools/memory.c \ + tools/lighting.c \ + tools/euclid.c \ + tools/curve.c \ + tools/color.c \ + tools/cache.c \ + tools/array.c \ + water/wat_render.c \ + water/wat_raster.c \ + water/wat_preview.c \ + water/wat_presets.c \ + water/wat_definition.c + +HEADERS += \ + zone.h \ + tools.h \ + system.h \ + scenery.h \ + renderer.h \ + render.h \ + opencl.h \ + noisesimplex.h \ + noiseperlin.h \ + noisenaive.h \ + noise.h \ + main.h \ + layers.h \ + geoarea.h \ + camera.h \ + auto.h \ + atmosphere/public.h \ + atmosphere/private.h \ + clouds/public.h \ + clouds/private.h \ + shared/types.h \ + shared/preview.h \ + terrain/public.h \ + terrain/private.h \ + textures/public.h \ + textures/private.h \ + tools/texture.h \ + tools/parallel.h \ + tools/pack.h \ + tools/memory.h \ + tools/lighting.h \ + tools/euclid.h \ + tools/curve.h \ + tools/color.h \ + tools/cache.h \ + tools/array.h \ + water/public.h \ + water/private.h + +symbian { + MMP_RULES += EXPORTUNFROZEN + TARGET.UID3 = 0xEC48CBFE + TARGET.CAPABILITY = + TARGET.EPOCALLOWDLLDATA = 1 + addFiles.sources = rendering.dll + addFiles.path = !:/sys/bin + DEPLOYMENT += addFiles +} + +unix:!symbian { + maemo5 { + target.path = /opt/usr/lib + } else { + target.path = /usr/lib + } + INSTALLS += target +}