paysages : Heightmap fixes + added detail noise.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@395 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-07-23 09:58:06 +00:00 committed by ThunderK
parent a4353f8a64
commit 4477d40e7a
6 changed files with 84 additions and 20 deletions

View file

@ -14,8 +14,33 @@ public:
void paintEvent(QPaintEvent* event) void paintEvent(QPaintEvent* event)
{ {
double min, max, value, fx, fy;
int ivalue;
QPainter painter(this); 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; HeightMap* _value;
}; };
@ -25,7 +50,7 @@ InputHeightMap::InputHeightMap(QWidget* form, QString label, HeightMap* value) :
_value = value; _value = value;
_preview = new SmallPreviewHeightMap(form, value); _preview = new SmallPreviewHeightMap(form, value);
_preview->setMinimumSize(100, 40); _preview->setMinimumSize(100, 100);
_control = new QPushButton(tr("Paint"), form); _control = new QPushButton(tr("Paint"), form);
_control->setMaximumWidth(150); _control->setMaximumWidth(150);

View file

@ -27,6 +27,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
_last_brush_action = 0; _last_brush_action = 0;
_last_mouse_x = 0; _last_mouse_x = 0;
_last_mouse_y = 0; _last_mouse_y = 0;
_mouse_moved = false;
_angle_h = 0.0; _angle_h = 0.0;
_angle_v = 0.3; _angle_v = 0.3;
@ -149,6 +150,7 @@ void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event)
_last_mouse_x = event->x(); _last_mouse_x = event->x();
_last_mouse_y = event->y(); _last_mouse_y = event->y();
_mouse_moved = true;
updateGL(); updateGL();
} }
@ -238,24 +240,28 @@ void WidgetHeightMap::paintGL()
} }
// Picking mouse position using z-buffer (for brush) // Picking mouse position using z-buffer (for brush)
GLint viewport[4]; if (_mouse_moved)
GLdouble modelview[16]; {
GLdouble projection[16]; GLint viewport[4];
GLfloat winX, winY, winZ; GLdouble modelview[16];
Vector3 point; GLdouble projection[16];
GLfloat winX, winY, winZ;
Vector3 point;
glGetDoublev(GL_MODELVIEW_MATRIX, modelview); glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection); glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport);
winX = (float)_last_mouse_x; winX = (float)_last_mouse_x;
winY = (float)height() - (float)_last_mouse_y; winY = (float)height() - (float)_last_mouse_y;
glReadPixels(_last_mouse_x, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); 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_x = point.x;
_brush_z = point.z; _brush_z = point.z;
_mouse_moved = false;
}
// Place camera // Place camera
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);

View file

@ -60,6 +60,7 @@ private:
int _last_brush_action; int _last_brush_action;
int _last_mouse_x; int _last_mouse_x;
int _last_mouse_y; int _last_mouse_y;
bool _mouse_moved;
double _angle_h; double _angle_h;
double _angle_v; double _angle_v;

View file

@ -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) double heightmapGetValue(HeightMap* heightmap, double x, double z)
{ {
int xmax = heightmap->resolution_x - 1; int xmax = heightmap->resolution_x - 1;

View file

@ -32,10 +32,12 @@ void heightmapValidate(HeightMap* heightmap);
void heightmapSave(PackStream* stream, HeightMap* heightmap); void heightmapSave(PackStream* stream, HeightMap* heightmap);
void heightmapLoad(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); 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); void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value);

View file

@ -128,7 +128,8 @@ Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location)
/* Apply factor */ /* Apply factor */
height = height * canvas->height_factor + canvas->offset_y; 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 */ /* Apply integration mask */
inside_x = (inside_x - 0.5) * 2.0; inside_x = (inside_x - 0.5) * 2.0;
@ -147,7 +148,7 @@ Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location)
{ {
location.y = height; location.y = height;
} }
else else if (distance <= 1.0)
{ {
double influence = (1.0 - distance) / canvas->mask.smoothing; double influence = (1.0 - distance) / canvas->mask.smoothing;
location.y = influence * height + (1.0 - influence) * location.y; location.y = influence * height + (1.0 - influence) * location.y;