1
0
forked from 0ad/0ad

Substantial speed-up of the foam generation code.

Remove waves for now as they were unsatisfactory.
Removes "shininess" as a water parameter as it was basically useless.
Add a button in Atlas to recompute water parameters so you can now see
fog in Atlas.

Fixes #1743, #1803 (invalid)
Refs #1875, #2114, #48.

This was SVN commit r14514.
This commit is contained in:
wraitii 2014-01-05 16:15:20 +00:00
parent d56595c802
commit 15ec863aec
17 changed files with 145 additions and 96 deletions

View File

@ -56,12 +56,6 @@ function setWaterHeight(h)
WATER_LEVEL_CHANGED = true;
}
// Set water shininess
function setWaterShininess(s)
{
g_Environment.Water.WaterBody.Shininess = s;
}
// Set water waviness
function setWaterWaviness(w)
{

View File

@ -15,7 +15,6 @@ var g_Environment = {
Type: "default",
Colour: {r: 0.3, g: 0.35, b: 0.7, a: 0},
Height: 5,
Shininess: 150,
Waviness: 8,
Murkiness: 0.45,
Tint: {r: 0.28, g: 0.3, b: 0.59, a: 0},

View File

@ -34,8 +34,6 @@ uniform vec3 sunColor;
uniform vec3 sunDir;
uniform vec3 cameraPos;
uniform float shininess;
uniform float specularStrength;
uniform float waviness;
uniform vec3 waterTint;
@ -124,7 +122,7 @@ void main()
refrColor = (0.5 + 0.5*ndotl) * mix(vec3(0.3), sunColor * waterTint,
murkiness * clamp(waterDepth / fullDepth, 0.0, 1.0)); // Murkiness and tint at this pixel (tweaked based on lighting and depth)
specular = pow(max(0.0, ndoth), shininess) * sunColor * specularStrength;
specular = pow(max(0.0, ndoth), 150.0f) * sunColor * specularStrength;
losMod = texture2D(losTex, v_los).a;

View File

@ -5,7 +5,6 @@ uniform vec3 sunDir;
uniform vec3 sunColor;
uniform vec3 cameraPos;
uniform sampler2D losMap;
uniform float shininess; // Blinn-Phong specular strength
uniform float specularStrength; // Scaling for specular reflection (specular color is (this,this,this))
uniform float waviness; // "Wildness" of the reflections and refractions; choose based on texture
uniform vec3 tint; // Tint for refraction (used to simulate particles in water)
@ -102,8 +101,7 @@ void main()
vec2 beachOrientation = heightmapval.rg;
float distToShore = heightmapval.b;
#endif
vec3 n, l, h, v; // Normal, light vector, half-vector and view vector (vector to eye)
float ndotl, ndoth, ndotv;
float fresnel;
@ -185,7 +183,7 @@ void main()
// texture is not rotated, moves twice faster in the opposite direction, translated.
vec2 foam2RC = gl_TexCoord[0].st*1.8 + vec2(time*-0.019,time*-0.012) - 0.012*n.xz + vec2(0.4,0.2);
vec2 WaveRocking = cos(time*1.2566) * beachOrientation * clamp(1.0 - distToShore,0.1,1.0)/3.0;
vec2 WaveRocking = cos(time*1.2566) * beachOrientation * clamp(1.0 - distToShore*0.8,0.1,1.0)/3.0;
vec4 foam1 = texture2D(Foam, foam1RC + vec2(-WaveRocking.t,WaveRocking.s));
vec4 foam2 = foam1.r*texture2D(Foam, foam2RC + WaveRocking);

View File

@ -583,7 +583,7 @@ void CXMLReader::ReadEnvironment(XMBElement parent)
EL(type);
EL(colour);
EL(height);
EL(shininess);
EL(shininess); // for compatibility
EL(waviness);
EL(murkiness);
EL(tint);
@ -718,6 +718,8 @@ void CXMLReader::ReadEnvironment(XMBElement parent)
if (!m_MapReader.pWaterMan)
continue;
float this_avoids_a_warning_about_unused_variables = 0;
if (element_name == el_type)
{
// TODO: implement this, when WaterManager supports it
@ -740,7 +742,7 @@ void CXMLReader::ReadEnvironment(XMBElement parent)
} \
READ_COLOUR(el_colour, m_MapReader.pWaterMan->m_WaterColor)
READ_FLOAT(el_shininess, m_MapReader.pWaterMan->m_Shininess)
READ_FLOAT(el_shininess, this_avoids_a_warning_about_unused_variables)
READ_FLOAT(el_waviness, m_MapReader.pWaterMan->m_Waviness)
READ_FLOAT(el_murkiness, m_MapReader.pWaterMan->m_Murkiness)
READ_COLOUR(el_tint, m_MapReader.pWaterMan->m_WaterTint)
@ -1461,7 +1463,6 @@ int CMapReader::ParseEnvironment()
// TODO: Water type not implemented
GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Colour, pWaterMan->m_WaterColor)
GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Shininess, pWaterMan->m_Shininess)
GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Waviness, pWaterMan->m_Waviness)
GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Murkiness, pWaterMan->m_Murkiness)
GET_ENVIRONMENT_PROPERTY(waterBodyObj.get(), Tint, pWaterMan->m_WaterTint)

View File

@ -256,7 +256,6 @@ void CMapWriter::WriteXML(const VfsPath& filename,
CmpPtr<ICmpWaterManager> cmpWaterManager(*pSimulation2, SYSTEM_ENTITY);
ENSURE(cmpWaterManager);
XML_Setting("Height", cmpWaterManager->GetExactWaterLevel(0, 0));
XML_Setting("Shininess", pWaterMan->m_Shininess);
XML_Setting("Waviness", pWaterMan->m_Waviness);
XML_Setting("Murkiness", pWaterMan->m_Murkiness);
{

View File

@ -126,7 +126,6 @@ X(shadingColor)
X(shadowScale)
X(shadowTex)
X(shadowTransform)
X(shininess)
X(skinBlendMatrices)
X2(skinBlendMatrices_0, "skinBlendMatrices[0]")
X(skyCube)

View File

@ -658,7 +658,7 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, ShadowMap*
defines.Add(str_USE_NORMALS, str_1);
if (WaterMgr->m_WaterRealDepth)
defines.Add(str_USE_REAL_DEPTH, str_1);
if (WaterMgr->m_WaterFoam && !g_AtlasGameLoop->running)
if (WaterMgr->m_WaterFoam)
defines.Add(str_USE_FOAM, str_1);
if (WaterMgr->m_WaterCoastalWaves && !g_AtlasGameLoop->running)
defines.Add(str_USE_WAVES, str_1);
@ -747,7 +747,8 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, ShadowMap*
GLuint FramebufferName = 0;
// rendering waves to a framebuffer
if (WaterMgr->m_WaterCoastalWaves && WaterMgr->m_VBWaves && !g_AtlasGameLoop->running)
// TODO: reactivate this with something that looks good.
if (false && WaterMgr->m_WaterCoastalWaves && WaterMgr->m_VBWaves && !g_AtlasGameLoop->running)
{
// Save the post-processing framebuffer.
GLint fbo;
@ -840,7 +841,6 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, ShadowMap*
m->fancyWaterShader->Uniform(str_sunDir, lightEnv.GetSunDir());
m->fancyWaterShader->Uniform(str_sunColor, lightEnv.m_SunColor.X);
m->fancyWaterShader->Uniform(str_color, WaterMgr->m_WaterColor);
m->fancyWaterShader->Uniform(str_shininess, WaterMgr->m_Shininess);
m->fancyWaterShader->Uniform(str_specularStrength, WaterMgr->m_SpecularStrength);
m->fancyWaterShader->Uniform(str_waviness, WaterMgr->m_Waviness);
m->fancyWaterShader->Uniform(str_murkiness, WaterMgr->m_Murkiness);

View File

@ -70,7 +70,6 @@ WaterManager::WaterManager()
m_ReflectionTextureSize = 0;
m_RefractionTextureSize = 0;
m_WaterTexTimer = 0.0;
m_Shininess = 150.0f;
m_SpecularStrength = 0.6f;
m_Waviness = 8.0f;
m_ReflectionTint = CColor(0.28f, 0.3f, 0.59f, 1.0f);
@ -268,11 +267,18 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
m_WaterHeight = cmpWaterManager->GetExactWaterLevel(0,0);
// Get the square we want to work on.
i32 Xstart = clamp(m_updatei0, 0, (i32)m_MapSize-1);
i32 Xend = clamp(m_updatei1, 0, (i32)m_MapSize-1);
i32 Zstart = clamp(m_updatej0, 0, (i32)m_MapSize-1);
i32 Zend = clamp(m_updatej1, 0, (i32)m_MapSize-1);
ssize_t Xstart = m_updatei0 < 0 ? 0 : (m_updatei0 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : m_updatei0);
ssize_t Xend = m_updatei1 < 0 ? 0 : (m_updatei1 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : m_updatei1);
ssize_t Zstart = m_updatej0 < 0 ? 0 : (m_updatej0 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : m_updatej0);
ssize_t Zend = m_updatej1 < 0 ? 0 : (m_updatej1 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : m_updatej1);
if (!(Xend > Xstart && Zend > Zstart))
{
// it corrupts every now and then for reasons I don't get.
std::cout << m_updatei0 << " , " << Xstart << std::endl;
std::cout << m_MapSize << "," << (ssize_t)m_MapSize << std::endl;
}
if (m_WaveX == NULL)
{
m_WaveX = new float[m_MapSize*m_MapSize];
@ -291,13 +297,13 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
// this might be updated to actually cache in the terrain manager but that's not for now.
CVector3D* normals = new CVector3D[m_MapSize*m_MapSize];
// taken out of the bottom loop, blurs the normal map
// To remove if below is reactivated
ssize_t blurZstart = Zstart-4 < 0 ? 0 : Zstart - 4;
ssize_t blurZend = Zend+4 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : Zend + 4;
ssize_t blurXstart = Xstart-4 < 0 ? 0 : Xstart - 4;
ssize_t blurXend = Xend+4 >= (ssize_t)m_MapSize ? (ssize_t)m_MapSize-1 : Xend + 4;
for (ssize_t j = blurZstart; j < blurZend; ++j)
{
for (ssize_t i = blurXstart; i < blurXend; ++i)
@ -339,113 +345,107 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
{
for (ssize_t i = Xstart; i < Xend; ++i)
{
ssize_t index = j*m_MapSize + i;
if (circular && (i-halfSize)*(i-halfSize)+(j-halfSize)*(j-halfSize) > mSize)
{
m_WaveX[j*m_MapSize + i] = 0.0f;
m_WaveZ[j*m_MapSize + i] = 0.0f;
m_DistanceToShore[j*m_MapSize + i] = 100;
m_FoamFactor[j*m_MapSize + i] = 0.0f;
m_WaveX[index] = 0.0f;
m_WaveZ[index] = 0.0f;
m_DistanceToShore[index] = 100;
m_FoamFactor[index] = 0.0f;
continue;
}
float depth = m_WaterHeight - heightmap[j*m_MapSize + i]*HEIGHT_SCALE;
int distanceToShore = 10000;
float depth = m_WaterHeight - heightmap[index]*HEIGHT_SCALE;
float distanceToShore = 10000;
// calculation of the distance to the shore.
// TODO: this is fairly dumb, though it returns a good result
// Could be sped up a fair bit.
if (depth >= 0)
if (i > 0 && i < (ssize_t)m_MapSize-1 && j > 0 && j < (ssize_t)m_MapSize-1)
{
// check in the square around.
for (int yy = -5; yy <= 5; ++yy)
// search a 5x5 array with us in the center (do not search me)
// much faster since we spiral search and can just stop once we've found the shore.
// also everything is precomputed and we get exact results instead.
int offset[24] = { -1,1,-m_MapSize,+m_MapSize, -1-m_MapSize,+1-m_MapSize,-1+m_MapSize,1+m_MapSize,
-2,2,-2*m_MapSize,2*m_MapSize,-2-m_MapSize,-2+m_MapSize,2-m_MapSize,2+m_MapSize,
-1-2*m_MapSize,+1-2*m_MapSize,-1+2*m_MapSize,1+2*m_MapSize,
-2-2*m_MapSize,2+2*m_MapSize,-2+2*m_MapSize,2-2*m_MapSize };
float dist[24] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.414f, 1.414f, 1.414f, 1.414f,
2.0f, 2.0f, 2.0f, 2.0f, 2.236f, 2.236f, 2.236f, 2.236f,
2.236f, 2.236f, 2.236f, 2.236f,
2.828f, 2.828f, 2.828f, 2.828f };
int max = 8;
if (i > 1 && i < (ssize_t)m_MapSize-2 && j > 1 && j < (ssize_t)m_MapSize-2)
max = 24;
for(int lookupI = 0; lookupI < max;++lookupI)
{
for (int xx = -5; xx <= 5; ++xx)
{
if (i+xx >= 0 && i + xx < (long)m_MapSize)
if (j + yy >= 0 && j + yy < (long)m_MapSize)
{
float hereDepth = m_WaterHeight - heightmap[(j+yy)*m_MapSize + (i+xx)]*HEIGHT_SCALE;
if (hereDepth < 0 && xx*xx + yy*yy < distanceToShore)
distanceToShore = xx*xx + yy*yy;
}
}
float hereDepth = m_WaterHeight - heightmap[index+offset[lookupI]]*HEIGHT_SCALE;
distanceToShore = hereDepth <= 0 && depth >= 0 ? dist[lookupI] : (depth < 0 ? 1 : distanceToShore);
if (distanceToShore != 10000)
break;
}
// refine the calculation if we're close enough
if (distanceToShore < 9)
{
for (float yy = -2.5f; yy <= 2.5f; ++yy)
} else {
// revert to for and if-based because I can't be bothered to special case all that.
for (int xx = -1; xx <= 1;++xx)
for (int yy = -1; yy <= 1;++yy)
{
for (float xx = -2.5f; xx <= 2.5f; ++xx)
if (i+xx >= 0 && i+xx < (ssize_t)m_MapSize && j+yy >= 0 && j+yy < (ssize_t)m_MapSize)
{
float hereDepth = m_WaterHeight - terrain->GetExactGroundLevel( (i+xx)*4, (j+yy)*4 );
if (hereDepth < 0 && xx*xx + yy*yy < distanceToShore)
distanceToShore = xx*xx + yy*yy;
float hereDepth = m_WaterHeight - heightmap[index+xx+yy*m_MapSize]*HEIGHT_SCALE;
distanceToShore = (hereDepth < 0 && sqrt((double)xx*xx+yy*yy) < distanceToShore) ? sqrt((double)xx*xx+yy*yy) : distanceToShore;
}
}
}
}
else
{
for (int yy = -2; yy <= 2; ++yy)
{
for (int xx = -2; xx <= 2; ++xx)
{
float hereDepth = m_WaterHeight - terrain->GetVertexGroundLevel(i+xx, j+yy);
if (hereDepth > 0)
distanceToShore = 0;
}
}
}
// speedup with default values for land squares
if (distanceToShore == 10000)
{
m_WaveX[j*m_MapSize + i] = 0.0f;
m_WaveZ[j*m_MapSize + i] = 0.0f;
m_DistanceToShore[j*m_MapSize + i] = 100;
m_FoamFactor[j*m_MapSize + i] = 0.0f;
m_WaveX[index] = 0.0f;
m_WaveZ[index] = 0.0f;
m_DistanceToShore[index] = 100.0f;
m_FoamFactor[index] = 0.0f;
continue;
}
// We'll compute the normals and the "water raise", to know about foam
// Normals are a pretty good calculation but it's slow since we normalize so much.
CVector3D normal;
int waterRaise = 0;
for (int yy = -4; yy <= 4; yy += 2)
for (int yy = -3; yy <= 3; yy += 2)
{
for (int xx = -4; xx <= 4; xx += 2) // every 2 tile is good enough.
for (int xx = -3; xx <= 3; xx += 2) // every 2 tile is good enough.
{
if (j+yy < (long)m_MapSize && i+xx < (long)m_MapSize && i+xx >= 0 && j+yy >= 0)
normal += normals[(j+yy)*m_MapSize + (i+xx)];
if (terrain->GetVertexGroundLevel(i+xx,j+yy) < heightmap[j*m_MapSize + i]*HEIGHT_SCALE)
waterRaise += heightmap[j*m_MapSize + i]*HEIGHT_SCALE - terrain->GetVertexGroundLevel(i+xx,j+yy);
waterRaise += heightmap[index]*HEIGHT_SCALE - terrain->GetVertexGroundLevel(i+xx,j+yy) > 0 ? heightmap[index]*HEIGHT_SCALE - terrain->GetVertexGroundLevel(i+xx,j+yy) : 0.0f;
}
}
// normalizes the terrain info to avoid foam moving at too different speeds.
normal *= 0.012345679f;
normal *= 0.08f;
normal[1] = 0.1f;
normal = normal.Normalized();
m_WaveX[j*m_MapSize + i] = normal[0];
m_WaveZ[j*m_MapSize + i] = normal[2];
m_WaveX[index] = normal[0];
m_WaveZ[index] = normal[2];
// distance is /5.0 to be a [0,1] value.
m_DistanceToShore[j*m_MapSize + i] = sqrtf(distanceToShore)/5.0f; // TODO: this can probably be cached as I'm integer here.
m_DistanceToShore[index] = distanceToShore;
// computing the amount of foam I want
depth = clamp(depth,0.0f,10.0f);
float foamAmount = (waterRaise/255.0f) * (1.0f - depth/10.0f) /** (waveForceHQ[j*m_MapSize+i]/255.0f)*/ * (m_Waviness/8.0f);
foamAmount += clamp(m_Waviness/2.0f - distanceToShore,0.0f,m_Waviness/2.0f)/(m_Waviness/2.0f) * clamp(m_Waviness/9.0f,0.3f,1.0f);
foamAmount = foamAmount > 1.0f ? 1.0f: foamAmount;
foamAmount += clamp(m_Waviness/2.0f,0.0f,m_Waviness/2.0f)/(m_Waviness/2.0f) * clamp(m_Waviness/9.0f,0.3f,1.0f);
foamAmount *= (m_Waviness/4.0f - distanceToShore);
foamAmount = foamAmount > 1.0f ? 1.0f: (foamAmount < 0.0f ? 0.0f : foamAmount);
m_FoamFactor[j*m_MapSize + i] = foamAmount;
m_FoamFactor[index] = foamAmount;
}
}
delete[] normals;
//delete[] waveForceHQ;
// TODO: The rest should be cleaned up
// TODO: reactivate this with something that looks good and is efficient.
/*
// okay let's create the waves squares. i'll divide the map in arbitrary squares
// For each of these squares, check if waves are needed.
// If yes, look for the best positionning (in order to have a nice blending with the shore)
@ -604,6 +604,7 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
// Construct indices buffer
m_VBWavesIndices = g_VBMan.Allocate(sizeof(GLushort), waves_indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
m_VBWavesIndices->m_Owner->UpdateChunkVertices(m_VBWavesIndices, &waves_indices[0]);
*/
}
////////////////////////////////////////////////////////////////////////

View File

@ -115,7 +115,6 @@ public:
// Shader parameters for fancy water
CColor m_WaterTint;
float m_RepeatPeriod;
float m_Shininess;
float m_SpecularStrength;
float m_Waviness;
float m_Murkiness;

View File

@ -26,6 +26,8 @@
#include "renderer/WaterManager.h"
#include "simulation2/MessageTypes.h"
#include "tools/atlas/GameInterface/GameLoop.h"
class CCmpWaterManager : public ICmpWaterManager
{
public:
@ -81,7 +83,9 @@ public:
case MT_TerrainChanged:
{
// Tell the renderer to redraw the map.
if (CRenderer::IsInitialised())
// TODO: sometimes atlas glitches out.
// I've added a button to recompute on demand but that's not extremely nice.
if (CRenderer::IsInitialised() && !g_AtlasGameLoop->running)
{
const CMessageTerrainChanged& msgData = static_cast<const CMessageTerrainChanged&> (msg);
g_Renderer.GetWaterManager()->m_NeedInfoUpdate = true;
@ -97,6 +101,19 @@ public:
}
}
virtual void RecomputeWaterData()
{
ssize_t mapSize = GetSimContext().GetTerrain().GetVerticesPerSide();
g_Renderer.GetWaterManager()->m_NeedInfoUpdate = true;
g_Renderer.GetWaterManager()->m_updatei0 = 0;
g_Renderer.GetWaterManager()->m_updatej0 = 0;
g_Renderer.GetWaterManager()->m_updatei1 = mapSize-1;
g_Renderer.GetWaterManager()->m_updatej1 = mapSize-1;
// Tell the terrain it'll need to recompute its cached render data
GetSimContext().GetTerrain().MakeDirty(RENDERDATA_UPDATE_VERTICES);
}
virtual void SetWaterLevel(entity_pos_t h)
{
m_WaterHeight = h;

View File

@ -22,6 +22,7 @@
#include "simulation2/system/InterfaceScripted.h"
BEGIN_INTERFACE_WRAPPER(WaterManager)
DEFINE_INTERFACE_METHOD_0("RecomputeWaterData", void, ICmpWaterManager, RecomputeWaterData)
DEFINE_INTERFACE_METHOD_1("SetWaterLevel", void, ICmpWaterManager, SetWaterLevel, entity_pos_t)
DEFINE_INTERFACE_METHOD_2("GetWaterLevel", entity_pos_t, ICmpWaterManager, GetWaterLevel, entity_pos_t, entity_pos_t)
END_INTERFACE_WRAPPER(WaterManager)

View File

@ -25,6 +25,11 @@
class ICmpWaterManager : public IComponent
{
public:
/**
* Recompute all the water information (foam)
*/
virtual void RecomputeWaterData() = 0;
/**
* Set the height of the water level, as a constant value across the whole map.
*/

View File

@ -197,6 +197,9 @@ END_EVENT_TABLE()
//////////////////////////////////////////////////////////////////////////
enum {
ID_RecomputeWaterData
};
static void SendToGame(const AtlasMessage::sEnvironmentSettings& settings)
{
POST_COMMAND(SetEnvironmentSettings, (settings));
@ -213,9 +216,8 @@ EnvironmentSidebar::EnvironmentSidebar(ScenarioEditor& scenarioEditor, wxWindow*
wxSizer* waterSizer = new wxStaticBoxSizer(wxVERTICAL, scrolledWindow, _T("Water settings"));
scrollSizer->Add(waterSizer, wxSizerFlags().Expand());
waterSizer->Add(new wxButton(this, ID_RecomputeWaterData, _("Reset Water Data")), wxSizerFlags().Expand());
waterSizer->Add(new VariableSliderBox(scrolledWindow, _("Water height"), g_EnvironmentSettings.waterheight, 0.f, 1.2f), wxSizerFlags().Expand());
waterSizer->Add(new VariableSliderBox(scrolledWindow, _("Water shininess"), g_EnvironmentSettings.watershininess, 0.f, 250.f), wxSizerFlags().Expand());
waterSizer->Add(new VariableSliderBox(scrolledWindow, _("Water waviness"), g_EnvironmentSettings.waterwaviness, 0.f, 10.f), wxSizerFlags().Expand());
waterSizer->Add(new VariableSliderBox(scrolledWindow, _("Water murkiness"), g_EnvironmentSettings.watermurkiness, 0.f, 1.f), wxSizerFlags().Expand());
waterSizer->Add(new VariableColourBox(scrolledWindow, _("Water colour"), g_EnvironmentSettings.watercolour), wxSizerFlags().Expand());
@ -277,3 +279,13 @@ void EnvironmentSidebar::OnMapReload()
g_EnvironmentSettings.NotifyObservers();
}
void EnvironmentSidebar::RecomputeWaterData(wxCommandEvent& evt)
{
POST_COMMAND(RecalculateWaterData, (0.0f));
}
BEGIN_EVENT_TABLE(EnvironmentSidebar, Sidebar)
EVT_BUTTON(ID_RecomputeWaterData, EnvironmentSidebar::RecomputeWaterData)
END_EVENT_TABLE();

View File

@ -27,6 +27,7 @@ public:
EnvironmentSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer);
virtual void OnMapReload();
virtual void RecomputeWaterData(wxCommandEvent& evt);
protected:
virtual void OnFirstDisplay();
@ -35,4 +36,6 @@ private:
VariableListBox* m_PostEffectList;
VariableListBox* m_SkyList;
ObservableScopedConnection m_Conn;
DECLARE_EVENT_TABLE();
};

View File

@ -44,7 +44,6 @@ sEnvironmentSettings GetSettings()
s.waterheight = cmpWaterManager->GetExactWaterLevel(0, 0) / (65536.f * HEIGHT_SCALE);
WaterManager* wm = g_Renderer.GetWaterManager();
s.watershininess = wm->m_Shininess;
s.waterwaviness = wm->m_Waviness;
s.watermurkiness = wm->m_Murkiness;
s.waterreflectiontintstrength = wm->m_ReflectionTintStrength;
@ -100,7 +99,6 @@ void SetSettings(const sEnvironmentSettings& s)
cmpWaterManager->SetWaterLevel(entity_pos_t::FromFloat(s.waterheight * (65536.f * HEIGHT_SCALE)));
WaterManager* wm = g_Renderer.GetWaterManager();
wm->m_Shininess = s.watershininess;
wm->m_Waviness = s.waterwaviness;
wm->m_Murkiness = s.watermurkiness;
wm->m_ReflectionTintStrength = s.waterreflectiontintstrength;
@ -169,6 +167,30 @@ BEGIN_COMMAND(SetEnvironmentSettings)
};
END_COMMAND(SetEnvironmentSettings)
BEGIN_COMMAND(RecalculateWaterData)
{
void Do()
{
Redo();
}
void Redo()
{
CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
ENSURE(cmpWaterManager);
cmpWaterManager->RecomputeWaterData();
}
void Undo()
{
Redo();
}
};
END_COMMAND(RecalculateWaterData)
QUERYHANDLER(GetEnvironmentSettings)
{
msg->settings = GetSettings();

View File

@ -422,7 +422,6 @@ MESSAGE(SetView,
struct sEnvironmentSettings
{
Shareable<float> waterheight; // range 0..1 corresponds to min..max terrain height; out-of-bounds values allowed
Shareable<float> watershininess; // range ???
Shareable<float> waterwaviness; // range ???
Shareable<float> watermurkiness; // range ???
@ -471,6 +470,8 @@ COMMAND(SetEnvironmentSettings, MERGE, // merge lots of small changes into one u
((sEnvironmentSettings, settings))
);
COMMAND(RecalculateWaterData, NOMERGE, ((float,unused)));
QUERY(GetSkySets,
// no inputs
,