2012-02-21 13:41:02 +00:00
|
|
|
#include "basepreview.h"
|
2011-12-25 21:19:32 +00:00
|
|
|
#include "formwater.h"
|
2012-01-29 17:39:56 +00:00
|
|
|
|
2011-12-26 21:53:29 +00:00
|
|
|
#include <QColor>
|
2012-01-05 16:32:41 +00:00
|
|
|
#include <QSlider>
|
2013-02-28 15:34:47 +00:00
|
|
|
#include <math.h>
|
2011-12-26 21:53:29 +00:00
|
|
|
|
2013-04-17 12:29:51 +00:00
|
|
|
#include "rendering/tools/euclid.h"
|
|
|
|
#include "rendering/tools/lighting.h"
|
|
|
|
#include "rendering/renderer.h"
|
|
|
|
#include "rendering/scenery.h"
|
|
|
|
#include "rendering/water/public.h"
|
2012-01-29 17:39:56 +00:00
|
|
|
#include "tools.h"
|
2011-12-26 21:53:29 +00:00
|
|
|
|
2013-02-27 16:38:27 +00:00
|
|
|
static WaterDefinition* _definition;
|
2011-12-27 19:03:46 +00:00
|
|
|
|
|
|
|
/**************** Previews ****************/
|
2013-04-27 19:41:57 +00:00
|
|
|
class PreviewWaterCoverage : public BasePreview
|
2011-12-26 21:53:29 +00:00
|
|
|
{
|
|
|
|
public:
|
2013-04-27 19:41:57 +00:00
|
|
|
|
|
|
|
PreviewWaterCoverage(QWidget* parent) : BasePreview(parent)
|
2011-12-26 21:53:29 +00:00
|
|
|
{
|
2013-02-27 16:38:27 +00:00
|
|
|
_renderer = waterCreatePreviewCoverageRenderer();
|
2012-12-28 11:28:01 +00:00
|
|
|
_highlight_enabled = true;
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-06-26 19:36:50 +00:00
|
|
|
addOsd(QString("geolocation"));
|
2012-12-28 11:28:01 +00:00
|
|
|
addToggle("highlight", tr("Coverage highlight"), true);
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2013-08-21 21:22:13 +00:00
|
|
|
configScaling(20.0, 1000.0, 20.0, 200.0);
|
2012-04-15 20:08:01 +00:00
|
|
|
configScrolling(-1000.0, 1000.0, 0.0, -1000.0, 1000.0, 0.0);
|
2011-12-26 21:53:29 +00:00
|
|
|
}
|
2012-12-28 11:28:01 +00:00
|
|
|
protected:
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2013-01-16 14:26:46 +00:00
|
|
|
Color getColor(double x, double y)
|
2011-12-26 21:53:29 +00:00
|
|
|
{
|
2013-02-27 16:38:27 +00:00
|
|
|
return waterGetPreviewCoverage(_renderer, x, y, scaling, _highlight_enabled ? 1 : 0);
|
2011-12-27 19:03:46 +00:00
|
|
|
}
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2012-01-26 22:30:20 +00:00
|
|
|
void updateData()
|
|
|
|
{
|
2013-02-27 16:38:27 +00:00
|
|
|
WaterRendererClass.bind(_renderer, _definition);
|
2012-12-28 11:28:01 +00:00
|
|
|
|
|
|
|
// TODO Do this only on full refresh
|
2013-04-27 19:41:57 +00:00
|
|
|
TerrainDefinition* terrain = (TerrainDefinition*) TerrainDefinitionClass.create();
|
2012-12-28 11:28:01 +00:00
|
|
|
sceneryGetTerrain(terrain);
|
2013-01-20 15:07:45 +00:00
|
|
|
TerrainRendererClass.bind(_renderer, terrain);
|
2012-12-28 11:28:01 +00:00
|
|
|
TerrainDefinitionClass.destroy(terrain);
|
|
|
|
}
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2012-12-28 11:28:01 +00:00
|
|
|
void toggleChangeEvent(QString key, bool value)
|
|
|
|
{
|
|
|
|
if (key == "highlight")
|
|
|
|
{
|
|
|
|
_highlight_enabled = value;
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
}
|
2012-01-24 13:16:20 +00:00
|
|
|
private:
|
2013-01-20 15:07:45 +00:00
|
|
|
Renderer* _renderer;
|
2012-12-28 11:28:01 +00:00
|
|
|
bool _highlight_enabled;
|
2011-12-27 19:03:46 +00:00
|
|
|
};
|
|
|
|
|
2013-04-27 19:41:57 +00:00
|
|
|
class PreviewWaterColor : public BasePreview
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
|
|
|
public:
|
2013-04-27 19:41:57 +00:00
|
|
|
|
|
|
|
PreviewWaterColor(QWidget* parent) : BasePreview(parent)
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
2012-07-04 17:50:32 +00:00
|
|
|
_background = 0;
|
|
|
|
_lighting_enabled = false;
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-01-29 21:45:58 +00:00
|
|
|
_renderer = rendererCreate();
|
2013-01-20 17:00:17 +00:00
|
|
|
_renderer->atmosphere->getLightingStatus = _getLightingStatus;
|
2013-01-20 15:07:45 +00:00
|
|
|
_renderer->rayWalking = _rayWalking;
|
2013-02-28 15:34:47 +00:00
|
|
|
_renderer->customData[0] = this;
|
2013-03-03 17:05:30 +00:00
|
|
|
//cameraSetTarget(&_renderer->render_camera, 0.0, 0.0, 0.0);
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2012-04-12 20:02:31 +00:00
|
|
|
configScaling(10.0, 1000.0, 10.0, 250.0);
|
2012-06-02 14:17:01 +00:00
|
|
|
//configScrolling(-30.0, 30.0, 0.0, -20.0, 20.0, 0.0);
|
2012-07-04 17:50:32 +00:00
|
|
|
|
|
|
|
addChoice("bg", tr("Background"), QStringList(tr("None")) << tr("Grid") << tr("Sinusoid"), 2);
|
2013-03-03 17:05:30 +00:00
|
|
|
addToggle("light", tr("Light reflection"), true);
|
2011-12-27 19:03:46 +00:00
|
|
|
}
|
2012-07-04 17:50:32 +00:00
|
|
|
int _background;
|
2013-01-20 17:00:17 +00:00
|
|
|
bool _lighting_enabled;
|
2011-12-27 19:03:46 +00:00
|
|
|
protected:
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2013-01-16 14:26:46 +00:00
|
|
|
Color getColor(double x, double y)
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
2013-02-28 15:34:47 +00:00
|
|
|
Vector3 eye, look;
|
|
|
|
double target_x, target_z;
|
2011-12-27 19:03:46 +00:00
|
|
|
|
|
|
|
eye.x = 0.0;
|
|
|
|
eye.y = scaling;
|
|
|
|
eye.z = -10.0 * scaling;
|
|
|
|
look.x = x * 0.01 / scaling;
|
|
|
|
look.y = -y * 0.01 / scaling - 0.3;
|
|
|
|
look.z = 1.0;
|
|
|
|
look = v3Normalize(look);
|
|
|
|
|
|
|
|
if (look.y > -0.0001)
|
|
|
|
{
|
2013-01-20 15:07:45 +00:00
|
|
|
return _rayWalking(_renderer, eye, look, 0, 0, 0, 0).hit_color;
|
2011-12-27 19:03:46 +00:00
|
|
|
}
|
|
|
|
|
2013-02-28 15:34:47 +00:00
|
|
|
target_x = eye.x - look.x * eye.y / look.y;
|
|
|
|
target_z = eye.z - look.z * eye.y / look.y;
|
2011-12-27 19:03:46 +00:00
|
|
|
|
2013-02-28 15:34:47 +00:00
|
|
|
if (target_z > 0.0)
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
2013-01-20 15:07:45 +00:00
|
|
|
return _rayWalking(_renderer, eye, look, 0, 0, 0, 0).hit_color;
|
2011-12-27 19:03:46 +00:00
|
|
|
}
|
|
|
|
|
2013-02-28 15:34:47 +00:00
|
|
|
return _renderer->water->getResult(_renderer, target_x, target_z).final;
|
2012-01-26 22:30:20 +00:00
|
|
|
}
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2013-03-03 17:05:30 +00:00
|
|
|
void cameraEvent()
|
|
|
|
{
|
2013-04-27 19:41:57 +00:00
|
|
|
Vector3 camera_location = {0.0, scaling, -10.0 * scaling};
|
|
|
|
cameraSetLocation(_renderer->render_camera, camera_location);
|
2013-03-03 17:05:30 +00:00
|
|
|
}
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2013-05-11 21:34:30 +00:00
|
|
|
static double _getWaterHeight(Renderer* renderer)
|
|
|
|
{
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
2012-01-26 22:30:20 +00:00
|
|
|
void updateData()
|
|
|
|
{
|
2013-02-28 15:34:47 +00:00
|
|
|
WaterRendererClass.bind(_renderer, _definition);
|
2013-05-11 21:34:30 +00:00
|
|
|
_renderer->terrain->getWaterHeight = _getWaterHeight;
|
2011-12-27 19:03:46 +00:00
|
|
|
}
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2012-07-04 17:50:32 +00:00
|
|
|
void choiceChangeEvent(const QString& key, int position)
|
|
|
|
{
|
|
|
|
if (key == "bg")
|
|
|
|
{
|
|
|
|
_background = position;
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
}
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2012-07-04 17:50:32 +00:00
|
|
|
void toggleChangeEvent(QString key, bool value)
|
|
|
|
{
|
|
|
|
if (key == "light")
|
|
|
|
{
|
|
|
|
_lighting_enabled = value;
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
}
|
2011-12-27 19:03:46 +00:00
|
|
|
|
|
|
|
private:
|
2013-01-20 15:07:45 +00:00
|
|
|
Renderer* _renderer;
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2013-01-16 14:26:46 +00:00
|
|
|
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int, int, int, int)
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
|
|
|
RayCastingResult result;
|
2013-04-27 19:41:57 +00:00
|
|
|
PreviewWaterColor* preview = (PreviewWaterColor*) renderer->customData[0];
|
2012-06-17 09:40:40 +00:00
|
|
|
double x, y;
|
2011-12-27 19:03:46 +00:00
|
|
|
|
|
|
|
result.hit = 1;
|
|
|
|
if (direction.z < 0.0001)
|
|
|
|
{
|
|
|
|
result.hit_color = COLOR_WHITE;
|
2012-01-24 13:16:20 +00:00
|
|
|
result.hit_location = location;
|
2011-12-27 19:03:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-24 13:16:20 +00:00
|
|
|
x = location.x + direction.x * (0.0 - location.z) / direction.z;
|
|
|
|
y = location.y + direction.y * (0.0 - location.z) / direction.z;
|
2011-12-27 19:03:46 +00:00
|
|
|
|
2012-07-04 17:50:32 +00:00
|
|
|
switch (preview->_background)
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
2012-07-04 17:50:32 +00:00
|
|
|
case 1:
|
2013-04-27 19:41:57 +00:00
|
|
|
result.hit_color = (((int) ceil(x * 0.2) % 2 == 0) ^ ((int) ceil(y * 0.2 - 0.5) % 2 == 0)) ? COLOR_WHITE : COLOR_BLACK;
|
2012-07-04 17:50:32 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
result.hit_color = (y * 0.1 > x * 0.03 + sin(x - M_PI_2)) ? COLOR_WHITE : COLOR_BLACK;
|
|
|
|
break;
|
|
|
|
default:
|
2011-12-27 19:03:46 +00:00
|
|
|
result.hit_color = COLOR_WHITE;
|
|
|
|
}
|
2012-01-22 18:39:42 +00:00
|
|
|
result.hit_location.x = x;
|
|
|
|
result.hit_location.y = y;
|
|
|
|
result.hit_location.z = 0.0;
|
2013-03-11 13:32:05 +00:00
|
|
|
|
|
|
|
if (result.hit_location.y < 0.0)
|
|
|
|
{
|
|
|
|
if (result.hit_location.y < -renderer->water->definition->lighting_depth)
|
|
|
|
{
|
|
|
|
result.hit_color = COLOR_BLACK;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double attenuation = -result.hit_location.y / renderer->water->definition->lighting_depth;
|
|
|
|
result.hit_color.r *= 1.0 - attenuation;
|
|
|
|
result.hit_color.g *= 1.0 - attenuation;
|
|
|
|
result.hit_color.b *= 1.0 - attenuation;
|
|
|
|
}
|
|
|
|
}
|
2011-12-26 21:53:29 +00:00
|
|
|
}
|
2011-12-27 19:03:46 +00:00
|
|
|
|
|
|
|
return result;
|
2011-12-26 21:53:29 +00:00
|
|
|
}
|
2013-04-27 19:41:57 +00:00
|
|
|
|
2013-01-20 17:00:17 +00:00
|
|
|
static void _getLightingStatus(Renderer* renderer, LightStatus* status, Vector3, int)
|
2012-07-04 17:50:32 +00:00
|
|
|
{
|
2013-01-20 17:00:17 +00:00
|
|
|
LightDefinition light;
|
2013-04-27 19:41:57 +00:00
|
|
|
PreviewWaterColor* preview = (PreviewWaterColor*) renderer->customData[0];
|
2013-01-20 17:00:17 +00:00
|
|
|
light.color = COLOR_WHITE;
|
|
|
|
light.direction.x = 0.0;
|
|
|
|
light.direction.y = -0.4794;
|
2013-03-03 17:05:30 +00:00
|
|
|
light.direction.z = -0.8776;
|
2013-01-20 17:00:17 +00:00
|
|
|
light.altered = 0;
|
|
|
|
if (preview->_lighting_enabled)
|
2012-07-04 17:50:32 +00:00
|
|
|
{
|
2013-01-20 17:00:17 +00:00
|
|
|
light.reflection = 1.0;
|
2012-07-04 17:50:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-01-20 17:00:17 +00:00
|
|
|
light.reflection = 0.0;
|
2012-07-04 17:50:32 +00:00
|
|
|
}
|
2013-01-20 17:00:17 +00:00
|
|
|
lightingPushLight(status, &light);
|
2012-07-04 17:50:32 +00:00
|
|
|
}
|
2011-12-26 21:53:29 +00:00
|
|
|
};
|
2011-12-25 21:19:32 +00:00
|
|
|
|
2011-12-27 19:03:46 +00:00
|
|
|
/**************** Form ****************/
|
2013-04-27 19:41:57 +00:00
|
|
|
FormWater::FormWater(QWidget *parent) :
|
|
|
|
BaseForm(parent)
|
2011-12-25 21:19:32 +00:00
|
|
|
{
|
2012-11-24 12:30:51 +00:00
|
|
|
addAutoPreset(tr("Lake surface"));
|
|
|
|
addAutoPreset(tr("Standard sea"));
|
2012-12-09 17:49:28 +00:00
|
|
|
|
2013-04-27 19:41:57 +00:00
|
|
|
_definition = (WaterDefinition*) WaterDefinitionClass.create();
|
2011-12-27 19:03:46 +00:00
|
|
|
|
2012-01-22 18:39:42 +00:00
|
|
|
previewCoverage = new PreviewWaterCoverage(this);
|
|
|
|
previewColor = new PreviewWaterColor(this);
|
2012-11-19 20:40:57 +00:00
|
|
|
addPreview(previewCoverage, tr("Coverage preview"));
|
|
|
|
addPreview(previewColor, tr("Rendered preview"));
|
2012-02-28 13:45:11 +00:00
|
|
|
|
2013-05-11 21:34:30 +00:00
|
|
|
//addInputDouble(tr("Height"), &_definition->height, -15.0, 15.0, 0.1, 1.0);
|
2013-02-28 15:34:47 +00:00
|
|
|
addInputMaterial(tr("Surface material"), &_definition->material);
|
|
|
|
addInputColor(tr("Depth color"), &_definition->depth_color);
|
|
|
|
addInputDouble(tr("Transparency"), &_definition->transparency, 0.0, 1.0, 0.001, 0.1);
|
|
|
|
addInputDouble(tr("Reflection"), &_definition->reflection, 0.0, 1.0, 0.001, 0.1);
|
|
|
|
addInputDouble(tr("Transparency distance"), &_definition->transparency_depth, 0.0, 20.0, 0.1, 1.0);
|
|
|
|
addInputDouble(tr("Light-through distance"), &_definition->lighting_depth, 0.0, 20.0, 0.1, 1.0);
|
|
|
|
addInputDouble(tr("Waves scaling"), &_definition->scaling, 0.02, 2.0, 0.02, 0.2);
|
|
|
|
addInputDouble(tr("Waves height"), &_definition->waves_height, 0.0, 2.0, 0.02, 0.2);
|
|
|
|
addInputDouble(tr("Waves detail"), &_definition->detail_height, 0.0, 0.3, 0.003, 0.03);
|
|
|
|
addInputDouble(tr("Waves turbulence"), &_definition->turbulence, 0.0, 0.5, 0.005, 0.05);
|
|
|
|
addInputDouble(tr("Foam coverage"), &_definition->foam_coverage, 0.0, 1.0, 0.01, 0.1);
|
|
|
|
addInputMaterial(tr("Foam material"), &_definition->foam_material);
|
2011-12-27 19:03:46 +00:00
|
|
|
|
|
|
|
revertConfig();
|
|
|
|
}
|
|
|
|
|
2012-01-05 18:39:17 +00:00
|
|
|
void FormWater::revertConfig()
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
2013-02-28 15:34:47 +00:00
|
|
|
sceneryGetWater(_definition);
|
2012-01-05 18:39:17 +00:00
|
|
|
BaseForm::revertConfig();
|
2011-12-27 19:03:46 +00:00
|
|
|
}
|
|
|
|
|
2012-01-07 16:53:23 +00:00
|
|
|
void FormWater::applyConfig()
|
2011-12-27 19:03:46 +00:00
|
|
|
{
|
2013-02-28 15:34:47 +00:00
|
|
|
scenerySetWater(_definition);
|
2012-01-07 16:53:23 +00:00
|
|
|
BaseForm::applyConfig();
|
|
|
|
}
|
2012-11-11 10:52:03 +00:00
|
|
|
|
|
|
|
void FormWater::configChangeEvent()
|
|
|
|
{
|
2013-02-28 15:34:47 +00:00
|
|
|
WaterDefinitionClass.validate(_definition);
|
2012-11-11 10:52:03 +00:00
|
|
|
BaseForm::configChangeEvent();
|
|
|
|
}
|
2012-11-19 20:40:57 +00:00
|
|
|
|
|
|
|
void FormWater::autoPresetSelected(int preset)
|
|
|
|
{
|
2013-04-27 19:41:57 +00:00
|
|
|
waterAutoPreset(_definition, (WaterPreset) preset);
|
2012-11-19 20:40:57 +00:00
|
|
|
BaseForm::autoPresetSelected(preset);
|
|
|
|
}
|
|
|
|
|