PDA

View Full Version : Trouble porting liquid simulation to Pascal - AARRGGHH!



paul_nicholls
26-08-2011, 03:12 AM
Hey all,
I found this article the other day:
http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/

and I just HAD to make a Pascal version of the code...I am hoping to get something like this added to The Probe game :D

Unfortunately I have been pulling out my remaining hair trying to get it working, and I am not succeeding!! :(

In my code, I have changed all references of Mass to Water, and my coordinate system uses -y for going up, and +y for going down which is the opposite of the source code posted on the site.

I have also used sx,sy for the source water tile (instead of x,y), and dx,dy for the tile the water is trying to move to instead of x,y+1, and similar.

It works sort of, but definitely is not correct - some water doesn't even fall down, and other anomalies...

I have attached a .zip file containing my project if anyone has time to try it out, and get it working correctly. It is driving me nuts!!

573

It has both Lazarus and Delphi 2010 projects if this helps, and includes the engine DLL and a pre-compiled exe :)

Any help would be much appreciated!!

cheers,
Paul

Ingemar
26-08-2011, 05:05 AM
So it is almost-C code, intended for an interpreter? I would start by making it run as C code, and convert from there, but OTOH you have already made the conversion. I'll have a look at it.

paul_nicholls
26-08-2011, 05:20 AM
So it is almost-C code, intended for an interpreter? I would start by making it run as C code, and convert from there, but OTOH you have already made the conversion. I'll have a look at it.

Thanks mate, much appreciated :)

cheers,
Paul

Ingemar
26-08-2011, 10:44 AM
Making a pure C version wasn't worthwhile. Evil twisted code full of vague implications, lots of undefined stuff. Maybe it isn't very strange that your port didn't work, I have some trouble understanding what the original code does.

paul_nicholls
26-08-2011, 11:06 AM
LOL! ok, perhaps it doesn't work and is different that what is actually being used then :)

EDIT: hmm...I might try downloading the Java-Based Processing Programming Language mentioned, and try the supplied code to see if it is flawed or not ;)

ZOIKS! It is ~85MBs in size...oh well, downloading...

cheers,
Paul

paul_nicholls
26-08-2011, 11:47 AM
Ok, after a few minutes working out how to use Processing, I got the code as downloaded from the site to work just fine, so that is ok - it must be my port that is not working :(

Here is the direct link to the processing code that I ported if you hadn't already gotten that :)

http://1.shadowcdn.com/files/water_sim.zip

cheers,
Paul

code_glitch
26-08-2011, 01:39 PM
Looking through it - gives me a break from modularization of prometheus so you're welcome for posting this... Plus thats a nice article - maybe making a pascal version of the tutorial would be nice for the PGD archives :)

code_glitch
26-08-2011, 02:09 PM
paul: It wouldn't be a big nono if I wrote an equivalent bit of code to this since my port does not look too pretty in the IDE ;D and gave you that instead? Trying to translate this C/C++ is not hard its just a tad annoying TBH. I wish we had a continue statement in pascal (not sure one does not exist actually ???).

I'll get back to you guys with my equivalent code for this most soon... A fluid simulation engine would be quite nice for my games too.8)

Dan
26-08-2011, 02:48 PM
I wish we had a continue statement in pascal (not sure one does not exist actually).
It does in fact exist.

Ingemar
26-08-2011, 02:59 PM
EDIT: hmm...I might try downloading the Java-Based Processing Programming Language mentioned, and try the supplied code to see if it is flawed or not ;)

The whole idea of making an interpreted language running with an interpreter written in Java, clinging to every design flaw of C from 1970 (even re-intruducing some flaws that were fixed in the 80's), it stinks so bad from start to end that I don't want to let more of it than the example source near my computer. But fluid simulation is nice, so freshing it up it by porting it to FPC could be useful.

One wish for the port: Portability! How about isolating all platform dependent stuff into one unit?

code_glitch
26-08-2011, 03:42 PM
Ingemar: I very much like that idea. Unfortunately I made an attempt to get this working but it is an utter failure in many senses... See below:

I figured this might be easy so I wrote this up real quick: http://dl.dropbox.com/u/4853895/WaterSimF2.zip

Its my WaterSimF2 unit I had a crack at and a TestApp using prometheus for drawing the TMX background and updating the water etc... It behaves a bit like water with one exception: IN REVERSE!!! Oo I have o idea why but it does XD

So if anyone wants a fluid system that works in reverse until all the water is gone or just wants to mess around with it, see the link above ;)

