Page 1 of 2

[TechDemo] liqöd - Water Simulation

Posted: Sat Jan 17, 2015 10:08 pm
by Ranguna259
Hello everyone :D

For the past month I've been working on water simulation and I've finally decided to post the code here.

The algorithm uses SPH to simulate water like physics and it's a basic copy from this code here with help from this post. It simulates water in a zero gravity enviroment (because I haven't implemented particle-to-rigid body collision yet) and it lookes really incredible.
Image

This demo also works on Android (and possibly iOS) using the corresponding ports (Android, iOS) but it's slow and that's why I need help threading things up. It supports multitouch too.

This is not the final code and I'm hoping you guys can help me out with this, namely performance wise (threading and such).
The main algorithm is located in liquid.applyLiquidConstraint function and this is not in any way binded with the LÖVE's physics module.

You can find liqöd's git repo here.

Keys:
Windows:
Left click - Spawn particles
Escape - Close demo
Mobile:
Touch press - Spawn particles

Re: [TechDemo] liqöd - Water Simulation

Posted: Sun Jan 18, 2015 1:47 am
by jack0088
super cool! makes me want to code cool things again. 8B

Re: [TechDemo] liqöd - Water Simulation

Posted: Sun Jan 18, 2015 7:22 pm
by Ranguna259
Thanks :3

Re: [TechDemo] liqöd - Water Simulation

Posted: Tue Jan 20, 2015 3:41 am
by rexjericho
Hey, this is really cool. I've been looking into SPH fluid simulation over the past few months.

I looked at your code, and modified a few lines to add gravity to the simulation to see how it would look. Press "g" to toggle gravity.

One way that could help with speeding up your program is to reduce the number of tables that are created each time step. Reusing tables will also ease the load on the garbage collector. Especially reuse of tables in loops within loops.

Example:

Instead of something like this:

Code: Select all

for i = 1,liquid._vars.numActiveParticles do
    local particle = liquid._vars.liquid[index]

    for i,v in ipairs(particle.neighbors) do
      local relativePosition = {liquid._vars.scaledPositions[v][1] - liquid._vars.scaledPositions[index][1],
                                              liquid._vars.scaledPositions[v][2] - liquid._vars.scaledPositions[index][2]}
      -- rest of loop
    end
end
Try this:

Code: Select all

local relativePosition = {}
for i = 1,liquid._vars.numActiveParticles do
    local particle = liquid._vars.liquid[index]

    for i,v in ipairs(particle.neighbors) do
      relativePosition[1] = liquid._vars.scaledPositions[v][1] - liquid._vars.scaledPositions[index][1]
      relativePosition[2] = liquid._vars.scaledPositions[v][2] - liquid._vars.scaledPositions[index][2]
      -- rest of loop
    end
end

Re: [TechDemo] liqöd - Water Simulation

Posted: Tue Jan 20, 2015 7:56 pm
by Ranguna259
Awesome job implementing bounderies :D
BTW, my code already has gravity but it was set to 0, you can find it on line 278 in my code and 286 in yours, at the end of the line change .0 to 9.8/300.
rexjericho wrote:One way that could help with speeding up your program is to reduce the number of tables that are created each time step. Reusing tables will also ease the load on the garbage collector. Especially reuse of tables in loops within loops.
I tested that and it got a little slower, I removed the local call from relativePosition, relativeVelocity and the d variables and created them right at the beginning of the applyLiquidConstraint function and I got these results:
Before changing:
120-160 FPS with 400 particles
liquid bfr.love
Before changing local calls
(4.18 KiB) Downloaded 140 times
After changing:
80-115 FPS with 400 particles
liquid aft.love
After changing local calls
(4.21 KiB) Downloaded 154 times
I'm looking into threading the code but I'm having difficulties because the current API thread doesn't support tables withing tables.

What's min_x and min_y for in your code ?
I'm going to merge your code with mine and upload it to github if you don't mind.

Re: [TechDemo] liqöd - Water Simulation

