Re: [Algorithms] CA fluid dynamics
Brought to you by:
vexxed72
From: Chris G. <ch...@to...> - 2005-02-20 15:45:36
|
Thanks very much for the code Tom, I tried out your clamping scheme and it works really well. I still have an issue with each water cell continuously trying to flow to the left for some reason but I'm sure I''ll track it down. Ta for the link Martin. I've noticed that there's a couple of interesting talks on fluid dynamics at GDC this year which I'm hoping to check out. Here's some links: Simulation and Rendering of Real-Time Breaking Waves in Water Simulation* *http://www.cmpevents.com/GD05/a.asp?option=C&V=11&SessID=4766 New Simulation Architectures and Algorithms For Games Physics http://www.cmpevents.com/GD05/a.asp?option=C&V=11&SessID=3929 Cheers, Chris Gregan Tom Forsyth wrote: >Be warned - I havn't looked at this code in a while, so I might start >talking rubbish! > >But that code looks correct, and is the same thing I do. Maybe the thing >going nuts is massive instantaneous flow - I damped all my simulations >(heat, water, etc) pretty heavily to keep them nice and stable, so you set >an upper limit to the amount of flow that can happen each frame. > >So, um, I dunno! Stability in dynamic feedback systems is something that I >don't have a good understanding of. Generally I apply enough damping until >its stable, and fortunately the water seemed to look realistic even with >"enough" damping. > > > >Here is a direct cut'n'paste from the code concerned with fluid flow: > >this = the current "brick" (can't remember why I called them bricks instead >of cells) >pbrick = the neighbouring brick >z = the direction the other brick is in, an enum 0-6. >Brick::fStrength is overloaded to mean "amount of water" when they're water >cubes. >pbrickmaterial->fStartStrength is the volume of water one cell can hold >before having to increase in pressure. >CA_FLUID_Compress is the "tiny bit of compressibility" fudge factor = 0.01 > >The material numbers I used for water were: >fStartStrength = 1000.0f >fFluidity = 1000.0f > >Pretty sure fTurnDelta is in seconds. > > > >for ( int z = 0 to 5 inclusive ) >{ > pbrick = the neighbouring brink in direction z > > ...code to deal with turning neighbouring air bricks into water... > > if ( both bricks are made of water ) > { > float fFlow = 0.0f; > // Find out how much needs to flow in these cases. > switch ( z ) > { > case 0: > case 1: > case 2: > case 3: > // Sideways bricks. > // Assume we have dealt with surface tension above, >i.e. if the difference is > // less than surface tension, then that brick would >still be air. > // So just equalise the "pressures". > fFlow = ( fStrength - pbrick->fStrength ) * 0.5f; > break; > case 4: > // Upwards. > // StartStrength is overloaded to mean "maximum >volume per cube" > // So we ideally want to equalise with them >differing by StartStrength. > if ( ( pbrick->fStrength < >pbrickmaterial->fStartStrength ) || ( fStrength < >pbrickmaterial->fStartStrength ) ) > { > // One or other of the bricks are not full >yet - make the bottom one full. > fFlow = ( fStrength - >pbrickmaterial->fStartStrength ); > } > else > { > // Both bricks are full, so just allow a >little pressure differential. > fFlow = ( fStrength - ( pbrick->fStrength + >( pbrickmaterial->fStartStrength * CA_FLUID_Compress ) ) ) * 0.5f; > } > break; > case 5: > // Downwards. > // StartStrength is overloaded to mean "maximum >volume per cube" > // So we ideally want to equalise with them >differing by StartStrength. > if ( ( pbrick->fStrength < >pbrickmaterial->fStartStrength ) || ( fStrength < >pbrickmaterial->fStartStrength ) ) > { > // One or other of the bricks are not full >yet - make the bottom one full. > fFlow = -( pbrick->fStrength - >pbrickmaterial->fStartStrength ); > } > else > { > // Both bricks are full, so just allow a >little pressure differential. > fFlow = ( ( fStrength + ( >pbrickmaterial->fStartStrength * CA_FLUID_Compress ) ) - pbrick->fStrength ) >* 0.5f; > } > break; > } > > // Now do the transfer. Note that the above stuff can easily >result in > // one block going -ve, so we need to watch for that. > float fFlowLimit = fTurnDelta * pbrickmaterial->fFluidity; > if ( fFlow == 0.0f ) > { > // Fascinating Captain. > } > else if ( fFlow > 0.0f ) > { > // Limit by fluidity. > if ( fFlow > fFlowLimit ) > { > fFlow = fFlowLimit; > } > if ( fStrength < fFlow ) > { > // Clamp strength to 0 > pbrick->fStrength += fStrength; > fStrength = 0.0f; > } > else > { > fStrength -= fFlow; > pbrick->fStrength += fFlow; > } > } > else > { > // Limit by fluidity. > fFlow = -fFlow; > if ( fFlow > fFlowLimit ) > { > fFlow = fFlowLimit; > } > if ( pbrick->fStrength < fFlow ) > { > // Clamp the other strength to 0 > fStrength += pbrick->fStrength; > pbrick->fStrength = 0.0f; > } > else > { > fStrength += fFlow; > pbrick->fStrength -= fFlow; > } > } > } >} > > >TomF. > > > > > >>-----Original Message----- >>From: gda...@li... >>[mailto:gda...@li...] On >>Behalf Of Chris Gregan >>Sent: 18 February 2005 15:59 >>To: gda...@li... >>Subject: [Algorithms] CA fluid dynamics >> >> >>This mail is intended for Tom Forsyth, but I thought I would post it >>here in case anyone is interested. >> >>I'm trying to implement your algorithm for CA water listed in Games >>Programming Gems 3 and am getting some nice results, and some snags! >> >>I'm using a simple 2D grid for the moment to get my head around the >>algorithm. The psuedo-code you give on page 207 for water flow >>calculation works perfectly, but I'm having trouble figuring >>out how to >>clamp the flow value as you mention. When you write "...to >>prevent any >>resulting masses from going negative." do you mean something like the >>following? >> >> if (p_current->newMass - flow < 0.f) >> { >> flow = p_current->newMass; >> } >> >> if (p_neighbour->newMass + flow < 0.f) >> { >> flow = -p_neighbour->newMass; >> } >> >> p_current->newMass -= flow; >> p_neighbour->newMass += flow; >> >>For some reason, my simulation goes completely nuts unless I >>also clamp >>the flow to always be positive. If I understand the algorithm >>correctly >>then this would mean that water can only flow "out" of the >>current cell, >>whereas I'm pretty sure it's meant to flow in either direction? >> >>Any help would be much appreciated! It's a great article by >>the way and >>it's really fired off a lot of ideas for things we can do in >>our engine. >> >>Cheers, >> >>Chris Gregan >> >> >>Tom Forsyth wrote: >> >> >> >>>Yes - each cell stores the mass/pressure(*) of the "stuff" >>> >>> >>(in this case, >> >> >>>air) inside it, and also the velocity of the stuff that >>> >>> >>flows through it. >> >> >>>Essentially, you run primitive versions of Navier-Stokes >>> >>> >>equations on each >> >> >>>cell each turn, and as long as you make sure you preserve >>> >>> >>mass and energy, >> >> >>>there's a whole bunch of interesting ways to tweak and >>> >>> >>approximate things to >> >> >>>get nice effects. >>> >>>Note that if simulating water with your CA, the best trick I >>> >>> >>found (which >> >> >>>took me a lot of experientation to realise!) is to allow it >>> >>> >>to be slightly >> >> >>>compressible. That makes things soooo much easier - and if >>> >>> >>you only allow a >> >> >>>tiny bit of compressability (e.g. 1% smaller volume at >>> >>> >>double the pressure), >> >> >>>the users never notice, but the simulation is nice and stable. >>> >>> >>>TomF. >>> >>> >>>(*) since the volume of the cell is fixed, and you ignore >>> >>> >>annoying stuff >> >> >>>like phase changes, you can just make these two proportional >>> >>> >>to each other, >> >> >>>and it doesn't matter which you store. >>> >>> >>> >>> >>> >> >>------------------------------------------------------- >>SF email is sponsored by - The IT Product Guide >>Read honest & candid reviews on hundreds of IT Products from >>real users. >>Discover which products truly live up to the hype. Start reading now. >>http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click >>_______________________________________________ >>GDAlgorithms-list mailing list >>GDA...@li... >>https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list >>Archives: >>http://sourceforge.net/mailarchive/forum.php?forum_id=6188 >> >> >> > > > >------------------------------------------------------- >SF email is sponsored by - The IT Product Guide >Read honest & candid reviews on hundreds of IT Products from real users. >Discover which products truly live up to the hype. Start reading now. >http://ads.osdn.com/?ad_ide95&alloc_id396&op=click >_______________________________________________ >GDAlgorithms-list mailing list >GDA...@li... >https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list >Archives: >http://sourceforge.net/mailarchive/forum.php?forum_ida88 > > > > |