Edit:
Screenie:

http://dl.dropbox.com/u/4853895/WaterSimF2_Screenie.png

paul_nicholls
26-08-2011, 10:25 PM
The whole idea of making an interpreted language running with an interpreter written in Java, clinging to every design flaw of C from 1970 (even re-intruducing some flaws that were fixed in the 80's), it stinks so bad from start to end that I don't want to let more of it than the example source near my computer

hahahaha!!! :D


But fluid simulation is nice, so freshing it up it by porting it to FPC could be useful.

One wish for the port: Portability! How about isolating all platform dependent stuff into one unit?

Isn't my non-working port portable and platform independent? LOL

cheers,
Paul

paul_nicholls
27-08-2011, 01:02 AM
Ingemar: I very much like that idea. Unfortunately I made an attempt to get this working but it is an utter failure in many senses... See below:

I figured this might be easy so I wrote this up real quick: http://dl.dropbox.com/u/4853895/WaterSimF2.zip

Its my WaterSimF2 unit I had a crack at and a TestApp using prometheus for drawing the TMX background and updating the water etc... It behaves a bit like water with one exception: IN REVERSE!!! Oo I have o idea why but it does XD

So if anyone wants a fluid system that works in reverse until all the water is gone or just wants to mess around with it, see the link above ;)

Edit:
Screenie:

http://dl.dropbox.com/u/4853895/WaterSimF2_Screenie.png

Hi code_glitch, I downloaded our port to have a look and found one thing - it doesn't compile using Delphi...

For example, in the Prometheus_Core.pas file:



{$Mode Delphi}

should probably be:


{$ifdef fpc}
{$Mode Delphi}
{$endif}

cheers,
Paul

User137
27-08-2011, 03:47 AM
Water simulation on pixel/block map has been in my interest for long time. I did some experiments long ago, but they weren't that great. However that tutorial you linked (http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/) was quite good, only that it was explained way too complicated.

Lets say we do water for pixelmap. For performance and memory reasons we want to have running water in a separate array like particles, and still water (100% of pixel in water) drawn to pixelmap. The particles try to divide its water to different down, left and right, and if they can't move and go full 100% of water they solidify into pixel to that spot.

The particle could have the water amount represented as byte (0..255), where 255 is full. Down direction is first priority. It attempts to move down if there is no particle at that spot, but if is, it adds all its water to that particle at down. How do you know what particle is down and that pixel reserved, is 1 problem. I'd propably solve it with per-pixel word map, each 0..65k telling particle index in that spot. It's much faster than going the whole particle array through checking for position, but takes more memory and limiting amount of max particles.

Next there is left and right. They must be considered simultaneously so that the water is split evenly to all 3 positions, self, left and right. Well, here it doesn't propably even matter how you do the math, it will look cool anyway and spread the water in all cases. You can even split all water to left and right and leave current position empty, if they had room to take it all. Or you can calculate it so that water level in all 3 blocks is made as close to each other as possible, with water you have usable from the current particle.

Could add that it might look pretty nice if water that is falling down would split it to left and right about 20% of its amount. It will make little shower effect, because it may look boring to see water flow down 1 pixel wide line.

Oh, when doing for-loop for dynamic particles like this, you must go through it from ParticleCount-1 downto 0. It will otherwise act weird.

code_glitch
27-08-2011, 08:56 AM
Paul: About the {$Mode Delphi} thing, I only use FPC and falsely make the assumption everyone else does. Sorry for that one - although if my code realy does not work in delphi, you could own your own copy of FPC for $0.00 extra! ;)

I'm still trying to figure out what is making my sim go screwy but logically ( to me anyway ) it should work. In theory.

paul_nicholls
27-08-2011, 11:56 AM
LOL! No worries mate, I will just try it in my insanely expensive (NOT!) copy of Lazarus :D

cheers,
Paul

paul_nicholls
27-08-2011, 10:35 PM
@code_glitch: I can't get your liquid sim to run...at first it was missing a bunch of SDL dlls (image, ttf, etc.) so I downloaded those.

Unfortunately it crashes for me and I don't see anything apart from the crash :(


---------------------------
Error
---------------------------
An unhandled exception occurred at $0041154B :

EAccessViolation : Access violation

$0041154B IMAGE__LOAD, line 170 of Src/Prometheus/Video/Image.pas

$004117B4 TILESET__LOADFROMIMAGEFILE, line 19 of Src/Prometheus/Video/TileSets.pas

$00412D41 MAP__LOADFROMTMX, line 342 of Src/Prometheus/Video/Maps.pas

$00401AB3 main, line 74 of TestApp.dpr




---------------------------
OK
---------------------------


cheers,
Paul

code_glitch
28-08-2011, 11:10 AM
Haha, of course, sorry. I'm still making retard mistakes and assumptions like 'everyone uses linux and requires no DLLs'... I repacked the whole things into one nice shiny new Win32 compatible package right here: http://dl.dropbox.com/u/4853895/WaterSimF2-Win32Compatible.zip

Sorry for all the faff, especially since it was just a case of dropping in the full RTL (I don't what is/isnt required here) so if you notice any of those DLLs are unused and need the extra 900kb of HD space please feel free and remove em'.

paul_nicholls
28-08-2011, 11:31 AM
Haha, of course, sorry. I'm still making retard mistakes and assumptions like 'everyone uses linux and requires no DLLs'... I repacked the whole things into one nice shiny new Win32 compatible package right here: http://dl.dropbox.com/u/4853895/WaterSimF2-Win32Compatible.zip

Sorry for all the faff, especially since it was just a case of dropping in the full RTL (I don't what is/isnt required here) so if you notice any of those DLLs are unused and need the extra 900kb of HD space please feel free and remove em'.

Thanks mate :) And no need to apologise at all...windows people usually don't know Linux very well, and Linux don't usually know Windows very well :D

I am a real noob when it comes to Linux programming! haha

cheers,
Paul

code_glitch
28-08-2011, 01:30 PM
HAL Voice: "I'm afraid I can't agree with you paul...."

In reality though, if you can program on windows, press ctrl+Alt+T and type sudo apt-get install you can use linux (yes, I know some people prefer yum and rpms but hey, thats just sudo yum install...). In fact, I found programming on linux more forgiving. EG: I forgot to close that file but I can re-open it a few times (bad coding practice I know) but sometimes you don't care what the file is doing - you're trying to fix a bug in some opengl matrix ;)

paul_nicholls
28-08-2011, 08:45 PM
Fair enough :) Oh, sorry if my previous post seemed insulting! That was not what I intended :(

cheers,
Paul

code_glitch
28-08-2011, 09:48 PM
Not at all, I didn't find it at all insulting actually. Rather, its encouraging to see a +1 for the 'interested in linux' or 'acknowledges linux group'. A lot of people say class linux as a hacking project by some shed geeks that isnt accessible to anyone and a rebellious non-conformist joke for the poor that can't afford 'real PCs'. And I kid you not - I have heard that opinion voiced more times than you would believe. So for me, your post was kinda refreshing since it puts Linux on par with windows as two means to the same end ;)

Ingemar
29-08-2011, 04:47 PM
I made a port, but the result makes no sense to me. This is using FPC, OpenGL and GLUT, so it should be quite portable. The text output is not supported. Here it is:

http://www.computer-graphics.se/water_sim_fpc.zip

It animates, but I don't find the animation very enlightening. It doesn't produce a pretty flow. I probably have some errors in the conversion (although I tried to stick as close to the original as possible).

code_glitch
29-08-2011, 06:15 PM
@Ingemar: compiles and runs fine. I can see your point - esthetically it really looks pretty dire - I guess if you set each block to 1 pixel x 1 pixel you could get some decent looks going but that would kind of defeat the point of handling it in a cellular fashion as it would be more efficient to simply render it as particles then...

User137
29-08-2011, 09:50 PM
I got it compiled and running (buggily like mentioned) but MacOSAll had to be commented out from uses list. You could add something like {$IFDEF mac}MacOSAll,{$ENDIF} if there is such. This on Win7-32bit.

paul_nicholls
30-08-2011, 03:29 AM
Woo Hoo!!

After some fiddling around, I have now gotten my fluid sim working just like the online demo (I think! LOL)
http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/

http://img155.imageshack.us/img155/7531/liquidsimulation.png (http://imageshack.us/photo/my-images/155/liquidsimulation.png/)

I have attached the complete project, including .exe and source code :)
583

Escape = exit program
R = randomize map
C = clear map
right mouse button = water (+ shift = air)
left mouse button = wall (+ shift = air)

Enjoy!

It would be nice to know if anyone manages to use this in a project :)

cheers,
Paul

