I’ve been working with Jordan over the last few days on getting the physics infrastructure in place for Team Marble-ous (the marble roller coaster team for Wonderland’s Week of Code). If you haven’t been following the Week of Code updates, we’re working on creating a way to build roller coasters in Wonderland, with brave little marbles that roll along them into glory, or fall off of them into peril. Our goal is to create something that can be used as a tool for physics teachers, and so we want the roller coaster to behave in a reasonably realistic way, as well as to be able to display information that would be relevant in a classroom setting (physical quantities at different points along the marble’s journey, for example). We checked out a bunch of options in terms of powering the physics behind the coaster, and ultimately decided to use the open source JBullet physics engine, attached to the MTGame processing/rendering engine that Wonderland uses. We arrived at JBullet because of its maturity and robustness compared to a lot of the other options out there, and because there’s already code in place in MTGame to allow it to plug in nicely. It’s a very full-featured system; this makes it powerful, especially with respect to physical realism. This also, however, makes it overkill in some ways for this project. In particular, as I’ll discuss, the complexity of the system creates some challenges in terms of extracting physical data.
Our highly complex technical diagram of the project
Getting physics attached to the coaster in a basic sense was accomplished by adding a physics Component to our coaster Cell. Components in Wonderland are used to extend the functionality of Cells; in our case, we use a Component which loads the JBullet physics engine into MTGame when the coaster Cell is loaded. Visual objects associated with the Cell can then be recognized by the physics engine, and interact with each other in physically realistic ways. Ultimately, our hope is that physics functionality will appear as a Component in the Wonderland core – while there’s a ways to go in terms of generalizing the process, it’s nice to see that it’s possible, and the Component system really is a powerful way to add this kind of functionality with a relatively small amount of code.
One of the challenges with using JBullet as our physics engine is that the engine is single-threaded. Kinematic computations are highly interdependent, in the sense that when multiple bodies are involved, the motion of each affects the motion of all the others, and solutions to motion equations are obtained iteratively and approximately to take these dependencies into account. To treat this sort of problem in a multi-threaded way would make it substantially more complex, so the engine chooses to forego thread safety in favor of simplicity. This means that while JBullet physics works fine if we just let it handle the motion of objects in the world, we can break it if we try to extract physical data explicitly from it – access to physics data has to occur on the JBullet thread, and even on this thread, internal data structures aren’t reliable during iterations of computation. For example, if we want to display information about the physics of the marble, we can’t just poll the marble object for its properties whenever we want.
To access data safely, we take advantage of the fact that JBullet treats motion as discrete. A simulation proceeds at some fixed frame rate; motion is resolved manually at the beginning of each frame, and then the JBullet thread sleeps for the remainder of the frame length. So, we’ve added the notion of a time step listener to the JBullet system in MTGame – we notify listeners after computations for each frame have been carried out, and they can safely access physical properties at that point. However, any access by listeners must still occur in the JBullet thread, meaning that computations based on physical properties have to happen quickly if the JBullet frame rate is to be maintained. In our case, this isn’t a huge problem, since for what we’re hoping to do we more or less just snag the position and velocity information from the marble at each time step, and use those to compute anything else we need later. But one could imagine situations where this becomes a bigger issue, if physics computations on top of JBullet are at all time-consuming. A problem to tackle another day :-).
Up next is dealing with how to manage the physics data we get for the marble, and then syncing it up with the UI. Jordan has a cool idea about making the marble change color to represent the balance between kinetic/potential energy and the loss of energy due to external factors. We’ll keep you updated.
Peace and marbles.