Posted: Wed Jan 21, 2015 1:56 am
by rexjericho
Ranguna259 wrote:Awesome job implementing bounderies :D
What's min_x and min_y for in your code ?
I'm going to merge your code with mine and upload it to github if you don't mind.
I don't mind at all.

(x_min, x_max) and (y_min, y_max) were for figuring out the bounds for particle.position. Then I found that I could multiply the position by liquid._vars.scale to get the relative position on the screen. x_min/y_min is always 0, and x_max/y_max aren't actually used since I figured out that scale thing.

I tried your above modifications and I also noticed a slowdown in the liquid_aft version. I had about 64fps before and 55fps after when simulating 400 particles.

I tried modifying liquid_bfr myself to make some optimizations, but they did not have an effect on framerate when simulating 400 particles. The modifications did have a slight impact when simulating a larger number of particles. I had 16 fps before vs 24 fps in the after version with 1700 particles. I wasn't able to measure a difference in FPS until simulating over 1500 particles.

It will be cool to see this fluid interact with Box2D rigid bodies when you get that working.

I implemented an alternate method of fluid-object interaction when writing my own SPH fluid simulation that seemed to work well. The objects were treated as a collection of fluid particles packed together into a shape. The object particles interact with regular fluid particles as if they were a fluid, except that their motion is controlled by an external force instead of by the force of the fluid. Here's a video showing what I mean:
https://www.youtube.com/watch?v=LIKSFU_4YTo

Re: [TechDemo] liqöd - Water Simulation

Posted: Wed Jan 21, 2015 6:28 am
by micha
This thing is impressive!!

Re: [TechDemo] liqöd - Water Simulation

Posted: Wed Jan 21, 2015 8:27 pm
by Ranguna259
rexjericho wrote:I implemented an alternate method of fluid-object interaction when writing my own SPH fluid simulation that seemed to work well.
Thank you
I love your blog and your game looks awesome too :D
rexjericho wrote:I don't mind at all.
Merged and updated.
I added the boundary as a post update function and I loved the way the fluid moved when the gravity was applied to the delta table of each neighbor so I added that too as a new type of gravity/water (press "w" to change between gravity types).
liquid.love
(4.96 KiB) Downloaded 161 times
rexjericho wrote:I tried modifying liquid_bfr myself to make some optimizations, but they did not have an effect on framerate when simulating 400 particles. The modifications did have a slight impact when simulating a larger number of particles. I had 16 fps before vs 24 fps in the after version with 1700 particles. I wasn't able to measure a difference in FPS until simulating over 1500 particles.
A little FPS improvement is better than no improvement at all, I'll look into your liquid_after to see what you did and I'll try to implement it in the current code.

rexjericho wrote:It will be cool to see this fluid interact with Box2D rigid bodies when you get that working.

I implemented an alternate method of fluid-object interaction when writing my own SPH fluid simulation that seemed to work well. The objects were treated as a collection of fluid particles packed together into a shape. The object particles interact with regular fluid particles as if they were a fluid, except that their motion is controlled by an external force instead of by the force of the fluid. Here's a video showing what I mean:
https://www.youtube.com/watch?v=LIKSFU_4YTo
I also thought about that but I never got into coding it because that'd probably have a major impact on performance due to simulating a huge quantities of particles so I decided to go with another approach, I'll call a queryBoundingBox to the objects on screen with a function that sorts the particles that are inside AABBs by using the grid, then I simply check if they are inside object by testing a point, if they are I'll run a raycast from the current point to the last point, see where it intersect with the object, move the particle to the intersection point and change velocities with the normal of the the object side that the particle intersected with, based my idea on this post.

Re: [TechDemo] liqöd - Water Simulation

Posted: Wed Jan 21, 2015 8:52 pm
by davisdude
Very cool library!
One minor note: you press "g" to change the gravity, not "w".

Re: [TechDemo] liqöd - Water Simulation

Posted: Wed Jan 21, 2015 9:08 pm
by Ranguna259
davisdude wrote:Very cool library!
One minor note: you press "g" to change the gravity, not "w".
Thank you :)
I said that the "w" key was to change the gravity "type" no the actual gravity :P