Ingemar
30-08-2011, 05:22 AM
I got it compiled and running (buggily like mentioned) but MacOSAll had to be commented out from uses list. You could add something like {$IFDEF mac}MacOSAll,{$ENDIF} if there is such. This on Win7-32bit.

MacOSAll isn't even used, it just popped in because I usually use it, but it has no place in portable code. But if that was the only difference, then portability is quite good.

User137
30-08-2011, 07:14 AM
After some fiddling around, I have now gotten my fluid sim working just like the online demo (I think! LOL)

It would be nice to know if anyone manages to use this in a project :)
It seems to be working somewhat, but there are 3 issues i can come up with ::)
- The timer is very heavy on cpu, using full capacity of 1 core.
- Air pockets are filled with water coming from below. The pressure should in physical world limit water flow to only down and sideways, as it is implemented in many games too.
- The simulation goes through every tile on screen per game tick. It may work with small mapsizes but when it comes to larger and pixelmap, it would hog all resources. This is why i suggested particle based approach earlier in this thread, which would be very high performance.

Ingemar
30-08-2011, 04:09 PM
Woo Hoo!!

After some fiddling around, I have now gotten my fluid sim working just like the online demo (I think! LOL)


I thought I should have a look at your code to see what I did wrong, but I am looking at your code and I don't get it. What code is working? I am looking in SimCompression_pde.pas, and it looks like... well, I must be looking at the wrong place because this can't be Pascal code:

if ( blocks[x][y] := GROUND) then continue;

That can NOT be a conversion of

if ( blocks[x][y] == GROUND) continue;

No, I must be looking in the wrong place. Is your archive really your working version? If it is, where is the code for the simulation?

I also note that if I change "continue" to "cycle" in my code, my code seem to get slightly closer to correct, so is really "continue" the same in both languages?

code_glitch
30-08-2011, 04:56 PM
Theres a small mistake there in the first if statement, you use := wich is to assign, a c/c++ family == is the same as = without the :

Just my 2 pence.

Ingemar
30-08-2011, 07:01 PM
Theres a small mistake there in the first if statement, you use := wich is to assign, a c/c++ family == is the same as = without the :

Just my 2 pence.

Yes, that is what I am saying. And there are such things all over that code so it can't be the working file. It looks more like a first step of conversion. The "for" loops are even worse:

for (integer x := 1; x <= map_width; x++)begin
for(integer y := 1; y <= map_height; y++)begin

Please don't tell me this is legal Pascal code. So is there a working conversion in there too?

code_glitch
30-08-2011, 10:32 PM
Wait, I'd be over the moon if you could x++ in pascal - as far as I know its either the INC() way or x := x + 1 and declaration on the fly could be nice also mind you ;)

Although when porting from one language to another - I have to admit a lot of my code can look like this or worse - but hey, if it compiles/compiled then please tell me how - I'd love those features :)

paul_nicholls
30-08-2011, 10:36 PM
I thought I should have a look at your code to see what I did wrong, but I am looking at your code and I don't get it. What code is working? I am looking in SimCompression_pde.pas, and it looks like... well, I must be looking at the wrong place because this can't be Pascal code:

if ( blocks[x][y] := GROUND) then continue;

That can NOT be a conversion of

if ( blocks[x][y] == GROUND) continue;

No, I must be looking in the wrong place. Is your archive really your working version? If it is, where is the code for the simulation?

I also note that if I change "continue" to "cycle" in my code, my code seem to get slightly closer to correct, so is really "continue" the same in both languages?

Ah! I know what is going on...the SimCompression_pde.pas file is a partially converted version which I forgot to delete - it is not used, sorry about that!! :-[

The files you need to look at are the units\unit_liquidsimulator.pas file, and of course the xeEngineTest.dpr file too :)

Continue I think works the same in both languages, at least my code gives the same visible results...what does cycle do? I haven't heard of that one :)


It seems to be working somewhat, but there are 3 issues i can come up with ::)
- The timer is very heavy on cpu, using full capacity of 1 core.

hmm...interesting, I just ran it on my machine here (Win XP, Intel(R) Core(TM) 2 Quad CPU (@2.83GHz, 3.48GB RAM) and it does't come close to hogging one core.


- Air pockets are filled with water coming from below. The pressure should in physical world limit water flow to only down and sideways, as it is implemented in many games too.

LOL The only game I remember playing with fluids is Terraria, and ok that does work only down and sideways as you said...but I quite like the way the 'pressure' pushes liquid up again as that is what I would expect to happen :)

