paysages : Heightmap painting - Added noise brush.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@399 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
8654276b07
commit
a16c5dd975
4 changed files with 111 additions and 9 deletions
|
@ -4,6 +4,7 @@
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
|
#include <qt4/QtCore/qlocale.h>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "../lib_paysages/terrain.h"
|
#include "../lib_paysages/terrain.h"
|
||||||
#include "../lib_paysages/scenery.h"
|
#include "../lib_paysages/scenery.h"
|
||||||
|
@ -27,6 +28,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;
|
||||||
|
_last_time = QDateTime::currentDateTime();
|
||||||
_mouse_moved = false;
|
_mouse_moved = false;
|
||||||
|
|
||||||
_angle_h = 0.0;
|
_angle_h = 0.0;
|
||||||
|
@ -38,10 +40,14 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
|
||||||
_brush_size = 10.0;
|
_brush_size = 10.0;
|
||||||
_brush_smoothing = 0.5;
|
_brush_smoothing = 0.5;
|
||||||
_brush_strength = 1.0;
|
_brush_strength = 1.0;
|
||||||
|
_brush_noise = noiseCreateGenerator();
|
||||||
|
noiseGenerateBaseNoise(_brush_noise, 102400);
|
||||||
|
noiseAddLevelsSimple(_brush_noise, 6, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetHeightMap::~WidgetHeightMap()
|
WidgetHeightMap::~WidgetHeightMap()
|
||||||
{
|
{
|
||||||
|
noiseDeleteGenerator(_brush_noise);
|
||||||
delete[] _vertexes;
|
delete[] _vertexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,10 +161,15 @@ void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event)
|
||||||
updateGL();
|
updateGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetHeightMap::timerEvent(QTimerEvent* event)
|
void WidgetHeightMap::timerEvent(QTimerEvent*)
|
||||||
{
|
{
|
||||||
if (_last_brush_action)
|
QDateTime new_time = QDateTime::currentDateTime();
|
||||||
|
double duration = 0.001 * (double)_last_time.msecsTo(new_time);
|
||||||
|
_last_time = new_time;
|
||||||
|
|
||||||
|
if (_last_brush_action != 0)
|
||||||
{
|
{
|
||||||
|
double brush_strength;
|
||||||
HeightMapBrush brush;
|
HeightMapBrush brush;
|
||||||
|
|
||||||
brush.relative_x = (_brush_x + 40.0) / 80.0;
|
brush.relative_x = (_brush_x + 40.0) / 80.0;
|
||||||
|
@ -166,15 +177,28 @@ void WidgetHeightMap::timerEvent(QTimerEvent* event)
|
||||||
brush.hard_radius = _brush_size * (1.0 - _brush_smoothing) / 80.0;
|
brush.hard_radius = _brush_size * (1.0 - _brush_smoothing) / 80.0;
|
||||||
brush.smoothed_size = _brush_size * _brush_smoothing / 80.0;
|
brush.smoothed_size = _brush_size * _brush_smoothing / 80.0;
|
||||||
|
|
||||||
|
brush_strength = _brush_strength * duration / 0.1;
|
||||||
|
|
||||||
switch (_brush_mode)
|
switch (_brush_mode)
|
||||||
{
|
{
|
||||||
case HEIGHTMAP_BRUSH_RAISE:
|
case HEIGHTMAP_BRUSH_RAISE:
|
||||||
heightmapBrushElevation(_heightmap, &brush, _brush_strength * _last_brush_action);
|
heightmapBrushElevation(_heightmap, &brush, brush_strength * _last_brush_action);
|
||||||
|
break;
|
||||||
|
case HEIGHTMAP_BRUSH_SMOOTH:
|
||||||
|
if (_last_brush_action < 0)
|
||||||
|
{
|
||||||
|
heightmapBrushSmooth(_heightmap, &brush, brush_strength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
heightmapBrushAddNoise(_heightmap, &brush, _brush_noise, brush_strength);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Only mark dirty the updated area
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
updateGL();
|
updateGL();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
#define _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
||||||
|
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
|
#include <QDateTime>
|
||||||
#include "../lib_paysages/euclid.h"
|
#include "../lib_paysages/euclid.h"
|
||||||
#include "../lib_paysages/heightmap.h"
|
#include "../lib_paysages/heightmap.h"
|
||||||
|
|
||||||
|
@ -60,6 +61,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;
|
||||||
|
QDateTime _last_time;
|
||||||
bool _mouse_moved;
|
bool _mouse_moved;
|
||||||
|
|
||||||
double _angle_h;
|
double _angle_h;
|
||||||
|
@ -71,6 +73,7 @@ private:
|
||||||
double _brush_size;
|
double _brush_size;
|
||||||
double _brush_smoothing;
|
double _brush_smoothing;
|
||||||
double _brush_strength;
|
double _brush_strength;
|
||||||
|
NoiseGenerator* _brush_noise;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "heightmap.h"
|
#include "heightmap.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
#include "noise.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -140,17 +141,46 @@ double heightmapGetValue(HeightMap* heightmap, double x, double z)
|
||||||
return toolsBicubicInterpolate(stencil, x * xmax - (double)xlow, z * zmax - (double)zlow);
|
return toolsBicubicInterpolate(stencil, x * xmax - (double)xlow, z * zmax - (double)zlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void _getBrushBoundaries(HeightMapBrush* brush, int rx, int rz, int* x1, int* x2, int* z1, int* z2)
|
||||||
|
{
|
||||||
|
double cx = brush->relative_x * rx;
|
||||||
|
double cz = brush->relative_z * rz;
|
||||||
|
double s = brush->smoothed_size + brush->hard_radius;
|
||||||
|
double sx = s * rx;
|
||||||
|
double sz = s * rz;
|
||||||
|
*x1 = (int)floor(cx - sx);
|
||||||
|
*x2 = (int)ceil(cx + sx);
|
||||||
|
*z1 = (int)floor(cz - sz);
|
||||||
|
*z2 = (int)ceil(cz + sz);
|
||||||
|
if (*x1 < 0)
|
||||||
|
{
|
||||||
|
*x1 = 0;
|
||||||
|
}
|
||||||
|
if (*x1 > rx)
|
||||||
|
{
|
||||||
|
*x1 = rx;
|
||||||
|
}
|
||||||
|
if (*z1 < 0)
|
||||||
|
{
|
||||||
|
*z1 = 0;
|
||||||
|
}
|
||||||
|
if (*z1 > rz)
|
||||||
|
{
|
||||||
|
*z1 = rz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value)
|
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value)
|
||||||
{
|
{
|
||||||
int x, z;
|
int x, x1, x2, z, z1, z2;
|
||||||
double dx, dz, distance;
|
double dx, dz, distance;
|
||||||
|
|
||||||
/* TODO Limit to brush radius */
|
_getBrushBoundaries(brush, heightmap->resolution_x - 1, heightmap->resolution_z - 1, &x1, &x2, &z1, &z2);
|
||||||
|
|
||||||
for (x = 0; x < heightmap->resolution_x; x++)
|
for (x = x1; x <= x2; x++)
|
||||||
{
|
{
|
||||||
dx = (double)x / (double)heightmap->resolution_x;
|
dx = (double)x / (double)heightmap->resolution_x;
|
||||||
for (z = 0; z < heightmap->resolution_z; z++)
|
for (z = z1; z <= z2; z++)
|
||||||
{
|
{
|
||||||
dz = (double)z / (double)heightmap->resolution_z;
|
dz = (double)z / (double)heightmap->resolution_z;
|
||||||
distance = sqrt((brush->relative_x - dx) * (brush->relative_x - dx) + (brush->relative_z - dz) * (brush->relative_z - dz));
|
distance = sqrt((brush->relative_x - dx) * (brush->relative_x - dx) + (brush->relative_z - dz) * (brush->relative_z - dz));
|
||||||
|
@ -159,13 +189,55 @@ void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double
|
||||||
{
|
{
|
||||||
if (distance <= brush->hard_radius + brush->smoothed_size)
|
if (distance <= brush->hard_radius + brush->smoothed_size)
|
||||||
{
|
{
|
||||||
heightmap->data[z * heightmap->resolution_x +x] += value * (1.0 - (distance - brush->hard_radius) / brush->smoothed_size);
|
heightmap->data[z * heightmap->resolution_x + x] += value * (1.0 - (distance - brush->hard_radius) / brush->smoothed_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
heightmap->data[z * heightmap->resolution_x +x] += value;
|
heightmap->data[z * heightmap->resolution_x + x] += value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void heightmapBrushSmooth(HeightMap* heightmap, HeightMapBrush* brush, double value)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
void heightmapBrushAddNoise(HeightMap* heightmap, HeightMapBrush* brush, NoiseGenerator* generator, double value)
|
||||||
|
{
|
||||||
|
int x, x1, x2, z, z1, z2;
|
||||||
|
double dx, dz, distance, factor, brush_size;
|
||||||
|
|
||||||
|
_getBrushBoundaries(brush, heightmap->resolution_x - 1, heightmap->resolution_z - 1, &x1, &x2, &z1, &z2);
|
||||||
|
brush_size = brush->hard_radius + brush->smoothed_size;
|
||||||
|
|
||||||
|
for (x = x1; x <= x2; x++)
|
||||||
|
{
|
||||||
|
dx = (double)x / (double)heightmap->resolution_x;
|
||||||
|
for (z = z1; z <= z2; z++)
|
||||||
|
{
|
||||||
|
dz = (double)z / (double)heightmap->resolution_z;
|
||||||
|
distance = sqrt((brush->relative_x - dx) * (brush->relative_x - dx) + (brush->relative_z - dz) * (brush->relative_z - dz));
|
||||||
|
|
||||||
|
if (distance > brush->hard_radius)
|
||||||
|
{
|
||||||
|
if (distance <= brush->hard_radius + brush->smoothed_size)
|
||||||
|
{
|
||||||
|
factor = (1.0 - (distance - brush->hard_radius) / brush->smoothed_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
factor = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
heightmap->data[z * heightmap->resolution_x + x] += factor * noiseGet2DTotal(generator, dx / brush_size, dz / brush_size) * brush_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
/* Height map for terrain */
|
/* Height map for terrain */
|
||||||
|
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
#include "noise.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -40,6 +41,8 @@ void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resol
|
||||||
void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath);
|
void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath);
|
||||||
|
|
||||||
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value);
|
void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double value);
|
||||||
|
void heightmapBrushSmooth(HeightMap* heightmap, HeightMapBrush* brush, double value);
|
||||||
|
void heightmapBrushAddNoise(HeightMap* heightmap, HeightMapBrush* brush, NoiseGenerator* generator, double value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue