I'm sure I could come up with some really edgy double entendre, but my brain is too frazzled... I've been working on the digital component of "Open Casket" - essentially a very simple 2d water simulation of drops sending ripples, reflecting off the edges of the impression.
After a bit of Googling around, I found a very simple simulation that basically said that for each step, the height of the water in a 'cell' at a point x,y, is the combination of the heights in the left/right/top/bottom cells. I mentioned this in my last post on Open Casket, and suggested it was too simple to work with non-rectilinear containers. My assumption was that given the way it was presented [basically as if it was a 'hack'], it must be something someone had just come up with messing around. I did implement it, but it gave ugly results, so I went to look for a 'real' implementation.
After more research, I discovered that the type of simulation I'm after is typically referred to as height-field water. Essentially the water is modelled as a height-field, which allows ripples etc, but doesn't allow splash or tearing, since the water can only have one height at a given point. What was more interesting was that I saw the same implementation [more or less], but this time with a full explanation of the logic behind it. It actually transpires to be a real physics based implementation, albeit a very simplified one!
Essentially it is based on the fact that the force acting on a column element in the grid is proportional to its height relative to its neighbours. The velocity of the water interface can therefore be derived from that, and from there, the height at each point, for any given time. In other words, the taller any point is above its neighbours, the more it accelerates downward, and vice versa.
Buoyed up by this discovery [I love a good pun, you know that], I re-implemented the code. After a bunch of cock-ups because I forgot that I was reading the same array of heights as I was writing too, I got to something fairly well-behaved. Nevertheless, the ripples were still a bit weird and square, but I realised this is because I was perturbing a single element to initiate the ripple, so I wrote code to perturb a circular patch instead - essentially make a small bulge. This gave much nicer ripples.
Finally I have implemented code to add obstacles to the grid - basically to allow me to draw regions that are 'not water'. These are held fixed at zero height, which is probably a nasty hack, but seems to give good ripple reflections anyhow.
There's not a lot to see, but please notice and appreciate the ripples coming off the blue blob, especially how they are distorted by the non-straight edge. Yeah, this is how I get my thrills.
Next step is probably to find a nicer way to render the surface - it's currently based directly on height, but that gives some 'meh' results, especially the white 'blips' which each bulge is initialised. Ideally I'd render it as something closer to reflection and caustics. I need to decide if I want to do that by hand [I have code I created before that could potentially do it] or whether I just export to Blender using Openvdb Volumes and render there with full ray traced sexiness....
I also need to consider if I need to make each drop a double perturbation to simulate tearing at that point - basically ripples from a drop spread in a series of ripples because the initial splash goes up, tears, and comes down as a second drop a few moments later, which in turn may throw up a third drop that comes down to make a third ripple... And so on... Kinda fiddly to code as I'd have to track all the drop positions and add the second/third perturbations a few simulation steps later... Right now that sounds too painful for the benefit [relative to things like nicing up the rendering] but we'll see how I feel later [plus I only have 3 weeks left... Eeeek!]