paysages : Terrain canvas (WIP).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@388 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
e1def5c5d5
commit
a52321fd45
13 changed files with 438 additions and 35 deletions
|
@ -8,6 +8,7 @@
|
||||||
#include "inputnoise.h"
|
#include "inputnoise.h"
|
||||||
#include "inputcurve.h"
|
#include "inputcurve.h"
|
||||||
#include "inputmaterial.h"
|
#include "inputmaterial.h"
|
||||||
|
#include "inputheightmap.h"
|
||||||
#include "inputenum.h"
|
#include "inputenum.h"
|
||||||
#include "inputlayers.h"
|
#include "inputlayers.h"
|
||||||
|
|
||||||
|
@ -407,6 +408,11 @@ BaseInput* BaseForm::addInputMaterial(QString label, SurfaceMaterial* material)
|
||||||
return addInput(new InputMaterial(_form, label, material));
|
return addInput(new InputMaterial(_form, label, material));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseInput* BaseForm::addInputHeightMap(QString label, HeightMap* heightmap)
|
||||||
|
{
|
||||||
|
return addInput(new InputHeightMap(_form, label, heightmap));
|
||||||
|
}
|
||||||
|
|
||||||
BaseInput* BaseForm::addInputEnum(QString label, int* value, const QStringList& values)
|
BaseInput* BaseForm::addInputEnum(QString label, int* value, const QStringList& values)
|
||||||
{
|
{
|
||||||
return addInput(new InputEnum(_form, label, value, values));
|
return addInput(new InputEnum(_form, label, value, values));
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../lib_paysages/curve.h"
|
#include "../lib_paysages/curve.h"
|
||||||
#include "../lib_paysages/color.h"
|
#include "../lib_paysages/color.h"
|
||||||
#include "../lib_paysages/layers.h"
|
#include "../lib_paysages/layers.h"
|
||||||
|
#include "../lib_paysages/heightmap.h"
|
||||||
#include "../lib_paysages/pack.h"
|
#include "../lib_paysages/pack.h"
|
||||||
|
|
||||||
class BaseForm:public QWidget
|
class BaseForm:public QWidget
|
||||||
|
@ -56,6 +57,7 @@ protected:
|
||||||
BaseInput* addInputNoise(QString label, NoiseGenerator* value);
|
BaseInput* addInputNoise(QString label, NoiseGenerator* value);
|
||||||
BaseInput* addInputCurve(QString label, Curve* value, double xmin, double xmax, double ymin, double ymax, QString xlabel, QString ylabel);
|
BaseInput* addInputCurve(QString label, Curve* value, double xmin, double xmax, double ymin, double ymax, QString xlabel, QString ylabel);
|
||||||
BaseInput* addInputMaterial(QString label, SurfaceMaterial* material);
|
BaseInput* addInputMaterial(QString label, SurfaceMaterial* material);
|
||||||
|
BaseInput* addInputHeightMap(QString label, HeightMap* heightmap);
|
||||||
BaseInput* addInputEnum(QString label, int* value, const QStringList& values);
|
BaseInput* addInputEnum(QString label, int* value, const QStringList& values);
|
||||||
BaseInput* addInputLayers(QString label, Layers* value, FormLayerBuilder form_builder);
|
BaseInput* addInputLayers(QString label, Layers* value, FormLayerBuilder form_builder);
|
||||||
|
|
||||||
|
|
93
gui_qt/dialogheightmap.cpp
Normal file
93
gui_qt/dialogheightmap.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#include "dialogheightmap.h"
|
||||||
|
#include "widgetheightmap.h"
|
||||||
|
|
||||||
|
#include <QBoxLayout>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QSlider>
|
||||||
|
|
||||||
|
/**************** Dialog form ****************/
|
||||||
|
DialogHeightMap::DialogHeightMap(QWidget* parent, HeightMap* heightmap) : DialogWithPreview(parent)
|
||||||
|
{
|
||||||
|
QWidget* mainarea;
|
||||||
|
QWidget* buttons;
|
||||||
|
QWidget* panel;
|
||||||
|
QWidget* viewer;
|
||||||
|
QGridLayout* viewer_layout;
|
||||||
|
|
||||||
|
QSlider* slider;
|
||||||
|
QPushButton* button;
|
||||||
|
|
||||||
|
_value_original = heightmap;
|
||||||
|
_value_modified = heightmapCreate();
|
||||||
|
heightmapCopy(_value_original, &_value_modified);
|
||||||
|
setLayout(new QVBoxLayout());
|
||||||
|
|
||||||
|
// Dialog layout (main area + buttons)
|
||||||
|
mainarea = new QWidget(this);
|
||||||
|
mainarea->setLayout(new QHBoxLayout());
|
||||||
|
this->layout()->addWidget(mainarea);
|
||||||
|
|
||||||
|
buttons = new QWidget(this);
|
||||||
|
buttons->setLayout(new QHBoxLayout());
|
||||||
|
buttons->layout()->setAlignment(buttons, Qt::AlignBottom);
|
||||||
|
this->layout()->addWidget(buttons);
|
||||||
|
|
||||||
|
// Main area layout (viewer + panel)
|
||||||
|
viewer = new QWidget(mainarea);
|
||||||
|
viewer_layout = new QGridLayout();
|
||||||
|
viewer->setLayout(viewer_layout);
|
||||||
|
mainarea->layout()->addWidget(viewer);
|
||||||
|
|
||||||
|
panel = new QWidget(mainarea);
|
||||||
|
panel->setLayout(new QVBoxLayout());
|
||||||
|
mainarea->layout()->addWidget(panel);
|
||||||
|
|
||||||
|
// Viewer layout (3d display + sliders)
|
||||||
|
_3dview = new WidgetHeightMap(viewer, &_value_modified);
|
||||||
|
viewer_layout->addWidget(_3dview, 0, 0);
|
||||||
|
slider = new QSlider(Qt::Horizontal, viewer);
|
||||||
|
viewer_layout->addWidget(slider, 1, 0);
|
||||||
|
slider = new QSlider(Qt::Vertical, viewer);
|
||||||
|
viewer_layout->addWidget(slider, 0, 1);
|
||||||
|
|
||||||
|
// Panel layout
|
||||||
|
button = new QPushButton(tr("Reset to terrain height"), buttons);
|
||||||
|
panel->layout()->addWidget(button);
|
||||||
|
|
||||||
|
// Buttons layout
|
||||||
|
button = new QPushButton(tr("Validate"), buttons);
|
||||||
|
buttons->layout()->addWidget(button);
|
||||||
|
QObject::connect(button, SIGNAL(clicked()), this, SLOT(accept()));
|
||||||
|
|
||||||
|
button = new QPushButton(tr("Revert"), buttons);
|
||||||
|
buttons->layout()->addWidget(button);
|
||||||
|
QObject::connect(button, SIGNAL(clicked()), this, SLOT(revert()));
|
||||||
|
|
||||||
|
button = new QPushButton(tr("Cancel"), buttons);
|
||||||
|
buttons->layout()->addWidget(button);
|
||||||
|
QObject::connect(button, SIGNAL(clicked()), this, SLOT(reject()));
|
||||||
|
|
||||||
|
setWindowTitle(tr("Paysages 3D - Height map painting"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DialogHeightMap::editHeightMap(QWidget* parent, HeightMap* heightmap)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
DialogHeightMap* dialog = new DialogHeightMap(parent, heightmap);
|
||||||
|
result = dialog->exec();
|
||||||
|
|
||||||
|
delete dialog;
|
||||||
|
|
||||||
|
return (result != 0) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogHeightMap::accept()
|
||||||
|
{
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogHeightMap::revert()
|
||||||
|
{
|
||||||
|
}
|
25
gui_qt/dialogheightmap.h
Normal file
25
gui_qt/dialogheightmap.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef _PAYSAGES_QT_DIALOGHEIGHTMAP_H_
|
||||||
|
#define _PAYSAGES_QT_DIALOGHEIGHTMAP_H_
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
#include "widgetheightmap.h"
|
||||||
|
#include "../lib_paysages/heightmap.h"
|
||||||
|
|
||||||
|
class DialogHeightMap : public DialogWithPreview
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DialogHeightMap(QWidget* parent, HeightMap* heightmap);
|
||||||
|
static bool editHeightMap(QWidget* parent, HeightMap* heightmap);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void accept();
|
||||||
|
void revert();
|
||||||
|
|
||||||
|
private:
|
||||||
|
HeightMap* _value_original;
|
||||||
|
HeightMap _value_modified;
|
||||||
|
WidgetHeightMap* _3dview;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,13 +8,13 @@ FormTerrainCanvas::FormTerrainCanvas(QWidget *parent, Layers* layers):
|
||||||
|
|
||||||
// TODO Area
|
// TODO Area
|
||||||
addInputDouble(tr("Apply at height"), &_definition->offset_z, -20.0, 20.0, 0.1, 1.0);
|
addInputDouble(tr("Apply at height"), &_definition->offset_z, -20.0, 20.0, 0.1, 1.0);
|
||||||
// TODO Height map
|
addInputHeightMap(tr("Height map"), &_definition->height_map);
|
||||||
addInputDouble(tr("Canvas height"), &_definition->height_factor, 0.0, 20.0, 0.1, 1.0);
|
addInputDouble(tr("Canvas height"), &_definition->height_factor, 0.0, 20.0, 0.1, 1.0);
|
||||||
addInputNoise(tr("Detail noise"), _definition->detail_noise);
|
addInputNoise(tr("Detail noise"), _definition->detail_noise);
|
||||||
addInputDouble(tr("Detail noise height"), &_definition->detail_height_factor, 0.0, 20.0, 0.1, 1.0);
|
addInputDouble(tr("Detail noise height"), &_definition->detail_height_factor, 0.0, 20.0, 0.1, 1.0);
|
||||||
addInputDouble(tr("Detail noise scaling"), &_definition->detail_scaling, 0.0, 20.0, 0.1, 1.0);
|
addInputDouble(tr("Detail noise scaling"), &_definition->detail_scaling, 0.0, 20.0, 0.1, 1.0);
|
||||||
// TODO Mask mode
|
addInputEnum(tr("Mask shape"), &_definition->mask_mode, QStringList(tr("Square")) << tr("Circle"));
|
||||||
// TODO Mask smoothing
|
addInputDouble(tr("Mask smoothing"), &_definition->mask_smoothing, 0.0, 1.0, 0.01, 0.1);
|
||||||
|
|
||||||
revertConfig();
|
revertConfig();
|
||||||
}
|
}
|
||||||
|
|
59
gui_qt/inputheightmap.cpp
Normal file
59
gui_qt/inputheightmap.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#include "inputheightmap.h"
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QPainter>
|
||||||
|
#include "dialogheightmap.h"
|
||||||
|
|
||||||
|
class SmallPreviewHeightMap:public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SmallPreviewHeightMap(QWidget* parent, HeightMap* value) : QWidget(parent)
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent* event)
|
||||||
|
{
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.fillRect(this->rect(), Qt::black);
|
||||||
|
}
|
||||||
|
HeightMap* _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
InputHeightMap::InputHeightMap(QWidget* form, QString label, HeightMap* value) : BaseInput(form, label)
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
|
||||||
|
_preview = new SmallPreviewHeightMap(form, value);
|
||||||
|
_preview->setMinimumSize(100, 40);
|
||||||
|
|
||||||
|
_control = new QPushButton(tr("Paint"), form);
|
||||||
|
_control->setMaximumWidth(150);
|
||||||
|
|
||||||
|
connect((QPushButton*)_control, SIGNAL(clicked()), this, SLOT(editHeightMap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHeightMap::updatePreview()
|
||||||
|
{
|
||||||
|
_preview->update();
|
||||||
|
|
||||||
|
BaseInput::updatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHeightMap::applyValue()
|
||||||
|
{
|
||||||
|
BaseInput::applyValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHeightMap::revert()
|
||||||
|
{
|
||||||
|
BaseInput::revert();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHeightMap::editHeightMap()
|
||||||
|
{
|
||||||
|
if (DialogHeightMap::editHeightMap(_control, _value))
|
||||||
|
{
|
||||||
|
applyValue();
|
||||||
|
}
|
||||||
|
}
|
28
gui_qt/inputheightmap.h
Normal file
28
gui_qt/inputheightmap.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef _PAYSAGES_QT_INPUTHEIGHTMAP_H_
|
||||||
|
#define _PAYSAGES_QT_INPUTHEIGHTMAP_H_
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include "baseinput.h"
|
||||||
|
|
||||||
|
#include "../lib_paysages/heightmap.h"
|
||||||
|
|
||||||
|
class InputHeightMap:public BaseInput
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
InputHeightMap(QWidget* form, QString label, HeightMap* value);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void updatePreview();
|
||||||
|
virtual void applyValue();
|
||||||
|
virtual void revert();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void editHeightMap();
|
||||||
|
|
||||||
|
private:
|
||||||
|
HeightMap* _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
98
gui_qt/widgetheightmap.cpp
Normal file
98
gui_qt/widgetheightmap.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#include "widgetheightmap.h"
|
||||||
|
|
||||||
|
#include <QTime>
|
||||||
|
#include <math.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
WidgetHeightMap::WidgetHeightMap(QWidget *parent, HeightMap* heightmap):
|
||||||
|
QGLWidget(parent)
|
||||||
|
{
|
||||||
|
setMinimumSize(500, 500);
|
||||||
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
|
|
||||||
|
_average_frame_time = 0.0;
|
||||||
|
_last_mouse_x = 0;
|
||||||
|
_last_mouse_y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetHeightMap::~WidgetHeightMap()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::keyPressEvent(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::mousePressEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::wheelEvent(QWheelEvent* event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::initializeGL()
|
||||||
|
{
|
||||||
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
|
glFrontFace(GL_CCW);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
glDepthMask(true);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
glLineWidth(1.0);
|
||||||
|
|
||||||
|
glDisable(GL_FOG);
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::resizeGL(int w, int h)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
//gluPerspective(_current_camera.yfov * 180.0 / M_PI, _current_camera.xratio, _current_camera.znear, _current_camera.zfar);
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetHeightMap::paintGL()
|
||||||
|
{
|
||||||
|
GLenum error_code;
|
||||||
|
QTime start_time;
|
||||||
|
double frame_time;
|
||||||
|
|
||||||
|
start_time = QTime::currentTime();
|
||||||
|
|
||||||
|
// Place camera
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
//gluLookAt(_current_camera.location.x, _current_camera.location.y, _current_camera.location.z, _current_camera.target.x, _current_camera.target.y, _current_camera.target.z, _current_camera.up.x, _current_camera.up.y, _current_camera.up.z);
|
||||||
|
|
||||||
|
// Background
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
// Time stats
|
||||||
|
frame_time = 0.001 * (double)start_time.msecsTo(QTime::currentTime());
|
||||||
|
_average_frame_time = _average_frame_time * 0.8 + frame_time * 0.2;
|
||||||
|
//printf("%d %f\n", quality, average_frame_time);
|
||||||
|
|
||||||
|
while ((error_code = glGetError()) != GL_NO_ERROR)
|
||||||
|
{
|
||||||
|
logDebug(QString("[OpenGL] ERROR : ") + (const char*)gluErrorString(error_code));
|
||||||
|
}
|
||||||
|
}
|
30
gui_qt/widgetheightmap.h
Normal file
30
gui_qt/widgetheightmap.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
||||||
|
#define _PAYSAGES_QT_WIDGETHEIGHTMAP_H_
|
||||||
|
|
||||||
|
#include <QGLWidget>
|
||||||
|
#include "../lib_paysages/heightmap.h"
|
||||||
|
|
||||||
|
class WidgetHeightMap : public QGLWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WidgetHeightMap(QWidget* parent, HeightMap* heightmap);
|
||||||
|
~WidgetHeightMap();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent* event);
|
||||||
|
void mousePressEvent(QMouseEvent* event);
|
||||||
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
|
void wheelEvent(QWheelEvent* event);
|
||||||
|
|
||||||
|
void initializeGL();
|
||||||
|
void resizeGL(int w, int h);
|
||||||
|
void paintGL();
|
||||||
|
|
||||||
|
private:
|
||||||
|
double _average_frame_time;
|
||||||
|
int _last_mouse_x;
|
||||||
|
int _last_mouse_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
56
lib_paysages/heightmap.c
Normal file
56
lib_paysages/heightmap.c
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#include "heightmap.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
HeightMap heightmapCreate()
|
||||||
|
{
|
||||||
|
HeightMap result;
|
||||||
|
|
||||||
|
result.data = malloc(sizeof(double));
|
||||||
|
result.resolution_x = 1;
|
||||||
|
result.resolution_z = 1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void heightmapDelete(HeightMap* heightmap)
|
||||||
|
{
|
||||||
|
free(heightmap->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void heightmapCopy(HeightMap* source, HeightMap* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void heightmapValidate(HeightMap* heightmap)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void heightmapSave(PackStream* stream, HeightMap* heightmap)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
packWriteInt(stream, &heightmap->resolution_x);
|
||||||
|
packWriteInt(stream, &heightmap->resolution_z);
|
||||||
|
for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++)
|
||||||
|
{
|
||||||
|
packWriteDouble(stream, &heightmap->data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void heightmapLoad(PackStream* stream, HeightMap* heightmap)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
packReadInt(stream, &heightmap->resolution_x);
|
||||||
|
packReadInt(stream, &heightmap->resolution_z);
|
||||||
|
for (i = 0; i < heightmap->resolution_x * heightmap->resolution_z; i++)
|
||||||
|
{
|
||||||
|
packReadDouble(stream, &heightmap->data[i]);
|
||||||
|
}
|
||||||
|
}
|
31
lib_paysages/heightmap.h
Normal file
31
lib_paysages/heightmap.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef _PAYSAGES_HEIGHTMAP_H_
|
||||||
|
#define _PAYSAGES_HEIGHTMAP_H_
|
||||||
|
|
||||||
|
/* Height map for terrain */
|
||||||
|
|
||||||
|
#include "pack.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int resolution_x;
|
||||||
|
int resolution_z;
|
||||||
|
double* data;
|
||||||
|
} HeightMap;
|
||||||
|
|
||||||
|
HeightMap heightmapCreate();
|
||||||
|
void heightmapDelete(HeightMap* heightmap);
|
||||||
|
void heightmapCopy(HeightMap* source, HeightMap* destination);
|
||||||
|
void heightmapValidate(HeightMap* heightmap);
|
||||||
|
|
||||||
|
void heightmapSave(PackStream* stream, HeightMap* heightmap);
|
||||||
|
void heightmapLoad(PackStream* stream, HeightMap* heightmap);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,9 +13,7 @@ TerrainCanvas* terrainCanvasCreate()
|
||||||
result->area.size_x = 1.0;
|
result->area.size_x = 1.0;
|
||||||
result->area.size_z = 1.0;
|
result->area.size_z = 1.0;
|
||||||
result->offset_z = 0.0;
|
result->offset_z = 0.0;
|
||||||
result->height_map.data = malloc(sizeof(double));
|
result->height_map = heightmapCreate();
|
||||||
result->height_map.resolution_x = 1;
|
|
||||||
result->height_map.resolution_z = 1;
|
|
||||||
result->height_factor = 1.0;
|
result->height_factor = 1.0;
|
||||||
result->detail_noise = noiseCreateGenerator();
|
result->detail_noise = noiseCreateGenerator();
|
||||||
result->detail_height_factor = 0.1;
|
result->detail_height_factor = 0.1;
|
||||||
|
@ -28,7 +26,7 @@ TerrainCanvas* terrainCanvasCreate()
|
||||||
|
|
||||||
void terrainCanvasDelete(TerrainCanvas* canvas)
|
void terrainCanvasDelete(TerrainCanvas* canvas)
|
||||||
{
|
{
|
||||||
free(canvas->height_map.data);
|
heightmapDelete(&canvas->height_map);
|
||||||
noiseDeleteGenerator(canvas->detail_noise);
|
noiseDeleteGenerator(canvas->detail_noise);
|
||||||
free(canvas);
|
free(canvas);
|
||||||
}
|
}
|
||||||
|
@ -37,11 +35,8 @@ void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination)
|
||||||
{
|
{
|
||||||
destination->area = source->area;
|
destination->area = source->area;
|
||||||
destination->offset_z = source->offset_z;
|
destination->offset_z = source->offset_z;
|
||||||
destination->height_map.resolution_x = source->height_map.resolution_x;
|
|
||||||
destination->height_map.resolution_z = source->height_map.resolution_z;
|
|
||||||
destination->height_map.data = realloc(destination->height_map.data, sizeof(double) * destination->height_map.resolution_x * destination->height_map.resolution_z);
|
|
||||||
memcpy(destination->height_map.data, source->height_map.data, sizeof(double) * destination->height_map.resolution_x * destination->height_map.resolution_z);
|
|
||||||
destination->height_factor = source->height_factor;
|
destination->height_factor = source->height_factor;
|
||||||
|
heightmapCopy(&source->height_map, &destination->height_map);
|
||||||
noiseCopy(source->detail_noise, destination->detail_noise);
|
noiseCopy(source->detail_noise, destination->detail_noise);
|
||||||
destination->detail_height_factor = source->detail_height_factor;
|
destination->detail_height_factor = source->detail_height_factor;
|
||||||
destination->detail_scaling = source->detail_scaling;
|
destination->detail_scaling = source->detail_scaling;
|
||||||
|
@ -55,6 +50,7 @@ void terrainCanvasValidate(TerrainCanvas* canvas)
|
||||||
{
|
{
|
||||||
canvas->detail_scaling = 0.00001;
|
canvas->detail_scaling = 0.00001;
|
||||||
}
|
}
|
||||||
|
heightmapValidate(&canvas->height_map);
|
||||||
noiseValidate(canvas->detail_noise);
|
noiseValidate(canvas->detail_noise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,20 +70,13 @@ LayerType terrainCanvasGetLayerType()
|
||||||
|
|
||||||
void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas)
|
void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
packWriteInt(stream, &canvas->area.bounded);
|
packWriteInt(stream, &canvas->area.bounded);
|
||||||
packWriteDouble(stream, &canvas->area.location_x);
|
packWriteDouble(stream, &canvas->area.location_x);
|
||||||
packWriteDouble(stream, &canvas->area.location_z);
|
packWriteDouble(stream, &canvas->area.location_z);
|
||||||
packWriteDouble(stream, &canvas->area.size_x);
|
packWriteDouble(stream, &canvas->area.size_x);
|
||||||
packWriteDouble(stream, &canvas->area.size_z);
|
packWriteDouble(stream, &canvas->area.size_z);
|
||||||
packWriteDouble(stream, &canvas->offset_z);
|
packWriteDouble(stream, &canvas->offset_z);
|
||||||
packWriteInt(stream, &canvas->height_map.resolution_x);
|
heightmapSave(stream, &canvas->height_map);
|
||||||
packWriteInt(stream, &canvas->height_map.resolution_z);
|
|
||||||
for (i = 0; i < canvas->height_map.resolution_x * canvas->height_map.resolution_z; i++)
|
|
||||||
{
|
|
||||||
packWriteDouble(stream, &canvas->height_map.data[i]);
|
|
||||||
}
|
|
||||||
packWriteDouble(stream, &canvas->height_factor);
|
packWriteDouble(stream, &canvas->height_factor);
|
||||||
noiseSaveGenerator(stream, canvas->detail_noise);
|
noiseSaveGenerator(stream, canvas->detail_noise);
|
||||||
packWriteDouble(stream, &canvas->detail_height_factor);
|
packWriteDouble(stream, &canvas->detail_height_factor);
|
||||||
|
@ -98,21 +87,13 @@ void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas)
|
||||||
|
|
||||||
void terrainCanvasLoad(PackStream* stream, TerrainCanvas* canvas)
|
void terrainCanvasLoad(PackStream* stream, TerrainCanvas* canvas)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
packReadInt(stream, &canvas->area.bounded);
|
packReadInt(stream, &canvas->area.bounded);
|
||||||
packReadDouble(stream, &canvas->area.location_x);
|
packReadDouble(stream, &canvas->area.location_x);
|
||||||
packReadDouble(stream, &canvas->area.location_z);
|
packReadDouble(stream, &canvas->area.location_z);
|
||||||
packReadDouble(stream, &canvas->area.size_x);
|
packReadDouble(stream, &canvas->area.size_x);
|
||||||
packReadDouble(stream, &canvas->area.size_z);
|
packReadDouble(stream, &canvas->area.size_z);
|
||||||
packReadDouble(stream, &canvas->offset_z);
|
packReadDouble(stream, &canvas->offset_z);
|
||||||
packReadInt(stream, &canvas->height_map.resolution_x);
|
heightmapLoad(stream, &canvas->height_map);
|
||||||
packReadInt(stream, &canvas->height_map.resolution_z);
|
|
||||||
canvas->height_map.data = realloc(canvas->height_map.data, sizeof(double) * canvas->height_map.resolution_x * canvas->height_map.resolution_z);
|
|
||||||
for (i = 0; i < canvas->height_map.resolution_x * canvas->height_map.resolution_z; i++)
|
|
||||||
{
|
|
||||||
packReadDouble(stream, &canvas->height_map.data[i]);
|
|
||||||
}
|
|
||||||
packReadDouble(stream, &canvas->height_factor);
|
packReadDouble(stream, &canvas->height_factor);
|
||||||
noiseLoadGenerator(stream, canvas->detail_noise);
|
noiseLoadGenerator(stream, canvas->detail_noise);
|
||||||
packReadDouble(stream, &canvas->detail_height_factor);
|
packReadDouble(stream, &canvas->detail_height_factor);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "noise.h"
|
#include "noise.h"
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
#include "layers.h"
|
#include "layers.h"
|
||||||
|
#include "heightmap.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -21,13 +22,6 @@ typedef struct
|
||||||
double size_z;
|
double size_z;
|
||||||
} GeoArea;
|
} GeoArea;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int resolution_x;
|
|
||||||
int resolution_z;
|
|
||||||
double* data;
|
|
||||||
} HeightMap;
|
|
||||||
|
|
||||||
#define TERRAINCANVAS_MASKMODE_SQUARE 0
|
#define TERRAINCANVAS_MASKMODE_SQUARE 0
|
||||||
#define TERRAINCANVAS_MASKMODE_CIRCLE 1
|
#define TERRAINCANVAS_MASKMODE_CIRCLE 1
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue