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:
parent
d56595c802
commit
15ec863aec
@ -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)
|
||||
{
|
||||
|
@ -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},
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
{
|
||||
|
@ -126,7 +126,6 @@ X(shadingColor)
|
||||
X(shadowScale)
|
||||
X(shadowTex)
|
||||
X(shadowTransform)
|
||||
X(shininess)
|
||||
X(skinBlendMatrices)
|
||||
X2(skinBlendMatrices_0, "skinBlendMatrices[0]")
|
||||
X(skyCube)
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
,
|
||||
|
Loading…
Reference in New Issue
Block a user