paysages : Added edge scrolling to terrain painting + restore to original.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@530 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2013-03-01 14:23:21 +00:00 committed by ThunderK
parent 737ba2a4d1
commit a78fecdae7
4 changed files with 58 additions and 10 deletions

View file

@ -77,6 +77,7 @@ DialogHeightMap::DialogHeightMap(QWidget* parent, TerrainDefinition* terrain) :
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);

View file

@ -4,9 +4,11 @@
#include <QMouseEvent>
#include <math.h>
#include <GL/glu.h>
#include <qt4/QtGui/qwidget.h>
#include "tools.h"
#define HEIGHTMAP_RESOLUTION 256
#define CAMERA_DISTANCE 200.0
WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain):
QGLWidget(parent)
@ -37,7 +39,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain):
_position_x = 0;
_position_z = 0;
_angle_h = 0.0;
_angle_v = 0.3;
_angle_v = 0.8;
_brush_x = 0.0;
_brush_z = 0.0;
@ -181,13 +183,18 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
double duration = 0.001 * (double)_last_time.msecsTo(new_time);
_last_time = new_time;
if (not underMouse())
{
return;
}
if (_last_brush_action != 0)
{
double brush_strength;
TerrainBrush brush;
brush.relative_x = _brush_x;
brush.relative_z = _brush_z;
brush.relative_x = _brush_x + (double)_position_x;
brush.relative_z = _brush_z + (double)_position_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;
@ -209,6 +216,9 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
terrainBrushAddNoise(_terrain->height_map, &brush, _brush_noise, brush_strength * 10.0);
}
break;
case HEIGHTMAP_BRUSH_RESTORE:
terrainBrushReset(_terrain->height_map, &brush, brush_strength);
break;
default:
return;
}
@ -217,6 +227,42 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
_dirty = true;
updateGL();
}
// Edge scrolling
// TODO Apply scrolling to vertex info and dirty only needed area
double edge_length = 10.0;
if (_brush_x > HEIGHTMAP_RESOLUTION / 2.0 - edge_length)
{
double dx = HEIGHTMAP_RESOLUTION / 2.0 - edge_length - _brush_x;
_position_x -= (int)ceil(dx);
_dirty = true;
updateGL();
}
if (_brush_x < -HEIGHTMAP_RESOLUTION / 2.0 + edge_length)
{
double dx = -HEIGHTMAP_RESOLUTION / 2.0 + edge_length - _brush_x;
_position_x -= (int)ceil(dx);
_dirty = true;
updateGL();
}
if (_brush_z > HEIGHTMAP_RESOLUTION / 2.0 - edge_length)
{
double dz = HEIGHTMAP_RESOLUTION / 2.0 - edge_length - _brush_z;
_position_z -= (int)ceil(dz);
_dirty = true;
updateGL();
}
if (_brush_z < -HEIGHTMAP_RESOLUTION / 2.0 + edge_length)
{
double dz = -HEIGHTMAP_RESOLUTION / 2.0 + edge_length - _brush_z;
_position_z -= (int)ceil(dz);
_dirty = true;
updateGL();
}
}
void WidgetHeightMap::initializeGL()
@ -319,7 +365,7 @@ void WidgetHeightMap::paintGL()
// Place camera
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(50.0 * cos(_angle_h) * cos(_angle_v), 50.0 * sin(_angle_v), -50.0 * sin(_angle_h) * cos(_angle_v), 0.0, 0.0, 0.0, -cos(_angle_h) * sin(_angle_v), cos(_angle_v), sin(_angle_h) * sin(_angle_v));
gluLookAt(CAMERA_DISTANCE * cos(_angle_h) * cos(_angle_v), CAMERA_DISTANCE * sin(_angle_v), -CAMERA_DISTANCE * sin(_angle_h) * cos(_angle_v), 0.0, 0.0, 0.0, -cos(_angle_h) * sin(_angle_v), cos(_angle_v), sin(_angle_h) * sin(_angle_v));
// Place lights
GLfloat light_position[] = { 40.0, 40.0, 40.0, 0.0 };
@ -342,8 +388,8 @@ void WidgetHeightMap::paintGL()
_VertexInfo* vertex = _vertices + z * rx + x + dx;
double diff_x, diff_z, diff;
diff_x = vertex->point.x - _brush_x;
diff_z = vertex->point.z - _brush_z;
diff_x = vertex->point.x - (double)_position_x - _brush_x;
diff_z = vertex->point.z - (double)_position_z - _brush_z;
diff = sqrt(diff_x * diff_x + diff_z * diff_z);
if (diff > _brush_size)
{
@ -359,7 +405,7 @@ void WidgetHeightMap::paintGL()
}
glColor3f(0.8 + diff, 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);
glVertex3f(vertex->point.x - (double)_position_x, vertex->point.y, vertex->point.z - (double)_position_z);
}
}
glEnd();

View file

@ -17,7 +17,8 @@ typedef struct
typedef enum
{
HEIGHTMAP_BRUSH_RAISE = 0,
HEIGHTMAP_BRUSH_SMOOTH = 1
HEIGHTMAP_BRUSH_SMOOTH = 1,
HEIGHTMAP_BRUSH_RESTORE = 2
} HeightMapBrushMode;
class WidgetHeightMap : public QGLWidget

View file

@ -436,13 +436,13 @@ static double _applyBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush,
UNUSED(brush);
UNUSED(data);
double ideal = terrainGetInterpolatedHeight(heightmap->terrain, x, z, 1);
double ideal = terrainGetInterpolatedHeight(heightmap->terrain, x, z, 0);
return basevalue + (ideal - basevalue) * influence * force;
}
void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double value)
{
/* No need to prepare the floating data, it can't grow here */
_prepareBrushStroke(heightmap, brush);
_applyBrush(heightmap, brush, value, NULL, _applyBrushReset);
}