paysages : Height map painting (WIP).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@391 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-07-16 15:48:05 +00:00 committed by ThunderK
parent 2fc252f59a
commit 62e0ef5859
7 changed files with 92 additions and 1 deletions

View file

@ -10,6 +10,7 @@ Previews :
* Progressive rendering now takes advantage of multiple CPU cores.
Scenery :
* Added terrain canvases to paint the shape directly.
* Added clouds hardness to light.
* Added sun halo control.
* New cloud model with 2 noises : one for the global shape and one for edges.

View file

@ -4,6 +4,7 @@
#include <QBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QComboBox>
#include <QSlider>
#include <math.h>
#include "widgetheightmap.h"
@ -20,6 +21,7 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap) : Dialog
QLabel* label;
QSlider* slider;
QPushButton* button;
QComboBox* combobox;
_value_original = heightmap;
_value_modified = heightmapCreate();
@ -64,6 +66,12 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap) : Dialog
connect(button, SIGNAL(clicked()), _3dview, SLOT(resetToTerrain()));
panel->layout()->addWidget(button);
combobox = new QComboBox(panel);
combobox->addItem(tr("Raise / lower"));
combobox->addItem(tr("Smooth / add noise"));
connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(brushModeChanged(int)));
panel->layout()->addWidget(combobox);
label = new QLabel(tr("Brush size"), panel);
panel->layout()->addWidget(label);
@ -129,6 +137,11 @@ void DialogHeightMap::angleVChanged(int value)
_3dview->setVerticalViewAngle(M_PI_2 * ((double)value) / 1000.0);
}
void DialogHeightMap::brushModeChanged(int value)
{
_3dview->setBrushMode((HeightMapBrushMode)value);
}
void DialogHeightMap::brushSizeChanged(int value)
{
_3dview->setBrushSize((double)value / 10.0);

View file

@ -19,6 +19,7 @@ public slots:
private slots:
void angleHChanged(int value);
void angleVChanged(int value);
void brushModeChanged(int value);
void brushSizeChanged(int value);
void brushSmoothingChanged(int value);

View file

@ -30,6 +30,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
_brush_x = 0.0;
_brush_z = 0.0;
_brush_mode = HEIGHTMAP_BRUSH_RAISE;
_brush_size = 10.0;
_brush_smoothing = 0.5;
}
@ -51,6 +52,11 @@ void WidgetHeightMap::setVerticalViewAngle(double angle_v)
updateGL();
}
void WidgetHeightMap::setBrushMode(HeightMapBrushMode mode)
{
_brush_mode = mode;
}
void WidgetHeightMap::setBrushSize(double size)
{
_brush_size = size;
@ -96,6 +102,7 @@ void WidgetHeightMap::keyPressEvent(QKeyEvent* event)
void WidgetHeightMap::mousePressEvent(QMouseEvent* event)
{
mouseMoveEvent(event);
}
void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event)
@ -103,7 +110,27 @@ void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event)
int move_x = event->x() - _last_mouse_x;
int move_y = event->y() - _last_mouse_y;
if (event->buttons() & Qt::MiddleButton)
if ((event->buttons() & Qt::LeftButton) || (event->buttons() & Qt::RightButton))
{
HeightMapBrush brush;
brush.relative_x = (_brush_x + 40.0) / 80.0;
brush.relative_z = (_brush_z + 40.0) / 80.0;
brush.hard_radius = _brush_size / 80.0 - _brush_smoothing;
brush.smoothed_size = (_brush_size / 80.0) * _brush_smoothing;
switch (_brush_mode)
{
case HEIGHTMAP_BRUSH_RAISE:
heightmapBrushElevation(_heightmap, &brush, (event->buttons() & Qt::RightButton) ? -0.01 : 0.01);
_dirty = true;
updateGL();
break;
default:
;
}
}
else if (event->buttons() & Qt::MiddleButton)
{
// Rotate around the turntable
_angle_h -= (double)move_x * 0.008;

View file

@ -11,6 +11,12 @@ typedef struct
Vector3 normal;
} _VertexInfo;
typedef enum
{
HEIGHTMAP_BRUSH_RAISE = 0,
HEIGHTMAP_BRUSH_SMOOTH = 1
} HeightMapBrushMode;
class WidgetHeightMap : public QGLWidget
{
Q_OBJECT
@ -20,6 +26,7 @@ public:
void setHorizontalViewAngle(double angle_h);
void setVerticalViewAngle(double angle_v);
void setBrushMode(HeightMapBrushMode mode);
void setBrushSize(double size);
void setBrushSmoothing(double smoothing);
@ -55,6 +62,7 @@ private:
double _brush_x;
double _brush_z;
HeightMapBrushMode _brush_mode;
double _brush_size;
double _brush_smoothing;
};

View file

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
HeightMap heightmapCreate()
{
@ -68,3 +69,33 @@ void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resol
heightmap->data[i] = 0.0;
}
}
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value)
{
int x, z;
double dx, dz, distance;
// TODO Limit to brush radius
for (x = 0; x < heightmap->resolution_x; x++)
{
dx = (double)x / (double)heightmap->resolution_x;
for (z = 0; z < heightmap->resolution_z; 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));
if (distance > brush->hard_radius)
{
if (distance <= brush->hard_radius + brush->smoothed_size)
{
heightmap->data[z * heightmap->resolution_x +x] += value * (distance - brush->hard_radius) / brush->smoothed_size;
}
}
else
{
heightmap->data[z * heightmap->resolution_x +x] += value;
}
}
}
}

View file

@ -16,6 +16,14 @@ typedef struct
double* data;
} HeightMap;
typedef struct
{
double relative_x;
double relative_z;
double hard_radius;
double smoothed_size;
} HeightMapBrush;
HeightMap heightmapCreate();
void heightmapDelete(HeightMap* heightmap);
void heightmapCopy(HeightMap* source, HeightMap* destination);
@ -25,6 +33,8 @@ void heightmapSave(PackStream* stream, HeightMap* heightmap);
void heightmapLoad(PackStream* stream, HeightMap* heightmap);
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z);
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value);
#ifdef __cplusplus
}