It could easily be changed though ;)


- The simulation goes through every tile on screen per game tick. It may work with small mapsizes but when it comes to larger and pixelmap, it would hog all resources. This is why i suggested particle based approach earlier in this thread, which would be very high performance.

Ok, it could definitely be made more efficient. Perhaps I could use a particle (pixel) based approach that you mentioned earlier, but that would be harder to draw wouldn't it? With the current version, you just draw some tiles (which also fits in with how a game I am writing is done too)...

Other ideas would be to have a separate list of tiles with pressures in them which you process instead of the whole map, and only process their neighbours too in the map when needed...that should be much quicker.

Hmm...I could also convert the current version to use fixed-point math too, that might may things quicker too :)

cheers,
Paul

paul_nicholls
30-08-2011, 11:19 PM
Wait, I'd be over the moon if you could x++ in pascal - as far as I know its either the INC() way or x := x + 1 and declaration on the fly could be nice also mind you ;)

Although when porting from one language to another - I have to admit a lot of my code can look like this or worse - but hey, if it compiles/compiled then please tell me how - I'd love those features :)

I believe there is a setting in Lazarus (and I guess freepascal too) where you can use +=, -=, etc. operators, but I don't know about ++ and --

cheers,
Paul

Ingemar
31-08-2011, 05:30 AM
I believe there is a setting in Lazarus (and I guess freepascal too) where you can use +=, -=, etc. operators, but I don't know about ++ and --

cheers,
Paul

Correct, and += and -= are pretty useful. ++ and --, however, I'd rather live without, especially when used for throwing in side effects while doing other things.

You even have << and >> in FPC. It is sensible, the few times where C syntax makes sense there is no reason not to incorporate it. But finding C-style "for" loops is something that was supposed to be working Pascal code, that was scary. One detail that makes me uncertain is the ability to spread variable declarations all over the place. Should variables be at one place or anywhere? Defining a variable locally within a for loop or inside a begin-end pair, well, not entirely unreasonable... or is it just a workaround for messy code, when C programmers write entirely too big functions?

Anyway, now that I know what files to look for I can compare what we do.

User137
31-08-2011, 07:03 AM
I managed to partially do my idea on the pixelmap demo, just that i haven't done the solidifying part yet. With tiles that would be simple but i have to optimize the visuals for rendering to texture... So in the end all that would remain as particles is water surface and falling water, rest would become solid blue.

Cpu use was showing 0% at 3000, 12% at 5000 particles and going up from there. The solidifying would greatly reduce the amount of particles.

And it was quite fun to do too, was pulling my hair almost when equasion was wrong and water was disappearing slowly :D

Edit: Solidifying is working now in my dev version and it's awesome! Just 1 bug with some random particles leaving bubbling inside and doesn't fill their density up. After that's fixed i'll show again.

Ingemar
31-08-2011, 09:02 AM
OK, now I have fixed a few glitches and my version of the water simulation runs quite well. No Mac dependencies, I am not even using the macpas mode. It should be pretty close to Paul's version. The problem was in the screen update, not the simulation. What is good about this conversion: Small, close to the original, uses OpenGL (so it is fast), isolates user interface stuff (GLUT) into a separate unit so you can change it easily. Mac binary included.

http://www.computer-graphics.se/water_sim_fpc.zip

http://www.computer-graphics.se/watersim.png


The "continue" keyword seems to work just fine, and is equivalent to "cycle" in the macpas dialect.

I fixed the mouse support, so you can edit the map by clicking, which toggles between water and ground.

paul_nicholls
31-08-2011, 09:19 AM
@Ingemar: Nice work :)
@User137: Wow! this is very cool!

cheers,
Paul

User137
31-08-2011, 11:47 AM
So my pixel version should now be working correctly. Uploaded the files in its thread:
http://www.pascalgamedevelopment.com/showthread.php?10460-Cave-flying-technique&p=64326#post64326

Here's additional eye candy when i was still debugging the behaviour.
Blue = solid water drawn in texture
red = moving water with density<254
yellow = moving water with density=254
gray = moving water with density=255

Another picture just added... First i piled up a massive amount of water. Then go middle of water, hold firing key down and do a full 360 turn and you get something like this:
http://imageshack.us/photo/my-images/825/waterbig.png/
I just love to see things huge, lol. 46000 living water particles waving the streams. Very soon after it stabilized to more normal number of 1300 moving, where cpu is happy at 0% use.