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 <math.h>
|
||||
#include <GL/glu.h>
|
||||
#include <qt4/QtCore/qlocale.h>
|
||||
#include "tools.h"
|
||||
#include "../lib_paysages/terrain.h"
|
||||
#include "../lib_paysages/scenery.h"
|
||||
|
@ -27,6 +28,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
|
|||
_last_brush_action = 0;
|
||||
_last_mouse_x = 0;
|
||||
_last_mouse_y = 0;
|
||||
_last_time = QDateTime::currentDateTime();
|
||||
_mouse_moved = false;
|
||||
|
||||
_angle_h = 0.0;
|
||||
|
@ -38,10 +40,14 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
|
|||
_brush_size = 10.0;
|
||||
_brush_smoothing = 0.5;
|
||||
_brush_strength = 1.0;
|
||||
_brush_noise = noiseCreateGenerator();
|
||||
noiseGenerateBaseNoise(_brush_noise, 102400);
|
||||
noiseAddLevelsSimple(_brush_noise, 6, 1.0, 1.0);
|
||||
}
|
||||
|
||||
WidgetHeightMap::~WidgetHeightMap()
|
||||
{
|
||||
noiseDeleteGenerator(_brush_noise);
|
||||
delete[] _vertexes;
|
||||
}
|
||||
|
||||
|
@ -155,10 +161,15 @@ void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event)
|
|||
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;
|
||||
|
||||
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.smoothed_size = _brush_size * _brush_smoothing / 80.0;
|
||||
|
||||
brush_strength = _brush_strength * duration / 0.1;
|
||||
|
||||
switch (_brush_mode)
|
||||
{
|
||||
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;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Only mark dirty the updated area
|
||||
_dirty = true;
|
||||
updateGL();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QDateTime>
|
||||
#include "../lib_paysages/euclid.h"
|
||||
#include "../lib_paysages/heightmap.h"
|
||||
|
||||
|
@ -60,6 +61,7 @@ private:
|
|||
int _last_brush_action;
|
||||
int _last_mouse_x;
|
||||
int _last_mouse_y;
|
||||
QDateTime _last_time;
|
||||
bool _mouse_moved;
|
||||
|
||||
double _angle_h;
|
||||
|
@ -71,6 +73,7 @@ private:
|
|||
double _brush_size;
|
||||
double _brush_smoothing;
|
||||
double _brush_strength;
|
||||
NoiseGenerator* _brush_noise;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "heightmap.h"
|
||||
#include "tools.h"
|
||||
#include "system.h"
|
||||
#include "noise.h"
|
||||
|
||||
#include <stdlib.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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int x, z;
|
||||
int x, x1, x2, z, z1, z2;
|
||||
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;
|
||||
for (z = 0; z < heightmap->resolution_z; z++)
|
||||
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));
|
||||
|
@ -169,3 +199,45 @@ void heightmapBrushElevation(HeightMap* heightmap, HeightMapBrush* brush, double
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
#include "pack.h"
|
||||
#include "noise.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -40,6 +41,8 @@ void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resol
|
|||
void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath);
|
||||
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue