Last week I started integrating physics into my game. The two first two days I spent trying to learn Newton. Although straightforward, I dumped it because of a combination of outdated documentation, insufficient header file documentation, quirks, performance problems, poor forum support, and closed source. Every minor feature was a major time consuming issue and it just wasn’t worth hours of grinding to figure out why stuff as simple as acceleration = velocity * time doesn’t work. At the rate I was going, for my simple needs, I could have just written the physics from scratch faster.
Next up was a choice between ODE and PhysX. ODE was open-source which is a tremendous advantage over PhysX because if there are problems or something is unclear I can figure it out myself, rather than being at someone else’s mercy or just grinding my gears. However, PhysX used to be a commercial library which is now free for PC games. In my experience commercial libraries are usually an order of magnitude better than the free stuff. What ultimately decided me was the promise of a plugin for my 3D modelling program, and more confidence in PhysX meeting my performance needs.
Initially, I was overwhelmed by the amount of documentation and code provided in the SDK. However, after only a few hours I understood the structure of the system and found that it wasn’t that bad. There’s dozens of samples and tutorials, each of which is documented in a windows help file, which itself contains professionally written documentation covering the whole system.
At about the same time I investigated using NxOgre, a library to integrate the Ogre 3D graphics engine with PhysX. I found that PhysX was well enough documented and easy enough to use directly, while NxOgre was missing huge chunks of documentation and it was very confusing and unclear in those cases. I pretty much decided NxOgre was a solution in search of a problem, so dropped it and went with straight PhysX.
I first investigated the 3D modelling plugins. Unfortunately, they turned out to be buggy incomplete messes that were not up to production quality for a serious game. A programmer can use them perhaps, but they would never suit artists. So I was left to my own devices to come up with a physics entities exporting scheme. I wasn’t that upset about it, since nobody else has working plugins either, except Havok, which is half a million dollars + royalties. Compared to free, I’ll just write my own system. For my simple needs it’s only a day or two of work. This may be a problem for others though, especially if you plan to model physics based animation, ragdolls, or joints. If I were going with ODE instead, I could have potentially used the Sythe Physics Editor
As for the library itself, I made a lot of progress. In only two days I went from knowing nothing at all to being able to fly my ship around in the game. You can code straight from the documentation and to get started you don’t miss not having the source. Things generally work the way the documentation says they will, and I didn’t encounter too many problems where things just didn’t work and I had no idea what to do. Overall, PhysX is easy to use and well-documented.
Their architecture is based around multithreading, or offloading processing to a Physics card. This is a really nice performance feature because you take advantage of multi-core processors essentially for free. You simply lock the physics scene, send your inputs, and then unlock the physics scene. This is mostly transparent to the user, and I have to qualify that as mostly, because quirks do come up.
One quirk is that it’s very slow to do conditional evaluation of collision. For example, in my game I have force fields that only your own team can fly through. Other teams just bounce off as if they were a wall. It took me hours to figure out deal with their collision filter system to hack up a scheme to do this. Multithreaded callbacks are supported, but discouraged. The collision filter system uses logical operations with bitfields (that you set) to figure out what is collidable or not. I was able to get it to work with my scenario, but with more complicated games I don’t think it’s sufficient.
Another quirk is your updates are not immediately reflected. If I add rotational thrust to an object, and immediately check the orientation, the orientation will be the original, and not updated orientation.
The multithreaded quirks are understandable and as long as you know what kind of issues to expect they won’t be a problem.
I’ve used 3 major features of PhysX so far: joints, triggers, and the material system. These aren’t all the features, just the ones I’ve used.
Their joint system is good and easy to use for basic stuff. There is over a dozen joints available, including limit planes, springs, motors, breakable joints, spherical joints, pully joints, and 6 degree of freedom joints. As long as you stick to their samples you can get joints in your game very quickly. However, for more complex scenarios, especially with 6 degree of freedom joints, I was so confused at times I was about to have a nervous breakdown. This is one of those cases were the code would have been less confusing than the documentation because their explanations are very round-about, lack detail and precision, in some cases wrong, and the samples do things that just make no sense. It took me 3 14 hour days of grinding and head pounding just to figure out how to get an object to freely translate and at the same time be able to roll on one local axis.
Their trigger system is good. You can attach massless shapes to actors and then get callbacks through an interface. You can attach your own userdata to both the shapes, and the actors (which are made of ships). Because triggers are based on shapes, you can get triggers for not just spheres but all the kinds of physics primitives they support. I’m using their trigger system to maintain nearby object lists for network culling.
Their material system is very good. Unlike Newton, which only supports an explicit table, you can define basic parameters of a property (bounciness, friction) and then specify how that material interacts with other materials (add, multiply, smallest, largest, and others). You can also define a specific table if you want. You can also define what kind of materials collide with other materials, up to 32 types. So for example I have it so bullets do not collide with powerups, but spaceships do (so they pick them up). You can get callbacks for collisions as well.
If I have one major complaint with PhysX, it’s support. It’s free, so it’s not fair for me to complain too much, but at the same time I need to get my game done and busting my head spending 3 14 hour days just to get something to roll isn’t something I can afford to do too often. The forums have very little activity, and while I’ll give the admins there credit for trying to help, so far all their answers have been unhelpful or wrong and made me lose even more time. This is another case where I would have been better off going with ODE, since it has more forum activity and I would have been able to just look at the source. I’m not sure if paid support or paying for source code access is an option.
In conclusion, I think PhysX is worth investigating for the $75,000 to $1 million niche. At this level there’s enough money and time to make it worthwhile to figure things out, and performance, feature set, and quality are important enough lesser solutions can’t be counted on. Over 1 million, I would require real support and source-code (such as with Havok). Under $75,000, time is too important and I’d go open source (ODE) instead.
*** Edit ***
I was told that full-source and support are available to large projects. In this case, I think PhysX can be a good, much more affordable, solution to Havok and it is worth looking at both of them.