Shallow Water and Rigid Body Simulation

Development

I implemented the project together with my fellow student Stefan Lienhard for the Physically-based Simulation course at ETH during the autumn semester 2008. Since my team mate did not have enough time to invest into the project I had to do much of the work on my own.

Detailed Description

Simulation of physics is continuing to become more and more important in computer graphics, in the real-time area like games, in medical simulation or in movies. This physics demo was implemented as part of the physically-based simulation course at ETH. It features a rigid body simulation, a shallow water simulation and the coupling between the two simulations. Implementing two simulations and the interaction between them is quite a broad topic, so only the important aspects of the simulations involved have been implemented.

The rigid body simulation contains only the basic features, but a large set of supported primitives, namely planes, spheres, cubes and arbitrary triangle meshes. The simulation supports colliding contact between rigid bodies. Resting contacts, the really difficult part of a rigid body simulation, have not been implemented since they are not important to simulate the interaction between shallow water and rigid bodies. Therefore the simulation only supports the collision between bodies. They never arrive at a resting state and will be always moving, even if the movement is so small that it is barely visible.

The water simulator is an implementation of the shallow water simulation presented at the Siggraph 2008 class Real Time Physics. It features the movement of water through space and also the interaction between the water and the terrain it moves through. For example the simulation of a river can be simulated by simply creating a terrain consisting of a river bed, a source at the top of the river and a sink where the river should disappear.

The interaction between the two simulations was implemented according to the paper Real-time Breaking Waves for Shallow Water Simulations by Nils Thürey, Matthias Müller-Fischer, Simon Schirm and Markus Gross.

The demo features different executables. The main executables show the river scene as described above. Some spheres are placed inside the river and flow down the river until they end circulating around the sink in the lake. Another executable shows how some rigid bodies float on a lake while some others sink to the ground depending on their weight.

Technical Details

Feature List

Challenges

The main challenge in implementing this demo was the implementation of the physics simulation. On one hand it was quite an experience to get the rigid body simulator reasonably stable since the numerical computations tended to get out of hand quickly. The other difficult problem was the interaction between the two simulations. The main source of information was the paper Real-time Breaking Waves for Shallow Water Simulations. But inside the paper only something like a third of a page was dedicated to the problem of interaction. Implementing it just as stated in the paper resulted in an unstable simulation. It took me some time to have an idea of how to solve the problem. But after adding some fake friction between the water and the rigid bodies things worked acceptably.

Award

The professor awarded the demo with first price out of eleven projects.

Screenshots

Rigid body simulation

A river with spheres flowing down

A ball moving inside the collision mesh of a terrain

The shallow water simulation

A swimming Stanford bunny

Videos

Rigid body Simulation

River video

Shallow water simulation

Code Sample

This code sample shows the main loop of the rigid body physics simulator:

//--------------------------------------------------------------------------------------- template < typename ODET > void Simulator<ODET>::Simulate( const math::real_t t_from, const math::real_t t_to ) { ++simulation_step_; FireBeginSimulationStep(simulation_step_, t_from, t_to); assert(ValidateSimulation(ValidateBeginSimulationStep)); // find contacts and apply impulses to resolve them FindContacts(); ApplyContactImpulses(); FireCollisionsDone(); assert(ValidateSimulation(ValidateAfterCollisions)); // renormalize the bodies orientation matrices. through integration // they may become weird... RenormalizeRotationMatrices(); // convert all the bodies in there current state into a large array and // run the rigid body simulation. afterwards convert the large array // back BodiesToArray(x_0_); ode_(x_0_, x_final_, t_from, t_to, dxdt_callback, this); ArrayToBodies(x_final_); FireEndSimulationStep(); assert(ValidateSimulation(ValidateEndSimulationStep)); }

Additional Material / Downloads

Related Links