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. * Progressive rendering now takes advantage of multiple CPU cores.
Scenery : Scenery :
* Added terrain canvases to paint the shape directly.
* Added clouds hardness to light. * Added clouds hardness to light.
* Added sun halo control. * Added sun halo control.
* New cloud model with 2 noises : one for the global shape and one for edges. * New cloud model with 2 noises : one for the global shape and one for edges.

View file

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

View file

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

View file

@ -30,6 +30,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
_brush_x = 0.0; _brush_x = 0.0;
_brush_z = 0.0; _brush_z = 0.0;
_brush_mode = HEIGHTMAP_BRUSH_RAISE;
_brush_size = 10.0; _brush_size = 10.0;
_brush_smoothing = 0.5; _brush_smoothing = 0.5;
} }
@ -51,6 +52,11 @@ void WidgetHeightMap::setVerticalViewAngle(double angle_v)
updateGL(); updateGL();
} }
void WidgetHeightMap::setBrushMode(HeightMapBrushMode mode)
{
_brush_mode = mode;
}
void WidgetHeightMap::setBrushSize(double size) void WidgetHeightMap::setBrushSize(double size)
{ {
_brush_size = size; _brush_size = size;
@ -96,6 +102,7 @@ void WidgetHeightMap::keyPressEvent(QKeyEvent* event)
void WidgetHeightMap::mousePressEvent(QMouseEvent* event) void WidgetHeightMap::mousePressEvent(QMouseEvent* event)
{ {
mouseMoveEvent(event);
} }
void WidgetHeightMap::mouseMoveEvent(QMouseEvent* 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_x = event->x() - _last_mouse_x;
int move_y = event->y() - _last_mouse_y; 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 // Rotate around the turntable
_angle_h -= (double)move_x * 0.008; _angle_h -= (double)move_x * 0.008;

View file

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

View file

@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h>
HeightMap heightmapCreate() HeightMap heightmapCreate()
{ {
@ -68,3 +69,33 @@ void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resol
heightmap->data[i] = 0.0; 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; double* data;
} HeightMap; } HeightMap;
typedef struct
{
double relative_x;
double relative_z;
double hard_radius;
double smoothed_size;
} HeightMapBrush;
HeightMap heightmapCreate(); HeightMap heightmapCreate();
void heightmapDelete(HeightMap* heightmap); void heightmapDelete(HeightMap* heightmap);
void heightmapCopy(HeightMap* source, HeightMap* destination); void heightmapCopy(HeightMap* source, HeightMap* destination);
@ -25,6 +33,8 @@ void heightmapSave(PackStream* stream, HeightMap* heightmap);
void heightmapLoad(PackStream* stream, HeightMap* heightmap); void heightmapLoad(PackStream* stream, HeightMap* heightmap);
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z); void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z);
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value);
#ifdef __cplusplus #ifdef __cplusplus
} }