Search This Blog

Fizz: A rope physics simulation for SFML

Last summer I decided to work on a short project to exercise the use of custom shape classes in SFML. I settled on the idea of a screensaver which changes over time, featuring an sf::GrassShape class and some pretty coloured lamps which light up at night. You can see the end result in this video (sped up with a time lapse capture):

The idea behind the relatively low quality graphics was to draw the entire scene with only shapes derived from SFML's shape class; a class which draws shapes using OpenGL vertex arrays and optionally fills the shapes with a colour or texture. To keep the installation of the screensaver as tidy as possible I wanted to omit any external texture dependencies (and therefore a hard drive full of bitmaps) opting for the fill settings available in SFML.

While drawing the basic shapes is relatively straight forward due to the ease-of-use of the SFML api, I wanted to get some nice motion into the scene. I added a function to the grass shape class which modified the bend of a single blade, allowing me to modulate the bend value with the output of a wind force generator (which in this case was libNoise). The ropes holding the lights, however, were a bit more complex. Scouring the internet for samples and examples of rope simulation I came across an article on the always helpful NeHe site here. In it is described everything you need to know about the simulation of masses and constraints so I ported the example code to use SFML. The result was Fizz (as in FIZZicks - yes, I know...); a small group of classes which can be easily inserted into any SFML project to simulate ropes and any other mass/constraint system (pulleys perhaps?) by deriving a custom simulation from the BaseSimulation class. The simulations only calculate the underlying physics whose output values you can use to draw your rope or other simulations. If you've used box2D before you will know what I mean - although if you've used box2D there's little point to Fizz as box2D is far more comprehensive. Also, much like box2D, Fizz uses real world units (metres / kilograms / seconds) and therefore needs to be scaled to the SFML project world space. Trying to use 1 pixel as 1 metre just isn't going to work, so I included a Scale constant in the RopeSim class. The resulting rope simulation was perfect for the ropes in the screensaver holding up the lights. The simulation class also allows for interaction with external forces so it was easy to influence the movement of the ropes using the same libNoise generator which was blowing the grass blades around.

I've also written a small demo application using Fizz to demonstrate its rope simulation capabilities.

You can download the source, complete with Visual Studio 10 project, here. It should also compile on any other SFML compatible platform but you will need to set up your own project file and link to the necessary libraries - in this case SFML. The demo does not use libNoise. Hopefully someone may find a use for this - recently I found it quick and inexpensive to include in a project where I used it to simulate the loose wires dangling from a robot's head (more of that project another day). If anyone comes up with some more simulation classes for Fizz, I'd love to hear about it.