From f1fcd7058210a64d7a0483a117940c1ac6377037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 10 Jan 2013 15:41:14 +0000 Subject: [PATCH] paysages : Terrain painting (WIP). git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@491 b1fd45b6-86a6-48da-8261-f70d1f35bdcc --- gui_qt/widgetheightmap.cpp | 14 ++-- gui_qt/widgetheightmap.h | 2 + lib_paysages/terrain/main.c | 8 ++ lib_paysages/terrain/painting.c | 127 +++++++++++++++++++++++++------- lib_paysages/terrain/private.h | 10 +-- lib_paysages/terrain/public.h | 12 ++- 6 files changed, 134 insertions(+), 39 deletions(-) diff --git a/gui_qt/widgetheightmap.cpp b/gui_qt/widgetheightmap.cpp index 9362a42..0e11201 100644 --- a/gui_qt/widgetheightmap.cpp +++ b/gui_qt/widgetheightmap.cpp @@ -6,7 +6,7 @@ #include #include "tools.h" -#define HEIGHTMAP_RESOLUTION 512 +#define HEIGHTMAP_RESOLUTION 256 WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain): QGLWidget(parent) @@ -18,6 +18,8 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain): startTimer(100); _terrain = terrain; + _renderer = rendererCreate(); + TerrainRendererClass.bind(_renderer.terrain, _terrain); _vertices = new _VertexInfo[HEIGHTMAP_RESOLUTION * HEIGHTMAP_RESOLUTION]; _dirty = true; @@ -45,6 +47,7 @@ WidgetHeightMap::WidgetHeightMap(QWidget *parent, TerrainDefinition* terrain): WidgetHeightMap::~WidgetHeightMap() { + rendererDelete(&_renderer); noiseDeleteGenerator(_brush_noise); delete[] _vertices; } @@ -159,16 +162,16 @@ void WidgetHeightMap::timerEvent(QTimerEvent*) switch (_brush_mode) { case HEIGHTMAP_BRUSH_RAISE: - terrainBrushElevation(_terrain, &brush, brush_strength * _last_brush_action * 20.0); + terrainBrushElevation(_terrain->height_map, &brush, brush_strength * _last_brush_action * 20.0); break; case HEIGHTMAP_BRUSH_SMOOTH: if (_last_brush_action < 0) { - terrainBrushSmooth(_terrain, &brush, brush_strength * 0.1); + terrainBrushSmooth(_terrain->height_map, &brush, brush_strength * 0.1); } else { - terrainBrushAddNoise(_terrain, &brush, _brush_noise, brush_strength * 10.0); + terrainBrushAddNoise(_terrain->height_map, &brush, _brush_noise, brush_strength * 10.0); } break; default: @@ -361,8 +364,9 @@ void WidgetHeightMap::updateVertexInfo() _VertexInfo* vertex = _vertices + z * rx + x; vertex->point.x = 80.0 * (double)x / (double)(rx - 1) - 40.0; - vertex->point.y = 0.0; //_heightmap->data[z * rx + x]; vertex->point.z = 80.0 * (double)z / (double)(rz - 1) - 40.0; + + vertex->point.y = _renderer.terrain->getHeight(&_renderer, vertex->point.x, vertex->point.z); } } diff --git a/gui_qt/widgetheightmap.h b/gui_qt/widgetheightmap.h index 5e6f324..b287a54 100644 --- a/gui_qt/widgetheightmap.h +++ b/gui_qt/widgetheightmap.h @@ -4,6 +4,7 @@ #include #include #include "../lib_paysages/euclid.h" +#include "../lib_paysages/renderer.h" #include "../lib_paysages/terrain/public.h" typedef struct @@ -51,6 +52,7 @@ private: private: TerrainDefinition* _terrain; + Renderer _renderer; _VertexInfo* _vertices; bool _dirty; diff --git a/lib_paysages/terrain/main.c b/lib_paysages/terrain/main.c index b77ac59..5d10859 100644 --- a/lib_paysages/terrain/main.c +++ b/lib_paysages/terrain/main.c @@ -24,6 +24,9 @@ static TerrainDefinition* _createDefinition() definition->height = 0.0; definition->scaling = 1.0; definition->shadow_smoothing = 0.0; + + definition->height_map = terrainHeightMapCreate(); + definition->_height_noise = noiseCreateGenerator(); terrainAutoPreset(definition, TERRAIN_PRESET_STANDARD); @@ -33,6 +36,7 @@ static TerrainDefinition* _createDefinition() static void _deleteDefinition(TerrainDefinition* definition) { + terrainHeightmapDelete(definition->height_map); noiseDeleteGenerator(definition->_height_noise); free(definition); } @@ -43,6 +47,8 @@ static void _copyDefinition(TerrainDefinition* source, TerrainDefinition* destin destination->scaling = source->scaling; destination->shadow_smoothing = source->shadow_smoothing; + terrainHeightmapCopy(source->height_map, destination->height_map); + noiseCopy(source->_height_noise, destination->_height_noise); _validateDefinition(destination); @@ -53,6 +59,7 @@ static void _saveDefinition(PackStream* stream, TerrainDefinition* definition) packWriteDouble(stream, &definition->height); packWriteDouble(stream, &definition->scaling); packWriteDouble(stream, &definition->shadow_smoothing); + terrainHeightmapSave(stream, definition->height_map); noiseSaveGenerator(stream, definition->_height_noise); } @@ -61,6 +68,7 @@ static void _loadDefinition(PackStream* stream, TerrainDefinition* definition) packReadDouble(stream, &definition->height); packReadDouble(stream, &definition->scaling); packReadDouble(stream, &definition->shadow_smoothing); + terrainHeightmapLoad(stream, definition->height_map); noiseLoadGenerator(stream, definition->_height_noise); _validateDefinition(definition); diff --git a/lib_paysages/terrain/painting.c b/lib_paysages/terrain/painting.c index ed64d9b..975e401 100644 --- a/lib_paysages/terrain/painting.c +++ b/lib_paysages/terrain/painting.c @@ -5,65 +5,140 @@ */ #include +#include -TerrainHeightMap terrainHeightMapCreate() +TerrainHeightMap* terrainHeightMapCreate() { - TerrainHeightMap result; + TerrainHeightMap* result; - /*result.data = malloc(sizeof(double)); - result.resolution_x = 1; - result.resolution_z = 1;*/ + result = malloc(sizeof(TerrainHeightMap)); + result->fixed_count = 0; + result->fixed_data = malloc(sizeof(TerrainHeightMapData)); + result->floating_used = 0; + result->floating_data.data = malloc(sizeof(double)); return result; } void terrainHeightmapDelete(TerrainHeightMap* heightmap) { - /*free(heightmap->data);*/ + int i; + for (i = 0; i < heightmap->fixed_count; i++) + { + free(heightmap->fixed_data[i].data); + } + free(heightmap->fixed_data); + free(heightmap->floating_data.data); + free(heightmap); +} + +static void _setFixedCount(TerrainHeightMap* heightmap, int new_count) +{ + int old_count = heightmap->fixed_count; + int i; + + if (new_count > old_count) + { + heightmap->fixed_data = realloc(heightmap->fixed_data, sizeof(TerrainHeightMapData) * new_count); + for (i = old_count; i < new_count; i++) + { + heightmap->fixed_data[i].data = malloc(sizeof(double)); + } + } + else if (new_count < old_count) + { + for (i = new_count; i < old_count; i++) + { + free(heightmap->fixed_data[i].data); + } + if (new_count > 0) + { + heightmap->fixed_data = realloc(heightmap->fixed_data, sizeof(TerrainHeightMapData) * new_count); + } + } + + heightmap->fixed_count = new_count; } void terrainHeightmapCopy(TerrainHeightMap* source, TerrainHeightMap* destination) { - /*destination->resolution_x = source->resolution_x; - destination->resolution_z = source->resolution_z; - destination->data = realloc(destination->data, sizeof(double) * destination->resolution_x * destination->resolution_z); - memcpy(destination->data, source->data, sizeof(double) * destination->resolution_x * destination->resolution_z);*/ + int i, j; + + _setFixedCount(destination, source->fixed_count); + + for (i = 0; i < destination->fixed_count; i++) + { + destination->fixed_data[i].xstart = source->fixed_data[i].xstart; + destination->fixed_data[i].xsize = source->fixed_data[i].xsize; + destination->fixed_data[i].ystart = source->fixed_data[i].ystart; + destination->fixed_data[i].ysize = source->fixed_data[i].ysize; + if (destination->fixed_data[i].xsize * destination->fixed_data[i].ysize > 0) + { + destination->fixed_data[i].data = realloc(destination->fixed_data[i].data, sizeof(double) * destination->fixed_data[i].xsize * destination->fixed_data[i].ysize); + } + memcpy(destination->fixed_data[i].data, source->fixed_data[i].data, sizeof(double) * destination->fixed_data[i].xsize * destination->fixed_data[i].ysize); + } + + destination->floating_used = 0; } void terrainHeightmapSave(PackStream* stream, TerrainHeightMap* heightmap) { - /*int i; + int i, j; - packWriteInt(stream, &heightmap->resolution_x); - packWriteInt(stream, &heightmap->resolution_z); - for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++) + packWriteInt(stream, &heightmap->fixed_count); + for (i = 0; i < heightmap->fixed_count; i++) { - packWriteDouble(stream, &heightmap->data[i]); - }*/ + packWriteInt(stream, &heightmap->fixed_data[i].xstart); + packWriteInt(stream, &heightmap->fixed_data[i].xsize); + packWriteInt(stream, &heightmap->fixed_data[i].ystart); + packWriteInt(stream, &heightmap->fixed_data[i].ysize); + for (j = 0; j < heightmap->fixed_data[i].xsize * heightmap->fixed_data[i].ysize; j++) + { + packWriteDouble(stream, &heightmap->fixed_data[i].data[j]); + } + } } void terrainHeightmapLoad(PackStream* stream, TerrainHeightMap* heightmap) { - /*int i; + int new_count, i, j; - packReadInt(stream, &heightmap->resolution_x); - packReadInt(stream, &heightmap->resolution_z); - heightmap->data = realloc(heightmap->data, sizeof(double) * heightmap->resolution_x * heightmap->resolution_z); - for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++) + packReadInt(stream, &new_count); + _setFixedCount(heightmap, new_count); + + for (i = 0; i < heightmap->fixed_count; i++) { - packReadDouble(stream, &heightmap->data[i]); - }*/ + packReadInt(stream, &heightmap->fixed_data[i].xstart); + packReadInt(stream, &heightmap->fixed_data[i].xsize); + packReadInt(stream, &heightmap->fixed_data[i].ystart); + packReadInt(stream, &heightmap->fixed_data[i].ysize); + if (heightmap->fixed_data[i].xsize * heightmap->fixed_data[i].ysize > 0) + { + heightmap->fixed_data[i].data = realloc(heightmap->fixed_data[i].data, sizeof(double) * heightmap->fixed_data[i].xsize * heightmap->fixed_data[i].ysize); + } + for (j = 0; j < heightmap->fixed_data[i].xsize * heightmap->fixed_data[i].ysize; j++) + { + packReadDouble(stream, &heightmap->fixed_data[i].data[j]); + } + } + + heightmap->floating_used = 0; } -void terrainBrushElevation(TerrainDefinition* heightmap, TerrainBrush* brush, double value) +void terrainBrushElevation(TerrainHeightMap* heightmap, TerrainBrush* brush, double value) { } -void terrainBrushSmooth(TerrainDefinition* heightmap, TerrainBrush* brush, double value) +void terrainBrushSmooth(TerrainHeightMap* heightmap, TerrainBrush* brush, double value) { } -void terrainBrushAddNoise(TerrainDefinition* heightmap, TerrainBrush* brush, NoiseGenerator* generator, double value) +void terrainBrushAddNoise(TerrainHeightMap* heightmap, TerrainBrush* brush, NoiseGenerator* generator, double value) +{ +} + +void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double value) { } diff --git a/lib_paysages/terrain/private.h b/lib_paysages/terrain/private.h index 4243e63..3c54205 100644 --- a/lib_paysages/terrain/private.h +++ b/lib_paysages/terrain/private.h @@ -11,15 +11,15 @@ typedef struct int ystart; int xsize; int ysize; - void* data; + double* data; } TerrainHeightMapData; -typedef struct +struct TerrainHeightMap { int fixed_count; TerrainHeightMapData* fixed_data; - int floating_count; - TerrainHeightMapData* floating_data; -} TerrainHeightMap; + int floating_used; + TerrainHeightMapData floating_data; +}; #endif diff --git a/lib_paysages/terrain/public.h b/lib_paysages/terrain/public.h index 0138fad..63c4332 100644 --- a/lib_paysages/terrain/public.h +++ b/lib_paysages/terrain/public.h @@ -4,6 +4,7 @@ #include "../shared/types.h" #include "../noise.h" #include "../lighting.h" +#include "private.h" #ifdef __cplusplus extern "C" { @@ -14,12 +15,16 @@ typedef enum TERRAIN_PRESET_STANDARD } TerrainPreset; +typedef struct TerrainHeightMap TerrainHeightMap; + typedef struct { double height; double scaling; double shadow_smoothing; + TerrainHeightMap* height_map; + double _detail; NoiseGenerator* _height_noise; double _min_height; @@ -59,9 +64,10 @@ typedef struct double total_radius; } TerrainBrush; -void terrainBrushElevation(TerrainDefinition* heightmap, TerrainBrush* brush, double value); -void terrainBrushSmooth(TerrainDefinition* heightmap, TerrainBrush* brush, double value); -void terrainBrushAddNoise(TerrainDefinition* heightmap, TerrainBrush* brush, NoiseGenerator* generator, double value); +void terrainBrushElevation(TerrainHeightMap* heightmap, TerrainBrush* brush, double value); +void terrainBrushSmooth(TerrainHeightMap* heightmap, TerrainBrush* brush, double value); +void terrainBrushAddNoise(TerrainHeightMap* heightmap, TerrainBrush* brush, NoiseGenerator* generator, double value); +void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double value); #ifdef __cplusplus }