paysages : Terrain painting WIP.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@561 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
8c639ebb77
commit
53a29d5015
2 changed files with 116 additions and 65 deletions
|
@ -43,10 +43,12 @@ QGLWidget(parent)
|
||||||
_last_time = QDateTime::currentDateTime();
|
_last_time = QDateTime::currentDateTime();
|
||||||
_mouse_moved = false;
|
_mouse_moved = false;
|
||||||
|
|
||||||
|
_target_x = 0.0;
|
||||||
|
_target_z = 0.0;
|
||||||
_current_camera = cameraCreateDefinition();
|
_current_camera = cameraCreateDefinition();
|
||||||
_top_camera = cameraCreateDefinition();
|
_top_camera = cameraCreateDefinition();
|
||||||
_temp_camera = cameraCreateDefinition();
|
_temp_camera = cameraCreateDefinition();
|
||||||
_zoom = 50.0;
|
_zoom = 35.0;
|
||||||
|
|
||||||
Vector3 camera_location = {0.0, 80.0, 10.0};
|
Vector3 camera_location = {0.0, 80.0, 10.0};
|
||||||
cameraSetLocation(_current_camera, camera_location);
|
cameraSetLocation(_current_camera, camera_location);
|
||||||
|
@ -142,21 +144,43 @@ void WidgetHeightMap::revert()
|
||||||
updateGL();
|
updateGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::keyPressEvent(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
if (event->key() == Qt::Key_Up)
|
||||||
|
{
|
||||||
|
scrollTopCamera(0.0, -1.0);
|
||||||
|
}
|
||||||
|
else if (event->key() == Qt::Key_Down)
|
||||||
|
{
|
||||||
|
scrollTopCamera(0.0, 1.0);
|
||||||
|
}
|
||||||
|
else if (event->key() == Qt::Key_Left)
|
||||||
|
{
|
||||||
|
scrollTopCamera(-1.0, 0.0);
|
||||||
|
}
|
||||||
|
else if (event->key() == Qt::Key_Right)
|
||||||
|
{
|
||||||
|
scrollTopCamera(1.0, 0.0);
|
||||||
|
}
|
||||||
|
else if (event->key() == Qt::Key_PageUp)
|
||||||
|
{
|
||||||
|
zoomTopCamera(-3.0);
|
||||||
|
}
|
||||||
|
else if (event->key() == Qt::Key_PageDown)
|
||||||
|
{
|
||||||
|
zoomTopCamera(3.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QGLWidget::keyPressEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WidgetHeightMap::wheelEvent(QWheelEvent* event)
|
void WidgetHeightMap::wheelEvent(QWheelEvent* event)
|
||||||
{
|
{
|
||||||
if (event->orientation() == Qt::Vertical)
|
if (event->orientation() == Qt::Vertical)
|
||||||
{
|
{
|
||||||
_zoom -= 0.05 * (double) event->delta();
|
zoomTopCamera(-0.05 * (double) event->delta());
|
||||||
if (_zoom < 10.0)
|
|
||||||
{
|
|
||||||
_zoom = 10.0;
|
|
||||||
}
|
|
||||||
else if (_zoom > 70.0)
|
|
||||||
{
|
|
||||||
_zoom = 70.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cameraSetZoomToTarget(_top_camera, _zoom);
|
|
||||||
}
|
}
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
@ -207,11 +231,22 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
||||||
double duration = 0.001 * (double) _last_time.msecsTo(new_time);
|
double duration = 0.001 * (double) _last_time.msecsTo(new_time);
|
||||||
_last_time = new_time;
|
_last_time = new_time;
|
||||||
|
|
||||||
|
// Update top camera
|
||||||
|
Vector3 target = {_target_x, terrainGetInterpolatedHeight(_terrain, _target_x, _target_z, 1), _target_z};
|
||||||
|
cameraSetLocationCoords(_top_camera, target.x, target.y + 1.0, target.z + 0.1);
|
||||||
|
cameraSetTarget(_top_camera, target);
|
||||||
|
cameraSetZoomToTarget(_top_camera, _zoom);
|
||||||
|
if (cameraTransitionToAnother(_current_camera, _top_camera, 0.8))
|
||||||
|
{
|
||||||
|
updateGL();
|
||||||
|
}
|
||||||
|
|
||||||
if (not underMouse())
|
if (not underMouse())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply brush action
|
||||||
if (_last_brush_action != 0)
|
if (_last_brush_action != 0)
|
||||||
{
|
{
|
||||||
double brush_strength;
|
double brush_strength;
|
||||||
|
@ -232,16 +267,16 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
||||||
switch (_brush_mode)
|
switch (_brush_mode)
|
||||||
{
|
{
|
||||||
case HEIGHTMAP_BRUSH_RAISE:
|
case HEIGHTMAP_BRUSH_RAISE:
|
||||||
terrainBrushElevation(_terrain->height_map, &brush, brush_strength * _last_brush_action * 20.0);
|
terrainBrushElevation(_terrain->height_map, &brush, brush_strength * _last_brush_action * 3.0);
|
||||||
break;
|
break;
|
||||||
case HEIGHTMAP_BRUSH_SMOOTH:
|
case HEIGHTMAP_BRUSH_SMOOTH:
|
||||||
if (_last_brush_action < 0)
|
if (_last_brush_action < 0)
|
||||||
{
|
{
|
||||||
terrainBrushSmooth(_terrain->height_map, &brush, brush_strength * 0.1);
|
terrainBrushSmooth(_terrain->height_map, &brush, brush_strength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
terrainBrushAddNoise(_terrain->height_map, &brush, _brush_noise, brush_strength * 10.0);
|
terrainBrushAddNoise(_terrain->height_map, &brush, _brush_noise, brush_strength * 0.5);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HEIGHTMAP_BRUSH_RESTORE:
|
case HEIGHTMAP_BRUSH_RESTORE:
|
||||||
|
@ -256,50 +291,33 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
||||||
updateGL();
|
updateGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move camera
|
// Edge scrolling
|
||||||
if (cameraTransitionToAnother(_current_camera, _top_camera, 0.8))
|
double wx = (double) _last_mouse_x / (double) width();
|
||||||
|
double wy = (double) _last_mouse_y / (double) height();
|
||||||
|
double limit = 0.15;
|
||||||
|
double force = 1.0;
|
||||||
|
if (wx < limit)
|
||||||
{
|
{
|
||||||
updateGL();
|
scrollTopCamera(-(1.0 - wx / limit) * force, 0.0);
|
||||||
}
|
}
|
||||||
|
else if (wx > 1.0 - limit)
|
||||||
// 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;
|
scrollTopCamera(force * (wx - (1.0 - limit)) / limit, 0.0);
|
||||||
_position_x -= (int)ceil(dx);
|
|
||||||
|
|
||||||
_dirty = true;
|
|
||||||
updateGL();
|
|
||||||
}
|
}
|
||||||
if (_brush_x < -HEIGHTMAP_RESOLUTION / 2.0 + edge_length)
|
if (wy < limit)
|
||||||
{
|
{
|
||||||
double dx = -HEIGHTMAP_RESOLUTION / 2.0 + edge_length - _brush_x;
|
scrollTopCamera(0.0, -(1.0 - wy / limit) * force);
|
||||||
_position_x -= (int)ceil(dx);
|
|
||||||
|
|
||||||
_dirty = true;
|
|
||||||
updateGL();
|
|
||||||
}
|
}
|
||||||
if (_brush_z > HEIGHTMAP_RESOLUTION / 2.0 - edge_length)
|
else if (wy > 1.0 - limit)
|
||||||
{
|
{
|
||||||
double dz = HEIGHTMAP_RESOLUTION / 2.0 - edge_length - _brush_z;
|
|
||||||
_position_z -= (int)ceil(dz);
|
|
||||||
|
|
||||||
_dirty = true;
|
scrollTopCamera(0.0, force * (wy - (1.0 - limit)) / limit);
|
||||||
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()
|
void WidgetHeightMap::initializeGL()
|
||||||
{
|
{
|
||||||
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
GLfloat light_diffuse[] = {0.75, 0.74, 0.7, 1.0};
|
GLfloat light_diffuse[] = {0.75, 0.74, 0.7, 1.0};
|
||||||
|
@ -327,8 +345,8 @@ void WidgetHeightMap::initializeGL()
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
//glEnable(GL_LINE_SMOOTH);
|
glEnable(GL_LINE_SMOOTH);
|
||||||
//glLineWidth(1.0);
|
glLineWidth(2.0);
|
||||||
|
|
||||||
glDisable(GL_FOG);
|
glDisable(GL_FOG);
|
||||||
|
|
||||||
|
@ -337,6 +355,7 @@ void WidgetHeightMap::initializeGL()
|
||||||
|
|
||||||
void WidgetHeightMap::resizeGL(int w, int h)
|
void WidgetHeightMap::resizeGL(int w, int h)
|
||||||
{
|
{
|
||||||
|
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
@ -414,9 +433,6 @@ void WidgetHeightMap::paintGL()
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Height map
|
// Height map
|
||||||
camera_target = cameraGetTarget(_current_camera);
|
|
||||||
double tx = camera_target.x;
|
|
||||||
double tz = camera_target.z;
|
|
||||||
for (int x = 0; x < rx - 1; x++)
|
for (int x = 0; x < rx - 1; x++)
|
||||||
{
|
{
|
||||||
glBegin(GL_QUAD_STRIP);
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
@ -427,8 +443,8 @@ void WidgetHeightMap::paintGL()
|
||||||
_VertexInfo* vertex = _vertices + z * rx + x + dx;
|
_VertexInfo* vertex = _vertices + z * rx + x + dx;
|
||||||
double diff_x, diff_z, diff;
|
double diff_x, diff_z, diff;
|
||||||
|
|
||||||
diff_x = vertex->point.x - tx - _brush_x;
|
diff_x = vertex->point.x - _target_x - _brush_x;
|
||||||
diff_z = vertex->point.z - tz - _brush_z;
|
diff_z = vertex->point.z - _target_z - _brush_z;
|
||||||
diff = sqrt(diff_x * diff_x + diff_z * diff_z);
|
diff = sqrt(diff_x * diff_x + diff_z * diff_z);
|
||||||
if (diff > _brush_size)
|
if (diff > _brush_size)
|
||||||
{
|
{
|
||||||
|
@ -444,7 +460,7 @@ void WidgetHeightMap::paintGL()
|
||||||
}
|
}
|
||||||
glColor3f(0.8 + diff, vertex->painted ? 1.0 : 0.8, 0.8);
|
glColor3f(0.8 + diff, vertex->painted ? 1.0 : 0.8, 0.8);
|
||||||
glNormal3f(vertex->normal.x, vertex->normal.y, vertex->normal.z);
|
glNormal3f(vertex->normal.x, vertex->normal.y, vertex->normal.z);
|
||||||
glVertex3f(vertex->point.x - tx, vertex->point.y, vertex->point.z - tz);
|
glVertex3f(vertex->point.x - _target_x, vertex->point.y, vertex->point.z - _target_z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
@ -456,6 +472,7 @@ void WidgetHeightMap::paintGL()
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
glColor4f(0.8, 0.0, 0.0, 0.1);
|
glColor4f(0.8, 0.0, 0.0, 0.1);
|
||||||
for (int z = 0; z < rz; z++)
|
for (int z = 0; z < rz; z++)
|
||||||
{
|
{
|
||||||
|
@ -463,7 +480,7 @@ void WidgetHeightMap::paintGL()
|
||||||
for (int x = 0; x < rx; x++)
|
for (int x = 0; x < rx; x++)
|
||||||
{
|
{
|
||||||
_VertexInfo* vertex = _vertices + z * rx + x;
|
_VertexInfo* vertex = _vertices + z * rx + x;
|
||||||
glVertex3f(vertex->point.x - tx, vertex->point.y, vertex->point.z - tz);
|
glVertex3f(vertex->point.x - _target_x, vertex->point.y, vertex->point.z - _target_z);
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
@ -473,27 +490,30 @@ void WidgetHeightMap::paintGL()
|
||||||
for (int z = 0; z < rz; z++)
|
for (int z = 0; z < rz; z++)
|
||||||
{
|
{
|
||||||
_VertexInfo* vertex = _vertices + z * rx + x;
|
_VertexInfo* vertex = _vertices + z * rx + x;
|
||||||
glVertex3f(vertex->point.x - tx, vertex->point.y, vertex->point.z - tz);
|
glVertex3f(vertex->point.x - _target_x, vertex->point.y, vertex->point.z - _target_z);
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Water
|
// Water
|
||||||
if (_water)
|
if (_water)
|
||||||
{
|
{
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glColor4f(0.2, 0.3, 0.7, 0.7);
|
glColor4f(0.2, 0.3, 0.7, 0.7);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glVertex3f(camera_target.x - 500.0, _water_height, camera_target.z - 500.0);
|
glVertex3f(_target_x - 500.0, _water_height, _target_z - 500.0);
|
||||||
glVertex3f(camera_target.x - 500.0, _water_height, camera_target.z + 500.0);
|
glVertex3f(_target_x - 500.0, _water_height, _target_z + 500.0);
|
||||||
glVertex3f(camera_target.x + 500.0, _water_height, camera_target.z + 500.0);
|
glVertex3f(_target_x + 500.0, _water_height, _target_z + 500.0);
|
||||||
glVertex3f(camera_target.x + 500.0, _water_height, camera_target.z - 500.0);
|
glVertex3f(_target_x + 500.0, _water_height, _target_z - 500.0);
|
||||||
glEnd();
|
glEnd();
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time stats
|
// Time stats
|
||||||
|
@ -503,10 +523,38 @@ void WidgetHeightMap::paintGL()
|
||||||
|
|
||||||
while ((error_code = glGetError()) != GL_NO_ERROR)
|
while ((error_code = glGetError()) != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
|
|
||||||
logDebug(QString("[OpenGL] ERROR : ") + (const char*) gluErrorString(error_code));
|
logDebug(QString("[OpenGL] ERROR : ") + (const char*) gluErrorString(error_code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::scrollTopCamera(double dx, double dz)
|
||||||
|
{
|
||||||
|
if (dx != 0.0)
|
||||||
|
{
|
||||||
|
_target_x += dx;
|
||||||
|
}
|
||||||
|
if (dz != 0.0)
|
||||||
|
{
|
||||||
|
|
||||||
|
_target_z += dz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::zoomTopCamera(double dzoom)
|
||||||
|
{
|
||||||
|
_zoom += dzoom;
|
||||||
|
if (_zoom < 10.0)
|
||||||
|
{
|
||||||
|
_zoom = 10.0;
|
||||||
|
}
|
||||||
|
else if (_zoom > 70.0)
|
||||||
|
{
|
||||||
|
|
||||||
|
_zoom = 70.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WidgetHeightMap::updateVertexInfo()
|
void WidgetHeightMap::updateVertexInfo()
|
||||||
{
|
{
|
||||||
int rx = HEIGHTMAP_RESOLUTION;
|
int rx = HEIGHTMAP_RESOLUTION;
|
||||||
|
@ -520,17 +568,14 @@ void WidgetHeightMap::updateVertexInfo()
|
||||||
_memory_stats = terrainGetMemoryStats(_terrain);
|
_memory_stats = terrainGetMemoryStats(_terrain);
|
||||||
|
|
||||||
// Update positions
|
// Update positions
|
||||||
Vector3 camera_target = cameraGetTarget(_current_camera);
|
|
||||||
double tx = camera_target.x;
|
|
||||||
double tz = camera_target.z;
|
|
||||||
for (int x = 0; x < rx; x++)
|
for (int x = 0; x < rx; x++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z < rz; z++)
|
for (int z = 0; z < rz; z++)
|
||||||
{
|
{
|
||||||
_VertexInfo* vertex = _vertices + z * rx + x;
|
_VertexInfo* vertex = _vertices + z * rx + x;
|
||||||
|
|
||||||
dx = tx + x - rx / 2;
|
dx = _target_x + x - rx / 2;
|
||||||
dz = tz + z - rz / 2;
|
dz = _target_z + z - rz / 2;
|
||||||
|
|
||||||
vertex->point.x = (double) dx;
|
vertex->point.x = (double) dx;
|
||||||
vertex->point.z = (double) dz;
|
vertex->point.z = (double) dz;
|
||||||
|
|
|
@ -43,6 +43,7 @@ signals:
|
||||||
void heightmapChanged();
|
void heightmapChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void mousePressEvent(QMouseEvent* event);
|
void mousePressEvent(QMouseEvent* event);
|
||||||
void mouseReleaseEvent(QMouseEvent* event);
|
void mouseReleaseEvent(QMouseEvent* event);
|
||||||
void mouseMoveEvent(QMouseEvent* event);
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
|
@ -55,6 +56,9 @@ protected:
|
||||||
void paintGL();
|
void paintGL();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void scrollTopCamera(double dx, double dz);
|
||||||
|
void zoomTopCamera(double dzoom);
|
||||||
|
|
||||||
void updateVertexInfo();
|
void updateVertexInfo();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -77,6 +81,8 @@ private:
|
||||||
QDateTime _last_time;
|
QDateTime _last_time;
|
||||||
bool _mouse_moved;
|
bool _mouse_moved;
|
||||||
|
|
||||||
|
double _target_x;
|
||||||
|
double _target_z;
|
||||||
CameraDefinition* _top_camera;
|
CameraDefinition* _top_camera;
|
||||||
CameraDefinition* _temp_camera;
|
CameraDefinition* _temp_camera;
|
||||||
CameraDefinition* _current_camera;
|
CameraDefinition* _current_camera;
|
||||||
|
|
Loading…
Reference in a new issue