paysages : Terrain painting improvements (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@553 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
ae19273d18
commit
306a3fdd0b
5 changed files with 158 additions and 79 deletions
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QWidget>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
#include <qt4/QtGui/qwidget.h>
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define HEIGHTMAP_RESOLUTION 256
|
#define HEIGHTMAP_RESOLUTION 256
|
||||||
#define CAMERA_DISTANCE 200.0
|
|
||||||
|
|
||||||
WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain):
|
WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain):
|
||||||
QGLWidget(parent)
|
QGLWidget(parent)
|
||||||
|
@ -39,7 +38,8 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain):
|
||||||
_position_x = 0;
|
_position_x = 0;
|
||||||
_position_z = 0;
|
_position_z = 0;
|
||||||
_angle_h = 0.0;
|
_angle_h = 0.0;
|
||||||
_angle_v = 0.8;
|
_angle_v = 1.4;
|
||||||
|
_distance = 100.0;
|
||||||
|
|
||||||
_brush_x = 0.0;
|
_brush_x = 0.0;
|
||||||
_brush_z = 0.0;
|
_brush_z = 0.0;
|
||||||
|
@ -365,7 +365,7 @@ void WidgetHeightMap::paintGL()
|
||||||
// Place camera
|
// Place camera
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluLookAt(CAMERA_DISTANCE * cos(_angle_h) * cos(_angle_v), CAMERA_DISTANCE * sin(_angle_v), -CAMERA_DISTANCE * sin(_angle_h) * cos(_angle_v), 0.0, 0.0, 0.0, -cos(_angle_h) * sin(_angle_v), cos(_angle_v), sin(_angle_h) * sin(_angle_v));
|
gluLookAt(_distance * cos(_angle_h) * cos(_angle_v), _distance * sin(_angle_v), -_distance * sin(_angle_h) * cos(_angle_v), 0.0, 0.0, 0.0, -cos(_angle_h) * sin(_angle_v), cos(_angle_v), sin(_angle_h) * sin(_angle_v));
|
||||||
|
|
||||||
// Place lights
|
// Place lights
|
||||||
GLfloat light_position[] = { 40.0, 40.0, 40.0, 0.0 };
|
GLfloat light_position[] = { 40.0, 40.0, 40.0, 0.0 };
|
||||||
|
|
|
@ -77,6 +77,7 @@ private:
|
||||||
int _position_z;
|
int _position_z;
|
||||||
double _angle_h;
|
double _angle_h;
|
||||||
double _angle_v;
|
double _angle_v;
|
||||||
|
double _distance;
|
||||||
|
|
||||||
double _brush_x;
|
double _brush_x;
|
||||||
double _brush_z;
|
double _brush_z;
|
||||||
|
|
|
@ -375,7 +375,7 @@ double terrainGetGridHeight(TerrainDefinition* definition, int x, int z, int wit
|
||||||
{
|
{
|
||||||
double height;
|
double height;
|
||||||
|
|
||||||
if (!with_painting || !terrainHeightmapGetHeight(definition->height_map, (double)x, (double)z, &height))
|
if (!with_painting || !terrainHeightmapGetGridHeight(definition->height_map, x, z, &height))
|
||||||
{
|
{
|
||||||
height = noiseGet2DTotal(definition->_height_noise, (double)x, (double)z);
|
height = noiseGet2DTotal(definition->_height_noise, (double)x, (double)z);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +389,7 @@ double terrainGetInterpolatedHeight(TerrainDefinition* definition, double x, dou
|
||||||
x /= definition->scaling;
|
x /= definition->scaling;
|
||||||
z /= definition->scaling;
|
z /= definition->scaling;
|
||||||
|
|
||||||
if (!with_painting || !terrainHeightmapGetHeight(definition->height_map, x, z, &height))
|
if (!with_painting || !terrainHeightmapGetInterpolatedHeight(definition->height_map, x, z, &height))
|
||||||
{
|
{
|
||||||
height = noiseGet2DTotal(definition->_height_noise, x, z);
|
height = noiseGet2DTotal(definition->_height_noise, x, z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int z;
|
int z;
|
||||||
int memsize;
|
|
||||||
int pixel_groups_count;
|
int pixel_groups_count;
|
||||||
HeightMapPixelGroup* pixel_groups;
|
HeightMapPixelGroup* pixel_groups;
|
||||||
} HeightMapRow;
|
} HeightMapRow;
|
||||||
|
@ -45,6 +44,7 @@ static void _initData(HeightMapData* data)
|
||||||
{
|
{
|
||||||
data->rows_count = 0;
|
data->rows_count = 0;
|
||||||
data->rows = malloc(1);
|
data->rows = malloc(1);
|
||||||
|
data->memsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _clearData(HeightMapData* data)
|
static void _clearData(HeightMapData* data)
|
||||||
|
@ -60,6 +60,7 @@ static void _clearData(HeightMapData* data)
|
||||||
}
|
}
|
||||||
data->rows_count = 0;
|
data->rows_count = 0;
|
||||||
data->rows = realloc(data->rows, 1);
|
data->rows = realloc(data->rows, 1);
|
||||||
|
data->memsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _deleteData(HeightMapData* data)
|
static void _deleteData(HeightMapData* data)
|
||||||
|
@ -70,9 +71,36 @@ static void _deleteData(HeightMapData* data)
|
||||||
|
|
||||||
static void _copyData(HeightMapData* source, HeightMapData* destination)
|
static void _copyData(HeightMapData* source, HeightMapData* destination)
|
||||||
{
|
{
|
||||||
|
int i, j, n;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
_clearData(destination);
|
_clearData(destination);
|
||||||
|
|
||||||
/* TODO */
|
destination->rows_count = source->rows_count;
|
||||||
|
if (destination->rows_count > 0)
|
||||||
|
{
|
||||||
|
size = sizeof(HeightMapRow) * destination->rows_count;
|
||||||
|
destination->rows = realloc(destination->rows, size);
|
||||||
|
destination->memsize += size;
|
||||||
|
for (i = 0; i < destination->rows_count; i++)
|
||||||
|
{
|
||||||
|
destination->rows[i].z = source->rows[i].z;
|
||||||
|
destination->rows[i].pixel_groups_count = source->rows[i].pixel_groups_count;
|
||||||
|
size = sizeof(HeightMapPixelGroup) * destination->rows[i].pixel_groups_count;
|
||||||
|
destination->rows[i].pixel_groups = malloc(size);
|
||||||
|
destination->memsize += size;
|
||||||
|
for (j = 0; j < destination->rows[i].pixel_groups_count; j++)
|
||||||
|
{
|
||||||
|
destination->rows[i].pixel_groups[j].xstart = source->rows[i].pixel_groups[j].xstart;
|
||||||
|
destination->rows[i].pixel_groups[j].xend = source->rows[i].pixel_groups[j].xend;
|
||||||
|
n = destination->rows[i].pixel_groups[j].xend - destination->rows[i].pixel_groups[j].xstart;
|
||||||
|
size = sizeof(double) * n;
|
||||||
|
destination->rows[i].pixel_groups[j].height = malloc(size);
|
||||||
|
destination->memsize += size;
|
||||||
|
memcpy(destination->rows[i].pixel_groups[j].height, source->rows[i].pixel_groups[j].height, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _saveData(PackStream* stream, HeightMapData* data)
|
static void _saveData(PackStream* stream, HeightMapData* data)
|
||||||
|
@ -98,28 +126,38 @@ static void _saveData(PackStream* stream, HeightMapData* data)
|
||||||
static void _loadData(PackStream* stream, HeightMapData* data)
|
static void _loadData(PackStream* stream, HeightMapData* data)
|
||||||
{
|
{
|
||||||
int i, j, k, n;
|
int i, j, k, n;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
_clearData(data);
|
_clearData(data);
|
||||||
|
|
||||||
packReadInt(stream, &data->rows_count);
|
packReadInt(stream, &data->rows_count);
|
||||||
data->rows = realloc(data->rows, sizeof(HeightMapRow) * data->rows_count);
|
if (data->rows_count > 0)
|
||||||
|
{
|
||||||
|
size = sizeof(HeightMapRow) * data->rows_count;
|
||||||
|
data->rows = realloc(data->rows, size);
|
||||||
|
data->memsize += size;
|
||||||
for (i = 0; i < data->rows_count; i++)
|
for (i = 0; i < data->rows_count; i++)
|
||||||
{
|
{
|
||||||
packReadInt(stream, &data->rows[i].z);
|
packReadInt(stream, &data->rows[i].z);
|
||||||
packReadInt(stream, &data->rows[i].pixel_groups_count);
|
packReadInt(stream, &data->rows[i].pixel_groups_count);
|
||||||
data->rows[i].pixel_groups = malloc(sizeof(HeightMapPixelGroup) * data->rows[i].pixel_groups_count);
|
size = sizeof(HeightMapPixelGroup) * data->rows[i].pixel_groups_count;
|
||||||
|
data->rows[i].pixel_groups = malloc(size);
|
||||||
|
data->memsize += size;
|
||||||
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
||||||
{
|
{
|
||||||
packReadInt(stream, &data->rows[i].pixel_groups[j].xstart);
|
packReadInt(stream, &data->rows[i].pixel_groups[j].xstart);
|
||||||
packReadInt(stream, &data->rows[i].pixel_groups[j].xend);
|
packReadInt(stream, &data->rows[i].pixel_groups[j].xend);
|
||||||
n = data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart;
|
n = data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart;
|
||||||
data->rows[i].pixel_groups[j].height = malloc(sizeof(double) * n);
|
size = sizeof(double) * n;
|
||||||
|
data->rows[i].pixel_groups[j].height = malloc(size);
|
||||||
|
data->memsize += size;
|
||||||
for (k = 0; k < n; k++)
|
for (k = 0; k < n; k++)
|
||||||
{
|
{
|
||||||
packReadDouble(stream, &data->rows[i].pixel_groups[j].height[k]);
|
packReadDouble(stream, &data->rows[i].pixel_groups[j].height[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -127,7 +165,7 @@ static void _loadData(PackStream* stream, HeightMapData* data)
|
||||||
* If the location is not already in the heightmap, it is initialized with the terrain height.
|
* If the location is not already in the heightmap, it is initialized with the terrain height.
|
||||||
* This method will grow the heightmap as necessary (if 'grow' is set to false, NULL will be returned on missing pixels).
|
* This method will grow the heightmap as necessary (if 'grow' is set to false, NULL will be returned on missing pixels).
|
||||||
*/
|
*/
|
||||||
static double* _getDataPointer(HeightMapData* data, int x, int z, TerrainDefinition* terrain, int grow)
|
static double* _getDataPointer(HeightMapData* data, int x, int z, HeightMapData* fallback, TerrainDefinition* terrain, int grow)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -152,6 +190,7 @@ static double* _getDataPointer(HeightMapData* data, int x, int z, TerrainDefinit
|
||||||
row->pixel_groups = malloc(1);
|
row->pixel_groups = malloc(1);
|
||||||
|
|
||||||
data->rows_count++;
|
data->rows_count++;
|
||||||
|
data->memsize += sizeof(HeightMapRow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -192,6 +231,7 @@ static double* _getDataPointer(HeightMapData* data, int x, int z, TerrainDefinit
|
||||||
pixel = pixel_group->height;
|
pixel = pixel_group->height;
|
||||||
|
|
||||||
row->pixel_groups_count++;
|
row->pixel_groups_count++;
|
||||||
|
data->memsize += sizeof(HeightMapPixelGroup) + sizeof(double);
|
||||||
}
|
}
|
||||||
else if (x == pixel_group->xstart - 1)
|
else if (x == pixel_group->xstart - 1)
|
||||||
{
|
{
|
||||||
|
@ -203,6 +243,7 @@ static double* _getDataPointer(HeightMapData* data, int x, int z, TerrainDefinit
|
||||||
/* Extend the rowgroup at start */
|
/* Extend the rowgroup at start */
|
||||||
pixel_group->xstart--;
|
pixel_group->xstart--;
|
||||||
pixel = naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, 0);
|
pixel = naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, 0);
|
||||||
|
data->memsize += sizeof(double);
|
||||||
}
|
}
|
||||||
else if (x == pixel_group->xend + 1)
|
else if (x == pixel_group->xend + 1)
|
||||||
{
|
{
|
||||||
|
@ -214,6 +255,7 @@ static double* _getDataPointer(HeightMapData* data, int x, int z, TerrainDefinit
|
||||||
/* Extend the rowgroup at end */
|
/* Extend the rowgroup at end */
|
||||||
pixel_group->xend++;
|
pixel_group->xend++;
|
||||||
pixel = naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, pixel_group->xend - pixel_group->xstart);
|
pixel = naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, pixel_group->xend - pixel_group->xstart);
|
||||||
|
data->memsize += sizeof(double);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -224,10 +266,25 @@ static double* _getDataPointer(HeightMapData* data, int x, int z, TerrainDefinit
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset pixel if it had been added */
|
/* Reset pixel if it had been added */
|
||||||
if (added && terrain)
|
if (added && (terrain || fallback))
|
||||||
|
{
|
||||||
|
if (fallback)
|
||||||
|
{
|
||||||
|
double* dpointer = _getDataPointer(fallback, x, z, NULL, terrain, 0);
|
||||||
|
if (dpointer)
|
||||||
|
{
|
||||||
|
*pixel = *dpointer;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*pixel = terrainGetGridHeight(terrain, x, z, 0);
|
*pixel = terrainGetGridHeight(terrain, x, z, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pixel = terrainGetGridHeight(terrain, x, z, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
return pixel;
|
return pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,53 +326,71 @@ void terrainHeightmapLoad(PackStream* stream, TerrainHeightMap* heightmap)
|
||||||
_clearData(&heightmap->brush_data);
|
_clearData(&heightmap->brush_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int _getInterpolatedValue(HeightMapData* data, double x, double z, double* result, TerrainDefinition* terrain)
|
int terrainHeightmapGetGridHeight(TerrainHeightMap* heightmap, int x, int z, double* result)
|
||||||
{
|
{
|
||||||
/*if ((int)floor(x) >= chunk->rect.xstart && (int)floor(x) <= chunk->rect.xend && (int)floor(z) >= (double)chunk->rect.zstart && (int)floor(z) <= (double)chunk->rect.zend)
|
double* dpointer;
|
||||||
|
dpointer = _getDataPointer(&heightmap->brush_data, x, z, NULL, NULL, 0);
|
||||||
|
if (dpointer)
|
||||||
{
|
{
|
||||||
double stencil[16];
|
*result = *dpointer;
|
||||||
int ix, iz, cx, cz;
|
return 1;
|
||||||
int xmax = chunk->rect.xsize - 1;
|
|
||||||
int zmax = chunk->rect.zsize - 1;
|
|
||||||
int xlow;
|
|
||||||
int zlow;
|
|
||||||
|
|
||||||
x -= chunk->rect.xstart;
|
|
||||||
z -= chunk->rect.zstart;
|
|
||||||
|
|
||||||
xlow = floor(x);
|
|
||||||
zlow = floor(z);
|
|
||||||
|
|
||||||
for (ix = xlow - 1; ix <= xlow + 2; ix++)
|
|
||||||
{
|
|
||||||
for (iz = zlow - 1; iz <= zlow + 2; iz++)
|
|
||||||
{
|
|
||||||
cx = ix < 0 ? 0 : ix;
|
|
||||||
cx = cx > xmax ? xmax : cx;
|
|
||||||
cz = iz < 0 ? 0 : iz;
|
|
||||||
cz = cz > zmax ? zmax : cz;
|
|
||||||
stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = chunk->data[cz * chunk->rect.xsize + cx];
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
if (result)
|
|
||||||
{
|
{
|
||||||
*result = toolsBicubicInterpolate(stencil, x - (double)xlow, z - (double)zlow);
|
dpointer = _getDataPointer(&heightmap->merged_data, x, z, NULL, NULL, 0);
|
||||||
}
|
if (dpointer)
|
||||||
|
{
|
||||||
|
*result = *dpointer;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}*/
|
}
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int terrainHeightmapGetHeight(TerrainHeightMap* heightmap, double x, double z, double* result)
|
int terrainHeightmapGetInterpolatedHeight(TerrainHeightMap* heightmap, double x, double z, double* result)
|
||||||
{
|
{
|
||||||
/* TODO */
|
int ix, iz;
|
||||||
return 0;
|
int xlow;
|
||||||
|
int zlow;
|
||||||
|
|
||||||
|
xlow = floor(x);
|
||||||
|
zlow = floor(z);
|
||||||
|
|
||||||
|
int hit = 0;
|
||||||
|
for (ix = xlow - 1; ix <= xlow + 2 && !hit; ix++)
|
||||||
|
{
|
||||||
|
for (iz = zlow - 1; iz <= zlow + 2 && !hit; iz++)
|
||||||
|
{
|
||||||
|
if (_getDataPointer(&heightmap->brush_data, x, z, NULL, NULL, 0) || _getDataPointer(&heightmap->merged_data, x, z, NULL, NULL, 0))
|
||||||
|
{
|
||||||
|
hit = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit && result)
|
||||||
|
{
|
||||||
|
double stencil[16];
|
||||||
|
double value;
|
||||||
|
for (ix = xlow - 1; ix <= xlow + 2; ix++)
|
||||||
|
{
|
||||||
|
for (iz = zlow - 1; iz <= zlow + 2; iz++)
|
||||||
|
{
|
||||||
|
if (!terrainHeightmapGetGridHeight(heightmap, ix, iz, &value))
|
||||||
|
{
|
||||||
|
value = terrainGetGridHeight(heightmap->terrain, ix, iz, 0);
|
||||||
|
}
|
||||||
|
stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = toolsBicubicInterpolate(stencil, x - (double)xlow, z - (double)zlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline IntegerRect _getBrushRect(TerrainBrush* brush)
|
static inline IntegerRect _getBrushRect(TerrainBrush* brush)
|
||||||
|
@ -341,25 +416,12 @@ static inline int _isInRect(IntegerRect rect, int x, int z)
|
||||||
|
|
||||||
size_t terrainGetMemoryStats(TerrainDefinition* definition)
|
size_t terrainGetMemoryStats(TerrainDefinition* definition)
|
||||||
{
|
{
|
||||||
TerrainHeightMap* heightmap = definition->height_map;
|
return definition->height_map->merged_data.memsize + definition->height_map->brush_data.memsize;
|
||||||
size_t result = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*if (heightmap->floating_used)
|
|
||||||
{
|
|
||||||
result += sizeof(double) * heightmap->floating_data.rect.xsize * heightmap->floating_data.rect.zsize;
|
|
||||||
}
|
|
||||||
for (i = 0; i < heightmap->fixed_count; i++)
|
|
||||||
{
|
|
||||||
result += sizeof(double) * heightmap->fixed_data[i].rect.xsize * heightmap->fixed_data[i].rect.zsize;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int terrainIsPainted(TerrainHeightMap* heightmap, int x, int z)
|
int terrainIsPainted(TerrainHeightMap* heightmap, int x, int z)
|
||||||
{
|
{
|
||||||
return _getDataPointer(&heightmap->brush_data, x, z, NULL, 0) || _getDataPointer(&heightmap->merged_data, x, z, NULL, 0);
|
return _getDataPointer(&heightmap->brush_data, x, z, NULL, NULL, 0) || _getDataPointer(&heightmap->merged_data, x, z, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef double (*BrushCallback)(TerrainHeightMap* heightmap, TerrainBrush* brush, double x, double z, double basevalue, double influence, double force, void* data);
|
typedef double (*BrushCallback)(TerrainHeightMap* heightmap, TerrainBrush* brush, double x, double z, double basevalue, double influence, double force, void* data);
|
||||||
|
@ -394,7 +456,7 @@ static inline void _applyBrush(TerrainHeightMap* heightmap, TerrainBrush* brush,
|
||||||
influence = 1.0;
|
influence = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double* dpointer = _getDataPointer(&heightmap->brush_data, x, z, heightmap->terrain, 1);
|
double* dpointer = _getDataPointer(&heightmap->brush_data, x, z, &heightmap->merged_data, heightmap->terrain, 1);
|
||||||
*dpointer = callback(heightmap, brush, dx, dz, *dpointer, influence, force, data);
|
*dpointer = callback(heightmap, brush, dx, dz, *dpointer, influence, force, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -467,5 +529,20 @@ void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double
|
||||||
|
|
||||||
void terrainEndBrushStroke(TerrainHeightMap* heightmap)
|
void terrainEndBrushStroke(TerrainHeightMap* heightmap)
|
||||||
{
|
{
|
||||||
/* TODO Merge data */
|
int i, j, k;
|
||||||
|
HeightMapData* data = &heightmap->brush_data;
|
||||||
|
|
||||||
|
for (i = 0; i < data->rows_count; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
||||||
|
{
|
||||||
|
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart; k++)
|
||||||
|
{
|
||||||
|
double* dpointer = _getDataPointer(&heightmap->merged_data, data->rows[i].pixel_groups[j].xstart + k, data->rows[i].z, NULL, NULL, 1);
|
||||||
|
*dpointer = data->rows[i].pixel_groups[j].height[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearData(&heightmap->brush_data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ void terrainHeightmapDelete(TerrainHeightMap* heightmap);
|
||||||
void terrainHeightmapCopy(TerrainHeightMap* source, TerrainHeightMap* destination);
|
void terrainHeightmapCopy(TerrainHeightMap* source, TerrainHeightMap* destination);
|
||||||
void terrainHeightmapSave(PackStream* stream, TerrainHeightMap* heightmap);
|
void terrainHeightmapSave(PackStream* stream, TerrainHeightMap* heightmap);
|
||||||
void terrainHeightmapLoad(PackStream* stream, TerrainHeightMap* heightmap);
|
void terrainHeightmapLoad(PackStream* stream, TerrainHeightMap* heightmap);
|
||||||
int terrainHeightmapGetHeight(TerrainHeightMap* heightmap, double x, double z, double* result);
|
int terrainHeightmapGetInterpolatedHeight(TerrainHeightMap* heightmap, double x, double z, double* result);
|
||||||
|
int terrainHeightmapGetGridHeight(TerrainHeightMap* heightmap, int x, int z, double* result);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue