Thursday, February 24, 2011

Spatial Hashing and Blobbiness(!)

So though I have not yet gotten to add any real user interaction to the program, I'm pretty pleased with my progress for the week.

It turns out the Heckbert particle data structure was doing too much to be worth using for this part of the project since I only need a simple spatial data structure with a constant radius of interaction. I coded up a very basic spatial hash grid. Right now, the domain is finite for simplicity but I think if I choose a good hash function I should be able to essentially only create buckets where there are particles in the bucket. For now though, the grid is large enough to address any animations I would want to simulate and fine enough to get save on search time. The data structure is able to find all particles within the radius of interaction (which is also the grid size) by only searching within its own bucket and the neighboring 26 buckets instead of searching the entire space. I wrote a test program to make sure the spatial hashing grid is able to correctly find its neighbors. Every time step, the grid is regridded by looping through the particles and updating their buckets in O(n). Here is a video of the test program running:



The selected particle is in blue (I am using the arrow keys to toggle the selection) and its neighbors are colored red. I added some random particle movement to test that the regridding is working correctly. The boundaries of the grid are also shown.

I have implemented Lagrangian viscoelastic fluid dynamics in a method very similar to the Clavet et al. paper. The springs were tricky to get stable, and required some tweaking. Here is an entertaining video of the entire thing blowing up while debugging the springs.



Even with the speedup from the spatial data structure, I am still having difficulty getting it to run at real time for 1000 particles. Running at 100 particles though, I am still able to get enough resolution to see droplets forming. And best of all, I was able to get some blobby surface tension effects by tweaking the rest pressure parameter. The parameters could still use some more tweaking, e.g. probably way too much elasticity and viscosity right now, but I'm pretty happy with my progress. Anyway, here are some videos of my blobby particles:



For next week, I am planning on trying to speedup the framerate, starting to add in user interaction and working on getting the implicit formulation working. It might be worth trying a simple marching cubes method just to see how fast it is, vis a vis this openSource implementation Joe sent me: http://paulbourke.net/geometry/polygonise/

Alpha reviews coming up... hope it goes okay

Thursday, February 17, 2011

Unstable Particles = Not Quite Liquid

So after setting up the particle system last week, this week I attempted to start getting it to behave as a fluid.  Mostly, I have been closely following the Clavet paper, which is essentially simplified SPH with viscoelastic effects, but the fact that we are covering fluid sim in Physically Based Animation definitely helps.

Right now, however, I have hit up against some problems.  Although at least there are visible particle and they are moving, right now I am running into some weird errors, such as that the particles are flying off of the plane, so I have had to reign back on some of the effects such as viscosity, etc. until I can figure out was is going on.  I also am currently using a simple arrayList (c++ std::vector) as the particle data structure, making the spring effects intractable in real time, so I am now trying to switch everything over to using the Heckbert spatial hashing grid data structure that I added to my framework.

Anyway, here is the video of the unstable particles. If you squint your eyes, I guess it sort of looks like a liquid...



Although I had hoped to start on the implicit representation soon, my current plan for next week (in addition to preparing for the alpha review) is as follows:
  • Switch over to using a simple spatial hashing grid (or Heckbert's fast repulsion grid) instead of std::vector
  • Get some sort of reasonable looking stable fluid with at least some of the effects I mentioned last week working.
  • As the main idea is that the simulation be interactive liquid, get some sort of rough user interaction working (e.g. clicking and applies a force vector).
  • More background reading on high surface tension
Obviously the second bullet point is going to be the most time-intensive, but I'm confident that now that I have the basic framework, GUI, data structure, time-loop, and pseudo-code written out I will be able to make a lot more progress.

Thursday, February 3, 2011

Physical properties and data structures

Well, this week wasn't nearly as productive as I had hoped, but I have managed to setup a basic particle system data structure and am now incorporating in the code from Heckbert's report "Fast Surface Particle Repulsion." Basically it's the framework for a 3d spatial bucket-list style grid that allows for fast access to neighboring particles and will be useful for both layering the fluid simulation effects onto the particle system and later for quickly constraining floater particles to the implicit surface formulation.

In the process of setting up my particle data structure, I have been researching what physical properties of mercury to which I can put actual numbers.  So far, the most relevant properties of mercury I have been able to quantify:

 Behavioral Properties
  • Surface tension
  • Viscosity
  • Elasticity/Plasticity
  • Density
Rendering Properties
  • Reflectivity
  • Index of Refraction
Here is a brief overview of each property, how mercury exhibits it, and how my particle system will attempt to achieve the effect (see references below):

Surface Tension
Surface tension is the property exhibited by liquids that allows them to resist external forces due to the cohesive forces among liquid molecules which, while netting to zero within the liquid, result in a net internal force at the boundary. It turns out that surface tension is also responsible for the "blobby" feel of mercury as well as its tendency to form droplets or puddles instead of spreading all the way out (combined with mercury's lack of adherence to many solids), since the droplets are pulled into the spherical shape by the cohesive forces at the liquid surface. Note the blobby behavior of the high surface tension liquids in this movie (thanks to Joe for finding this one). Mercury's surface tension is extremely high: about 487 dyn/cm at 15 deg. Celsius, compared to water's suface tension of 71.97 dyn/cm at 25 degrees Celsius.
In order to simulate such a high surface tension, it's looking likely I might have to rely on more than the double density relaxation algorithm described in Particle-based viscoelastic fluid simulation where some amount of surface tension and smoothed surface is ensured but the amount is not directly controllable. I'm hoping I'll be able to fake the increased surface tension by applying an additional cohesive force to boundary particles, but this may result in asymmetry or instability, in which case I will need to think of a different approach.

Viscosity
The viscosity of mercury is slightly more viscous than water, but much less so than honey for example.  
While the actual viscosity of mercury falls at 1.526 mPa*s (compared to 0.894 for water and 2,000-10,000 for honey), I think to make the haptic interaction more interesting I will be want the user to be able to vary this
by making it more viscous. 

Elasticity/Plasticity
Elasticity is the property that brings the material back to its original shape after a deformation is applied then removed.  There is a linear relationship between the force applied (stress) and the relative deformation (strain).  Above the elastic limit for the material, the relationship becomes nonlinear and the material is said to exhibit plasticity, meaning the substance "forgets" its past shape.  Elastic modulus is the measure of an object's tendency to undergo an elastic non-permanent deformation when a force is applied to it and is defined as stress/strain.  The bulk modulus of a substance is a measure of its resistance to compression or its incompressibility.  Mercury has a very high Bulk Modulus (extremely incompressible) of 28.5 * 10^9 Pa, compared to water's Bulk Modulus of 2.15 * 10^9.
Like viscosity, elasticity/plasticity are part of the viscoelastic fluid formulation and can thus be worked into the system as variables that the users can change.

Density
Mercury has a density of  13,546 kg/m^3 at standard temperature and pressure, compared to water's density of 1000 kg/m^3 and gold's 19320.  The density might be useful in computing an appropriate force feedback.

Reflectivity
Mercury's reflectivity is relatively high at 73%.  I hope to simulate the reflectivity using basic environment mapping.

Index of Refraction 
Mercury has a low index of refraction at 1.000933 (compared to water which 1.33), which will result in essentially no refraction in a vacuum.  However, if there is time, I hope to parametrize this property as well, so there would have to be some perturbation of the environment map based on the amount of refraction.

Basic GUI

So, after a nice debilitating bout of the stomach flu that seems to have been going around, I finally finished the basic GUI design, more or less as I had planned it out (see diagram from last post).

I made extensive use of the Qt library in constructing my GUI (and yes Joe, it is much much nicer than MFC so thanks for the save on that one).  Taking Yiyi's advice into consideration, I added some shortcuts to hide the sidebar and toolbars so that the main openGL window can scale up.

I also implemented a very simple maya-style camera with buttons to "pan", "tumble", and "scale"(please excuse my terrible sense of humor with the icon images.  And yes, it's supposed to be a tumbler).  Also, same keyboard shortcuts to do the same.  Rob Bateman's site was an extremely helpful resource for setting the camera up.

There's obviously still a lot to be wanting in the design, such as more parameters in the side toolbox, a floating axis in the corner of the openGL window and perhaps more interaction tools, but this should give me a framework to work from for the time being.  Meanwhile, I have also been setting up the as of now invisible particle system framework, which should hopefully become visible in the near future.  I've also been reading and re-reading some papers on viscoelastic fluids.  Right now, this one is looking to be the closest to what I am going to attempt to implement.

Anyway, here are some screenshots of my GUI and a video capture of my using the camera. More to come soon!