Realistic dice throw rendering with ODE, Python, OpenGL, and POV-Ray

I like dice games. I bought Scarne on Dice precisely to read more about them. (And, I should note, because I like John Scarne’s mock-didactic style combined with anecdotes about hanging out with Rat Pack Vegas gangsters in the 50s; I bought his “New Complete Guide to Gambling” and “…on Cards” as well for the same reason.) I like the idea of letting myself play dice games on Ubuntu and my N9, but all the existing ones are graphically a bit iffy: in particular, the dice tend to be shown as one single square face which is “rolled” by going blurry and then showing a number.

That’s not how dice work. So, in the great spirit of yak shaving, I started thinking about writing a few dice games and then got sidetracked into how to draw a realistic dice throw, so the dice arc over the table and then roll properly to a halt. Now, there are few guides to how to do this in Blender out there (as well as stuff I don’t have access to like 3D Studio Max), but Blender confuses the hell out of me. After some poking around, I also found a bunch of videos on YouTube: rendering a rolling die seems to be a relatively common thing to do for a school computer graphics project. One of them mentioned using POV-Ray to do the rendering and ODE to do the physics. Now, I used POV-Ray, years and years ago, and I quite like the idea of doing this sort of thing by writing a little programming language rather than using a GUI that I don’t understand. So I looked into this a bit. ODE is a pure physics engine: it doesn’t do graphics at all. Instead, you set up the world by setting what gravity is, adding various shapes and explaining how heavy they are, etc, and then you tell ODE: tell me what happens at each clock tick. ODE works it all out and just gives you the numbers back — position and rotation of every object. It’s then your job to use those numbers to draw pictures. (This is probably laughably simple if you’re trying to, say, write Half-Life 5, but I’m trying to simulate two perfect cubes hitting the floor, so my problem is equally simple.)

ODE has Python bindings, fortunately for me. And those Python bindings come with some examples, and one of those examples shows a bunch of cuboid shapes falling to the floor and being rendered with the Python OpenGL bindings. It was the work of but a few moments* to turn that into a little program that made two cubes fall. And then I added a bunch of keypresses which could alter where the dice were thrown from, the force and direction with which they were thrown, how they were rotated, that sort of thing. My goal is to get something that looks like a realistic throw and which keeps the dice somewhere nice and central, rather than them bouncing off one another and then off-screen (rather like the bullets in Gunmen of the Apocalypse, for those of you who’ve seen the Red Dwarf Smeg-Ups video).

Pleasingly for myself, I now have that. You can grab the code (requires python-pyode and python-opengl) if you’re looking for a trivial example of how to render a dice throw with PyODE and PyOpenGL; Space re-throws the dice, and the keys mentioned in brackets tweak the parameters listed on screen. Next step is to use it to generate a bunch of dice throws I’m happy with, and then write something similar which generates POV-Ray input files for each frame, and then make the cubes be dice in POV-Ray, and then finally I’ll have realistic looking animations for dice!

At which point I can get back to actually writing the games, which was the point of this. Still, this yak, while not entirely shaved, has a considerably closer haircut than before.