Water issues

Topics: Developer Forum, User Forum
May 1, 2010 at 5:20 PM
Edited May 1, 2010 at 5:27 PM

Hi all,

I wanted to have a small body of water in my game, much like the SimpleWaterXNA sample from the latest version, and so I started off with just trying to get that same code working inside a test project first. I copied over the "WaterModel.cs" class, and then added in the code for Initialise(), Update(), and Draw(), making some modifications to fit the game engine I'm using (FlatRedBall XNA). I got the code compiling correctly, but when I run, all I get is the water block showing up, with absolutely no behaviour at all. There's not the slightest movement or waves (yes, I have the WaveController enabled), and the 2 objects I dropped into it don't get affected at all - they just fall past like they're falling through a transparent static texture and hit the ground.

Here's a sample screenshot: http://img263.imageshack.us/img263/1456/farseerwaterissue.png
I've taken it at the moment when the two objects hit the water (they fall from the top when the app is run), and as can be plainly seen, there is no reaction whatsoever...it's a perfectly static rectangle.

As the water demo had a fair bit of code, I've decided to upload the test project instead of pasting all the code I'm using. This can be found here.

There are a few things I wasn't sure about when porting over the code to my test project, so I'm listing them here, as they could potentially be the cause of trouble, I'm not sure (line numbers are from my test project):

  • 1) When we set the projectionMatrix (Matrix.CreateOrthographicOffCenter(...) method), the demo code had hardcoded zNearPlane and zFarPlane values. I wasn't 100% sure what to substitute it with for my use, so I've used the viewport's min and max depth      (FlatRedBallServices.GraphicsDevice.Viewport.MinDepth and FlatRedBallServices.GraphicsDevice.Viewport.MaxDepth), which I think should be right, atleast going by the IntelliSense description of those two fields.
  • 2) If you comment lines 146 - 148, and uncomment line 149 (which is basically just me initialising the WaterModel with fixed position and size as opposed to the demo doing some calculations), the water block goes to the top-left corner of the screen (because I have (0, 0) for position), although my game engine's (0, 0) is at the center!), is very tiny (I've given it a size of (200, 50), which would be massive in my engine, but I'm guessing it uses screen coordinates), but actually looks like its doing something. When the two objects fall down in between the walls on the ground, that tiny water block at the top-left actually shows some tiny waves. This bit really confuses me! :-/
  • 3) At line 294, second last statement of the CreateWaterVertexBuffer() method, there's a comment which says "Assumes bottom of screen is 600". What's up with that? I have no idea how that contributes to the water's functionality, or what I should change to fit my engine.
  • 4) Lastly, I've noticed that the VertexBuffer uses Vector3 positions, with all the Z values at 0 by default. And the default FlatRedBall camera through which the world is viewed has a Z of 40. Not sure whether this causes a problem with the water behaviour or not?

So that's basically it. Apart from the above mentioned, everything else is quite identical to the water demo code, and so I've been having a really hard time trying to figure out what to change.

Any help from anyone whose successfully implemented water, particularly if with the FRB XNA engine, or any of the awesome devs, would be great and highly appreciated.

Thanks in advance, guys!

May 1, 2010 at 10:40 PM

I will take a look at your code, but honestly the Water sample was written more for the physics part then the graphics part. I just got it running well in the demo and then left it. It's really not very well written and my code has gotten much better since then. Perhaps I will get some free time and implement a better solution for both Farseer 2.x and 3.x.

May 1, 2010 at 11:30 PM

Thanks for that, Matt, I do hope there's some sort of solution as I need it ASAP. It doesn't matter if the code isn't precise at the moment, as the priority is just getting what I've seen from the Water demo into my game so I can show that to my supervisor.

Also: While the sample project I've upped has Initialise(), Update(), and Draw() methods (Game1.cs), my actual game project uses FlatRedBall "Screens", which have only Initialise() and Update() methods, no Draw(). Would you have any idea in such a case as to where the demo's Draw() code could go?
When I copied that drawing code into the main Update() method before updating the waterModel, I got nothing on the screen, so was just wondering. Would I have to perhaps setup my own Draw() method or something for the Screen?

Cheers for your help. 

May 2, 2010 at 5:58 AM

Ok just based on a quick look it seems FRB is using an orthographic projection to render your sprites. So your physics world is centered around 0,0 but my code assumes you want to render your water at the same scale and location you create it at. So to fix this you must decouple the physics representation and the rendering. I hope this makes sense I am working on it now but I will have to go to sleep soon and might not finish it by tomorrow.

May 2, 2010 at 8:58 AM
Edited May 2, 2010 at 8:59 AM
As far as I know, the camera I'm using is the default one without any modifications, and that's a 3D camera, as outlined in their "Camera and Coordinates" tutorial.

As for "decoupling" the physics and the rendering, I'm not really quite sure about what exactly that should have me do. Any further explanation if you have some time would be great.

Oh and never mind about the timing, I'm extremely grateful for the fact that you're putting in your time to helping with my problem. I'll speak to my supervisor about it taking more time due to being slightly more complex than I originally thought. As long as I can get it working before due date (its for a Uni. submission), I should be okay.

I'm working on some other stuff for the project at the moment, but I will poke around a bit more and see if I get lucky...

Thanks very much :-)
May 2, 2010 at 11:45 PM

Have you set up any debugging renderer? This will greatly improve your ability to solve problems like this.

What is happening is you are scaling everything in your physics world down to match FRB's coordinate system. What you should be doing is either changing FRB's camera to match the physics world (probably the best option as Farseer 2.1 is designed to work in pixel space) or scale all the physics positions every frame to match those of FRB's.

May 6, 2010 at 4:12 PM

Well, changing stuff around so that everything is rendered in pixel coordinates with FRB is going to be quite unfavourable as I'd have to reposition every single sprite in my game menus and level so far, and I don't have that kinda time.
With regards to the 2nd option, how exactly do you mean "scaling the physics positions" so that they match with FRB?

I find it a bit surprising that all the physics objects I have so far work perfectly well in the default FRB coordinate system, but then just to do water, I need to change it all... :s
Also, how come it does work and produce waves at the top left corner when I set the position at (0, 0)? Furthermore, all the physics objects (bodies) I've positioned at (0, 0) so far start off at the centre of the screen, so why does the water go to the top left when I set a (0, 0) on it? 

May 9, 2010 at 4:28 PM


I've had no luck so far, can't figure out how to get the water working at the position/scale I want it to, only works at (0, 0) (top left), which is no use to me.

Any more solutions please? Anyone? :(