This (old) post originally appeared on the website of Infi, the company I co-founded in 2003.

After writing my first iPhone app some time ago (see: Navier Stokes: iPhone vs iPad), last week I wrote another one. Not surprisingly, this app is again a fluid simulation.

If you have ever been wondering about little fluid experiments in a lab, this magical app might be the solution to all your questions! Contained within your iPad, iPhone or iPod touch you will find a small universe where you can define all the physical constants of mother nature. Just tilt or swirl: enjoy!

a

Fluid Dynamics

Inspiration for the app is some liquid-simulation code I found floating around on the internet. As far as I can see the first implementation of the simulation is in java and can be found here. This simulator has already been ported to flash, and (for some extra karma) to html5. Hoping to grab some of the remaining karma, I ported the code to iOS. I did some simplifications of the math, reducing the amount of operations in the inner loop and speeding up the simulation, but the algorithm is in fact the same as the java, flash and html5 port.

Universal app

liquid2

The application is an ‘universal app’. This means that it runs on both the iPhone and IPad in the native resolution of the devices. Because all the rendering is done using OpenGL ES almost no changes had to be made to the code. The only exception is the rendering of the settings-view. On the iPhone this view is presented fullscreen, while the iPad shows it in a popover (see the figure above).

The implementation of this behaviour was surprisingly easy: using the if-statement shown below, I add the settings-view as a subview of an UIPopoverController (for the iPad) or directly as a subview of the mainview (iPhone).


if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    // The device is an iPad, present settingsview in popover
} else {
    // The device is an iPhone or iPod touch, present settingsview as subView
}

Game thread

The ‘hello world’ OpenGL ES application in the developer section of the Apple site uses an interval calling the update-frame-function of the application every 30th of a second. As pointed out in this excellent post a timer will always (and only) fire on the scheduled interval times.

This means that if your update-frame-function takes only slightly longer than a 30th of a second to run, your framerate will directly drop to 15 fps. A solution for this problem (as found in the doom source code) is to use a separate thread for your game loop. This thread (having a low priority) constantly calls the update-frame-function in an infinite loop. This way the CPU is never idle and the simulation is running as fast as possible. As a nice side-effect, interaction with the settings-view (running in the main ‘high priority’ thread) stays responsive and smooth.

Liquid on iPhone and iPad