Game Development Community

dev|Pro Game Development Curriculum

Waterblock Tiling Bug Fix

by Paul /*ilys*/ Symeou · 05/15/2007 (11:31 am) · 17 comments

Download Code File

This resource is a very simple fix to the tiling issue with TGE 1.4x and TGE 1.5.x. The main fix is in fluid::SetInfo() where mTile is not actually set to anything, so the tile option in the world editor has no effect. This can cause an untiled, scaled waterblock to still seem as if there is water outside of the scale range, which is also the same for a 2048x2048 scaled waterblock that seems to tile but in fact does not.
The rest of the fix is just keeping the waterblock scale tidy for when and when not tiled.

#1
06/02/2007 (4:54 pm)
in void WaterBlock::inspectPostApply()
change:
VectorF scale(2048, 2048, mObjScale.z);
to
VectorF scale(mTerrainHalfSize * 2, mTerrainHalfSize * 2, mObjScale.z);
So this "fix" will fix the water in non-8-squareSized terrains.
The only issue I have now - if you change the terrain squareSize you need to reload the mission, and only after that the terrain will "tile" in full.
If you (or someone) knows how is the best to re-call the WaterBlock::SnagTerrain (to get correct values from updated terrain) - please share :)
Also, if pasting new waterblock it will automatically scale to fit whole terrain (if set to "Tile").
#2
06/05/2007 (3:14 pm)
Thanks for the non-8-squareSized terrain fix :)

As for you question, that's easy enough. The problem, and solution, is twofold.
The first problem is the waterblock will always assume the terrainblock is centralized, which it never is when you change the square size. The second problem is the waterblock depthmask needs to be refreshed, which is the easy part.

You will need to make changes to three files:

terrData.cc
Add the following code into TerrainBlock::unpackUpdate, at the bottom of the "init" if statement.
SimpleQueryList sql;
      gClientSceneGraph->getWaterObjectList(sql);
      for(U32 i = 0; i < sql.mList.size(); i++)
      {
         WaterBlock * pWater = dynamic_cast<WaterBlock*>(sql.mList[i]);
         pWater->mpTerrain = NULL;
      }
      setPosition(Point3F(-squareSize * (BlockSize >> 1), -squareSize * (BlockSize >> 1), 0));
This will cause the waterblock code to refresh the terrain information (WaterBlock::prepRenderImage checks if the waterblock has an assigned terrain, if not it will copy the needed information via WaterBlock::SnagTerrain and rebuild the depthmask) and recentralize the terrainblock. The recentralizing could probably go somewhere more sane, but for now that seems the easiest place to put it.

waterblock.cc
Move the scaling code from WaterBlock::inspectPostApply to the top of WaterBlock::CalculateDepthMaps. Leaving it in inspectPostApply will cause an issue where the scale does not change due to the square size being the default at that stage, keeping the tiled scale at a max of 2048x2048 which is useless for a higher square sizes than 8. CalculateDepthMaps is always called after the terrain information has been refreshed and when a waterblock setting is changed, so it's probably a better place to have it anyway.

waterblock.h
Move the mpTerrain declaration out of private and into public, about twelve lines up.
This one I'm not sure if there is an easier way to reference a protected member other than to move it into public. If you know, please do tell. This one always annoys me.


I do not know if this will cause any unforeseen problems, but I've not run into any yet.
#3
06/18/2007 (6:27 pm)
Is this still a problem in 1.5.2?
#4
06/20/2007 (10:28 am)
Yes, this was broken way back in the days of 1.3 (I think that was done about 2002) and was never officially fixed. There have a been a few forum threads about this over the years with a fix of sorts, but no one has ever committed a resource.

The easiest way to see of the problem effects you is to run the starter.fps stronghold mission, go to camera mode and move to the edge of the waterblock. At certain angles the waterblock will disappear, and there will be no underwater effect (both visually and physically). The try turning off the waterblock tiling in the missions editor and you will see it has no effect on the waterblock.
#5
06/22/2007 (5:47 pm)
OK then, final question.

Do I really need to make the changes you told bank to make? Or is it just a nice thing to add?
#6
06/22/2007 (6:13 pm)
Ron: actually it's nice to have. It will ease your work with terrain/tiled waterblock on squaresize != 8.
If you work with with normal terrain (8) you are fine as it is.
#7
07/25/2007 (9:27 pm)
Thank you so much for this, it was driving me crazy!!
#8
07/26/2007 (12:15 am)
I was excited when I found this, but I was under the impression that when I click on the tile option in the editor my water would stop tiling forever, but after implementing your code it still has no effect. Is this supposed to do that?
#9
08/02/2007 (11:34 pm)
Remember to change the size of the waterblock. By default TGE will scale the waterblock to an extent where it appears to tile.
#10
09/30/2007 (6:57 pm)
I took the codefile and extracted it to the correct location, overwriting the original files, and then tried to rebuild and got some errors.

fluidSupport.cc
..\engine\terrain\fluidSupport.cc(555) : error C2084: function 'void fluid::SetEyePosition(F32,F32,F32)' already has a body
        ../engine\terrain/fluid.h(123) : see previous definition of 'SetEyePosition'
..\engine\terrain\fluidSupport.cc(556) : error C2039: 'X' : is not a member of 'Point3F'
        ../engine\math/mPoint.h(265) : see declaration of 'Point3F'
..\engine\terrain\fluidSupport.cc(557) : error C2039: 'Y' : is not a member of 'Point3F'
        ../engine\math/mPoint.h(265) : see declaration of 'Point3F'
..\engine\terrain\fluidSupport.cc(558) : error C2039: 'Z' : is not a member of 'Point3F'
        ../engine\math/mPoint.h(265) : see declaration of 'Point3F'
#11
10/02/2007 (1:23 pm)
I can't figure out what the problem is here!

error C2084: function 'void fluid::SetEyePosition(F32,F32,F32)' already has a body

I've been messing with that since my last post and I really don't see any problems...
#12
10/02/2007 (4:04 pm)
Someone? Anyone? PLEASE?? :(
#13
10/07/2007 (11:23 pm)
Which version of TGE are you using?
#14
10/08/2007 (1:37 pm)
I have 1.5.2
#15
10/08/2007 (11:38 pm)
OK, Try opening fluidSupport.cc and remove the void fluid::SetEyePosition function. The codebase I used is slightly different in fluid.h and does not set the m_Eye. My code may be slightly older, so I'll do a fresh merge with TGE 1.5.2.
#16
03/07/2009 (5:32 am)
Well, I just say - go with the flow
If the water doesn't work in one spot, try another.
Sometimes the wave up and down messes it up.
Nasty terrain blocks will mess it more.

Note that most terrains on earth near water are smooth and eroded anyway.
A world with lots of terrain peaks and valleys that is all water doesn't make sense. If there is a problem in a part, maybe pull up a cliff face there. Or make a stream or tributary that makes sense to the error.
#17
04/11/2011 (6:51 pm)
Paul, you're my hero. Nice work!