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();
|
||||
_mouse_moved = false;
|
||||
|
||||
_target_x = 0.0;
|
||||
_target_z = 0.0;
|
||||
_current_camera = cameraCreateDefinition();
|
||||
_top_camera = cameraCreateDefinition();
|
||||
_temp_camera = cameraCreateDefinition();
|
||||
_zoom = 50.0;
|
||||
_zoom = 35.0;
|
||||
|
||||
Vector3 camera_location = {0.0, 80.0, 10.0};
|
||||
cameraSetLocation(_current_camera, camera_location);
|
||||
|
@ -142,21 +144,43 @@ void WidgetHeightMap::revert()
|
|||
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)
|
||||
{
|
||||
if (event->orientation() == Qt::Vertical)
|
||||
{
|
||||
_zoom -= 0.05 * (double) event->delta();
|
||||
if (_zoom < 10.0)
|
||||
{
|
||||
_zoom = 10.0;
|
||||
}
|
||||
else if (_zoom > 70.0)
|
||||
{
|
||||
_zoom = 70.0;
|
||||
}
|
||||
|
||||
cameraSetZoomToTarget(_top_camera, _zoom);
|
||||
zoomTopCamera(-0.05 * (double) event->delta());
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
@ -207,11 +231,22 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
|||
double duration = 0.001 * (double) _last_time.msecsTo(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())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply brush action
|
||||
if (_last_brush_action != 0)
|
||||
{
|
||||
double brush_strength;
|
||||
|
@ -232,16 +267,16 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
|||
switch (_brush_mode)
|
||||
{
|
||||
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;
|
||||
case HEIGHTMAP_BRUSH_SMOOTH:
|
||||
if (_last_brush_action < 0)
|
||||
{
|
||||
terrainBrushSmooth(_terrain->height_map, &brush, brush_strength * 0.1);
|
||||
terrainBrushSmooth(_terrain->height_map, &brush, brush_strength);
|
||||
}
|
||||
else
|
||||
{
|
||||
terrainBrushAddNoise(_terrain->height_map, &brush, _brush_noise, brush_strength * 10.0);
|
||||
terrainBrushAddNoise(_terrain->height_map, &brush, _brush_noise, brush_strength * 0.5);
|
||||
}
|
||||
break;
|
||||
case HEIGHTMAP_BRUSH_RESTORE:
|
||||
|
@ -256,50 +291,33 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
|||
updateGL();
|
||||
}
|
||||
|
||||
// Move camera
|
||||
if (cameraTransitionToAnother(_current_camera, _top_camera, 0.8))
|
||||
// Edge scrolling
|
||||
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);
|
||||
}
|
||||
|
||||
// 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)
|
||||
else if (wx > 1.0 - limit)
|
||||
{
|
||||
double dx = HEIGHTMAP_RESOLUTION / 2.0 - edge_length - _brush_x;
|
||||
_position_x -= (int)ceil(dx);
|
||||
|
||||
_dirty = true;
|
||||
updateGL();
|
||||
scrollTopCamera(force * (wx - (1.0 - limit)) / limit, 0.0);
|
||||
}
|
||||
if (_brush_x < -HEIGHTMAP_RESOLUTION / 2.0 + edge_length)
|
||||
if (wy < limit)
|
||||
{
|
||||
double dx = -HEIGHTMAP_RESOLUTION / 2.0 + edge_length - _brush_x;
|
||||
_position_x -= (int)ceil(dx);
|
||||
|
||||
_dirty = true;
|
||||
updateGL();
|
||||
scrollTopCamera(0.0, -(1.0 - wy / limit) * force);
|
||||
}
|
||||
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;
|
||||
updateGL();
|
||||
scrollTopCamera(0.0, force * (wy - (1.0 - limit)) / limit);
|
||||
}
|
||||
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()
|
||||
{
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
GLfloat light_diffuse[] = {0.75, 0.74, 0.7, 1.0};
|
||||
|
@ -327,8 +345,8 @@ void WidgetHeightMap::initializeGL()
|
|||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
//glEnable(GL_LINE_SMOOTH);
|
||||
//glLineWidth(1.0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(2.0);
|
||||
|
||||
glDisable(GL_FOG);
|
||||
|
||||
|
@ -337,6 +355,7 @@ void WidgetHeightMap::initializeGL()
|
|||
|
||||
void WidgetHeightMap::resizeGL(int w, int h)
|
||||
{
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
@ -414,9 +433,6 @@ void WidgetHeightMap::paintGL()
|
|||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// 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++)
|
||||
{
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
|
@ -427,8 +443,8 @@ void WidgetHeightMap::paintGL()
|
|||
_VertexInfo* vertex = _vertices + z * rx + x + dx;
|
||||
double diff_x, diff_z, diff;
|
||||
|
||||
diff_x = vertex->point.x - tx - _brush_x;
|
||||
diff_z = vertex->point.z - tz - _brush_z;
|
||||
diff_x = vertex->point.x - _target_x - _brush_x;
|
||||
diff_z = vertex->point.z - _target_z - _brush_z;
|
||||
diff = sqrt(diff_x * diff_x + diff_z * diff_z);
|
||||
if (diff > _brush_size)
|
||||
{
|
||||
|
@ -444,7 +460,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 - tx, vertex->point.y, vertex->point.z - tz);
|
||||
glVertex3f(vertex->point.x - _target_x, vertex->point.y, vertex->point.z - _target_z);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
@ -456,6 +472,7 @@ void WidgetHeightMap::paintGL()
|
|||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glColor4f(0.8, 0.0, 0.0, 0.1);
|
||||
for (int z = 0; z < rz; z++)
|
||||
{
|
||||
|
@ -463,7 +480,7 @@ void WidgetHeightMap::paintGL()
|
|||
for (int x = 0; x < 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();
|
||||
}
|
||||
|
@ -473,27 +490,30 @@ void WidgetHeightMap::paintGL()
|
|||
for (int z = 0; z < rz; z++)
|
||||
{
|
||||
_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();
|
||||
}
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
// Water
|
||||
if (_water)
|
||||
{
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(0.2, 0.3, 0.7, 0.7);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(camera_target.x - 500.0, _water_height, camera_target.z - 500.0);
|
||||
glVertex3f(camera_target.x - 500.0, _water_height, camera_target.z + 500.0);
|
||||
glVertex3f(camera_target.x + 500.0, _water_height, camera_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(_target_x - 500.0, _water_height, _target_z + 500.0);
|
||||
glVertex3f(_target_x + 500.0, _water_height, _target_z + 500.0);
|
||||
glVertex3f(_target_x + 500.0, _water_height, _target_z - 500.0);
|
||||
glEnd();
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
// Time stats
|
||||
|
@ -503,10 +523,38 @@ void WidgetHeightMap::paintGL()
|
|||
|
||||
while ((error_code = glGetError()) != GL_NO_ERROR)
|
||||
{
|
||||
|
||||
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()
|
||||
{
|
||||
int rx = HEIGHTMAP_RESOLUTION;
|
||||
|
@ -520,17 +568,14 @@ void WidgetHeightMap::updateVertexInfo()
|
|||
_memory_stats = terrainGetMemoryStats(_terrain);
|
||||
|
||||
// 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 z = 0; z < rz; z++)
|
||||
{
|
||||
_VertexInfo* vertex = _vertices + z * rx + x;
|
||||
|
||||
dx = tx + x - rx / 2;
|
||||
dz = tz + z - rz / 2;
|
||||
dx = _target_x + x - rx / 2;
|
||||
dz = _target_z + z - rz / 2;
|
||||
|
||||
vertex->point.x = (double) dx;
|
||||
vertex->point.z = (double) dz;
|
||||
|
|
|
@ -43,6 +43,7 @@ signals:
|
|||
void heightmapChanged();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
|
@ -55,6 +56,9 @@ protected:
|
|||
void paintGL();
|
||||
|
||||
private:
|
||||
void scrollTopCamera(double dx, double dz);
|
||||
void zoomTopCamera(double dzoom);
|
||||
|
||||
void updateVertexInfo();
|
||||
|
||||
private:
|
||||
|
@ -77,6 +81,8 @@ private:
|
|||
QDateTime _last_time;
|
||||
bool _mouse_moved;
|
||||
|
||||
double _target_x;
|
||||
double _target_z;
|
||||
CameraDefinition* _top_camera;
|
||||
CameraDefinition* _temp_camera;
|
||||
CameraDefinition* _current_camera;
|
||||
|
|
Loading…
Reference in a new issue