Height Field Fluids simulation

BlitzMax Forums/BlitzMax Programming/Height Field Fluids simulation

Armitage 1982(Posted 2008) [#1]
Hi

There is a whole system to easily simulating fluids in realtime from the Matthias Müller-Fischer paper : http://www.matthiasmueller.info/talks/GDC2008.pdf

I'm trying to implement this into my platform Box2d game "sandbox" but the routine just won't work as intended.

The best I can do is this
SuperStrict
SetGraphicsDriver GLMax2DDriver()
Graphics 640, 480, 0

Const m:Int = 126
Const damping:Float = 1.2

Local size:Float = 5

Local current:Float[m]
Local previous:Float[m]
Local result:Float[m]

While Not KeyHit(KEY_ESCAPE)
	Cls

	If KeyHit(KEY_SPACE) Then current[Rnd(1, m - 1)] = 200
	
	For Local x:Int = 1 To m - 2
	
		result[x] :+(current[x - 1] + current[x + 1] - previous[x] * 3) / 4
		result[x] :*damping

		SetColor 5 * Abs(previous[x]), 100, 100
		DrawRect(x * size, 300, size * 2, - 50 - previous[x])
	Next

	'This work
	For Local x:Int = 1 To m - 1
		previous[x] = current[x]
		current[x] = result[x]
	Next

'	Strange number occurs with this method :
'	previous = current[..]
'	current = result[..]

	Flip
'	Delay 100
Wend


This routine isn't exactly the same as described in the paper but if I try the same math then the simulation became really ugly.

Implementing the whole paper would be an excellent solution other than trying to write complicated buoyancy system.
Also it would probably well fit inside a box2d simulation.
But successfully realise the waves effect and faking buoyancy with water sensor is my first priority for this.

Does anybody is interested in this or could help me to fix what's not going well ?
Thanks


plash(Posted 2008) [#2]
Is that code even supposed to work?

Unhandled Exception:Attemp to index array element beyond array length


at
result[x] :+(current[x - 1] + current[x + 1] - previous[x] * 3) / 4



Armitage 1982(Posted 2008) [#3]
Ok I've Fixed the code...
In non debug mode things are sometimes working event when they should not.


Armitage 1982(Posted 2008) [#4]
Is anybody interested in this or may help to improve it ?


Retimer(Posted 2008) [#5]
Wouldn't know where to start to help with fluid dynamics, but I do appreciate you sharing the code.

I've used it as part of a sound frequency spectrum demo for the engine i'm working on.


AlexO(Posted 2008) [#6]
The Farseer.BMX physics module has basic buoyancy and height field fluid simulation. Have you looked at the source for the fluid controllers in Farseer.BMX to see if it would be of any help?
The farseer demo application along with the videos posted seem to have similar functionality to what you posted above.

EDIT:
on a side note these 2 articles have good information for implementing fluid dynamics, but it's more for simulating currents and forces underwater rather than creating waves on the surface:
Practical Fluid Dynamics: Part 1
Practical Fluid Dynamics: Part 2
I feel like these types of systems would be good for simulating objects that move under water causing currents and water-flow to affect other underwater objects.


Armitage 1982(Posted 2008) [#7]
Indeed !
Those Fluid Dynamics informations are pretty interesting.
You right, this fall under the dynamics rather than the "splash" effect but could lead to others solutions.

I did look at the Farseer example code and it use exactly the same height field logic.
Unfortunately the Farseer module is pretty huge and it's hard to only extract part that interest me.
About the Farseer buoyancy I thing it's very specific to this engine since there is a lot of modifications done since Box2d to handle convex and concave poly shapes which is a needed feature to calculate object buoyancy (as introduce by Motor2 engine http://lab.polygonal.de/files/buoyancy.html)
By the way this motor 2 proves that it's possible
http://www.polygonal.de/dev/motor2/buoyancy.html
http://lab.polygonal.de/wp-content/swf/motor/motor2_buoyancy.html
Maybe it's a good idea to look at this solver.

@Retimer
Glad it help.
It's aim to help anybody interested in :)


Armitage 1982(Posted 2008) [#8]
There is a function in Chipmunk example that fake buoyancy quite well:
Function applyBuoyancy(body:CPBody, gravity:CPVect, damping:Float, dt:Float)

	Const numx:Int = 20
	Const numy:Int = 4
	
	Const stepx:Float = WIDTH/Float(numx)
	Const stepy:Float = HEIGHT/Float(numy)
	
	body.ResetForces()

	For Local x:Int = 0 Until numx
		For Local y:Int = 0 Until numy
			Local pSample:CPVect = Vec2((x + 0.5)*stepx - WIDTH/2, (y + 0.5)*stepy - HEIGHT/2)
			Local p:CPVect = body.Local2World(pSample)
			Local r:CPVect = p.Sub(body.GetPosition())
		
			If p.y > 0 Then
				Local v:CPVect = body.GetVelocity().Add(r.Perp().Mult(body.GetAngularVelocity()))
				Local fDamp:CPVect = v.Mult(-0.0003 * v.Length())
				Local f:CPVect = Vec2(0, -2.0).Add(fDamp)
				body.ApplyForce(f, r)
			End If
		Next
	Next
	
	body.UpdateVelocity(gravity, damping, dt)

End Function

Exactly what I was trying to do since it don't have to be very precise.

In fact my wave code was right !

Just need to tweak the effect by multiplying some values.
SuperStrict
SetGraphicsDriver GLMax2DDriver()
Graphics 640, 480, 0

Const m:Int = 126
Const damping:Float = 1.2
Const waveForce:Float = 100.0
Const factor:Float = 2.0
Local size:Float = 5

Local current:Float[m]
Local previous:Float[m]
Local result:Float[m]

While Not KeyHit(KEY_ESCAPE)
	Cls

	If KeyHit(KEY_SPACE)
		Local pos:Int = Rnd (4, m - 4)
		current[pos - 3] = waveForce
		current[pos - 2] = waveForce
		current[pos - 1] = waveForce
		current[pos + 3] = waveForce
		current[pos + 2] = waveForce
		current[pos + 1] = waveForce
		current[pos] = waveForce
	EndIf
	
	For Local x:Int = 1 To m - 2
	
		result[x]:+(current[x - 1] + current[x + 1] - previous[x] * 3) / 4
		result[x]:*damping

		SetColor 5 * Abs(previous[x]), 100, 100
		DrawRect(x * size, 300, size * 2, - 50 - current[x] * factor)
	Next

	For Local x:Int = 1 To m - 1
		previous[x] = current[x]
		current[x] = result[x]
	Next

'	Strange number occurs with this method :
'	previous = current[..]
'	current = result[..]

	Flip
'	Delay 100
Wend

Replacing drawrect by sprites should be visually enough to approach the "splash" animation of new super mario :-D


Armitage 1982(Posted 2008) [#9]
The whole technique for buoyancy is more explain here http://blitzmax.com/Community/posts.php?topic=79516
I have open this new topic since it's more related to box2d now.

I also explain why I search for methods to decompose shapes into grid of atom.
If someone could help that would be nice :)