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:
parent
2fc252f59a
commit
62e0ef5859
7 changed files with 92 additions and 1 deletions
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue