From 4477d40e7abee3d7588b5a8f3d72bf42499f7311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Mon, 23 Jul 2012 09:58:06 +0000 Subject: [PATCH] paysages : Heightmap fixes + added detail noise. git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@395 b1fd45b6-86a6-48da-8261-f70d1f35bdcc --- gui_qt/inputheightmap.cpp | 29 +++++++++++++++++++++++++++-- gui_qt/widgetheightmap.cpp | 34 ++++++++++++++++++++-------------- gui_qt/widgetheightmap.h | 1 + lib_paysages/heightmap.c | 29 +++++++++++++++++++++++++++++ lib_paysages/heightmap.h | 6 ++++-- lib_paysages/terraincanvas.c | 5 +++-- 6 files changed, 84 insertions(+), 20 deletions(-) diff --git a/gui_qt/inputheightmap.cpp b/gui_qt/inputheightmap.cpp index 640040d..036db27 100644 --- a/gui_qt/inputheightmap.cpp +++ b/gui_qt/inputheightmap.cpp @@ -14,8 +14,33 @@ public: void paintEvent(QPaintEvent* event) { + double min, max, value, fx, fy; + int ivalue; QPainter painter(this); - painter.fillRect(this->rect(), Qt::black); + + heightmapGetLimits(_value, &min, &max); + if (max - min < 0.000001) + { + painter.fillRect(rect(), Qt::black); + return; + } + + fx = 1.0 / (double)(width() - 1); + fy = 1.0 / (double)(height() - 1); + for (int x = 0; x < width(); x++) + { + for (int y = 0; y < height(); y++) + { + value = heightmapGetRawValue(_value, fx * x, fy * y); + ivalue = (int)(255.0 * (value - min) / (max - min)); + if (ivalue > 255 || ivalue < 0) + { + ivalue = 128; + } + painter.setPen(QColor(ivalue, ivalue, ivalue)); + painter.drawPoint(x, y); + } + } } HeightMap* _value; }; @@ -25,7 +50,7 @@ InputHeightMap::InputHeightMap(QWidget* form, QString label, HeightMap* value) : _value = value; _preview = new SmallPreviewHeightMap(form, value); - _preview->setMinimumSize(100, 40); + _preview->setMinimumSize(100, 100); _control = new QPushButton(tr("Paint"), form); _control->setMaximumWidth(150); diff --git a/gui_qt/widgetheightmap.cpp b/gui_qt/widgetheightmap.cpp index 0737b98..26fd766 100644 --- a/gui_qt/widgetheightmap.cpp +++ b/gui_qt/widgetheightmap.cpp @@ -27,6 +27,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap): _last_brush_action = 0; _last_mouse_x = 0; _last_mouse_y = 0; + _mouse_moved = false; _angle_h = 0.0; _angle_v = 0.3; @@ -149,6 +150,7 @@ void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event) _last_mouse_x = event->x(); _last_mouse_y = event->y(); + _mouse_moved = true; updateGL(); } @@ -238,24 +240,28 @@ void WidgetHeightMap::paintGL() } // Picking mouse position using z-buffer (for brush) - GLint viewport[4]; - GLdouble modelview[16]; - GLdouble projection[16]; - GLfloat winX, winY, winZ; - Vector3 point; + if (_mouse_moved) + { + GLint viewport[4]; + GLdouble modelview[16]; + GLdouble projection[16]; + GLfloat winX, winY, winZ; + Vector3 point; - glGetDoublev(GL_MODELVIEW_MATRIX, modelview); - glGetDoublev(GL_PROJECTION_MATRIX, projection); - glGetIntegerv(GL_VIEWPORT, viewport); + glGetDoublev(GL_MODELVIEW_MATRIX, modelview); + glGetDoublev(GL_PROJECTION_MATRIX, projection); + glGetIntegerv(GL_VIEWPORT, viewport); - winX = (float)_last_mouse_x; - winY = (float)height() - (float)_last_mouse_y; - glReadPixels(_last_mouse_x, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); + winX = (float)_last_mouse_x; + winY = (float)height() - (float)_last_mouse_y; + glReadPixels(_last_mouse_x, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); - gluUnProject(winX, winY, winZ, modelview, projection, viewport, &point.x, &point.y, &point.z); + gluUnProject(winX, winY, winZ, modelview, projection, viewport, &point.x, &point.y, &point.z); - _brush_x = point.x; - _brush_z = point.z; + _brush_x = point.x; + _brush_z = point.z; + _mouse_moved = false; + } // Place camera glMatrixMode(GL_MODELVIEW); diff --git a/gui_qt/widgetheightmap.h b/gui_qt/widgetheightmap.h index 3bddf33..89879ab 100644 --- a/gui_qt/widgetheightmap.h +++ b/gui_qt/widgetheightmap.h @@ -60,6 +60,7 @@ private: int _last_brush_action; int _last_mouse_x; int _last_mouse_y; + bool _mouse_moved; double _angle_h; double _angle_v; diff --git a/lib_paysages/heightmap.c b/lib_paysages/heightmap.c index ddad363..cc253e1 100644 --- a/lib_paysages/heightmap.c +++ b/lib_paysages/heightmap.c @@ -87,6 +87,35 @@ void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resol } } +double heightmapGetLimits(HeightMap* heightmap, double* ymin, double* ymax) +{ + double y; + int i; + *ymin = 1000000.0; + *ymax = -1000000.0; + /* TODO Keep the value in cache */ + for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++) + { + y = heightmap->data[i]; + if (y < *ymin) + { + *ymin = y; + } + if (y > *ymax) + { + *ymax = y; + } + } +} + +double heightmapGetRawValue(HeightMap* heightmap, double x, double z) +{ + assert(x >= 0.0 && x <= 1.0); + assert(z >= 0.0 && z <= 1.0); + + return heightmap->data[((int)(z * (double)(heightmap->resolution_z - 1))) * heightmap->resolution_x + ((int)(x * (double)(heightmap->resolution_x - 1)))]; +} + double heightmapGetValue(HeightMap* heightmap, double x, double z) { int xmax = heightmap->resolution_x - 1; diff --git a/lib_paysages/heightmap.h b/lib_paysages/heightmap.h index 16e58ba..5c89e6f 100644 --- a/lib_paysages/heightmap.h +++ b/lib_paysages/heightmap.h @@ -32,10 +32,12 @@ void heightmapValidate(HeightMap* heightmap); void heightmapSave(PackStream* stream, HeightMap* heightmap); void heightmapLoad(PackStream* stream, HeightMap* heightmap); -void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath); +double heightmapGetLimits(HeightMap* heightmap, double* ymin, double* ymax); +double heightmapGetRawValue(HeightMap* heightmap, double x, double z); +double heightmapGetValue(HeightMap* heightmap, double x, double z); void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z); -double heightmapGetValue(HeightMap* heightmap, double x, double z); +void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath); void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value); diff --git a/lib_paysages/terraincanvas.c b/lib_paysages/terraincanvas.c index 5930841..2b7611a 100644 --- a/lib_paysages/terraincanvas.c +++ b/lib_paysages/terraincanvas.c @@ -128,7 +128,8 @@ Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location) /* Apply factor */ height = height * canvas->height_factor + canvas->offset_y; - /* TODO Apply detail noise */ + /* Apply detail noise */ + height += noiseGet2DTotal(canvas->detail_noise, location.x / canvas->detail_scaling, location.z / canvas->detail_scaling) * canvas->detail_height_factor; /* Apply integration mask */ inside_x = (inside_x - 0.5) * 2.0; @@ -147,7 +148,7 @@ Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location) { location.y = height; } - else + else if (distance <= 1.0) { double influence = (1.0 - distance) / canvas->mask.smoothing; location.y = influence * height + (1.0 - influence) * location.y;