an older physics comparison posting at another forum

Post Reply
johan
Posts: 1
Joined: Thu Mar 16, 2006 6:12 pm

an older physics comparison posting at another forum

Post by johan »

There is a quite long comparison posting here by IxianEngineer. It mentions features for several physics engines.
http://bookofhook.com/phpBB/viewtopic.php?t=259

xianEngineer wrote: --------------------------------------------------------------------------------

There are several physics engines:
Commercial:
-Havok (H)
-RenderwarePhysics (formely known as Karma from MathEngine) (R)
-Novodex (N)
-Meqon (M)
Free (w/o sources):
-Tokamak (T)
-Newton (PhysicsEngine) (P)
Free (with sources)
-ODE (O)

I worked only with H but even then - I'm not a physics programmer For others, I looked through docs/forums/samples and tried to play a bit (exept R, that I dont know at all). From my little experience, H is the best (but probably most expensive too).
N and M seem to be interesting, they are improving, have companies behind them - with release schedules, support, docs, samples etc. In a few more iterations they might become strong competitors for H (assuming they will be lower priced:)
T and P seem to have some limits that makes them more fit for demos, not complex games. Their docs or samples are not complete and I have no idea when (or if) we can expect improvements.
O is unfortunately does not seem to be usable in its current state, and it's future is IMHO unclear.

So what would I expect from the physics/collision engine (and some comparison of N and T)?

1. dynamic rigid bodies, made of (collection of) simple shapes. Both N and T support box, sphere, capsule, convex. Use of arbitrary triangle meshes as dynamic moving bodies is probably a bad idea anyway - too expensive.

2. static (not moving at all) and keyframed (like a moving platform or crane - "infinite" mass, they push dynamic bodies but are not pused themselves) bodies. Typically, made of arbitrary triangle meshes or lists of boxes, but can be simple shapes too. Typical object - building, bridge, tunnel - often has more then 100 triangles (sometimes up to 300+) and sometimes more then 50 boxes, colliding with all of them just "as a list" is too slow, so engine must have some optimization algorithm (something like space partitioning) "on top" of the list. Just an example: character's shape (typically - box or capsule) moving along the wall of a building made out of several-hundred triangles might take as long as 3 msec to compute (PS2). If there is an optimized structure on top of mesh, it might be 0.3 msec.
H has MOPP - memory optimized partial polytope. Whatever this thing is, it works and it's extra data takes very small amount of memory. Also, it works not only on top of tri meshes, but on top of lists of boxes, farther reducing memory consumption and increasing speed. It might not be obvious, but boxes are better then triangles in many cases (they are not much more expensive on low level then triangles, but you can usually have several times less boxes then triangles!).

It is not clear what kind of optimization is used in N for mesh - simple shapes or convex collision. For mesh - mesh collisions, N has something called pmesh. From what I read in the docs, it works only with closed meshes and does some "voxelization" stuff, that takes memory. Also, it is accurate only for highly tesselated meshes.

In T, static/kinetic bodies can only be made from the same simple primitives as dynamic ones, but there is also one single mesh that can be set as "terrain". It does not have to be a heightfeild, can be any mesh (even non connected and non projective - so it can be anything, not level's "terrain"). It is unclear what (if any) optimization method used for it. There were questions about it on the T forum, but they were not answered. There is a callback that allows user to collect triangles within min/max boundary when engines asks for it - so to some extent it is possible to have your own optimizations (if you want to do all the work IMHO - this "single mesh" approach does not work well for games that create objects dynamically - as you go through the level. Also, there are several complains on the forum about mesh collision being buggy - especially with large numbers of triangles - but I dont know if it is really so or not.

3. height field for terrain. If optimized mesh is fast enough - can use this, but note that terrain can be large (say, 512x512), and so stored as compressed height field, not general tri mesh (modern graphics shaders allow as compact as 1 byte/vertex storage + some small per patch overhead).

H just allows the game to supply a callback "float GetHight( int x, int z )" this is IMHO the best approach.

N terrain mesh is basically tri mesh. Does not have to be regular - but have to be projective. The difference with tri mesh - the space below considered to be "occupied", so even fast moving objects will not "pop through". Again, exact optimization is not known.

As mentioned in 2 - everything that is static in T is "terrain".

4. joints (with joint limits) for 2 bodies. Ball, hinge, slider, prizmatic. Some joint break criteria. Motors.

N has all + "point on line", "point in plane" and ability to set spring/damper for a joint. In addition to limits specified as min/max angle (or couple of them - for ball) around some axis, N also has a more generic way - by specifying limiting point and bunch of planes. N also has support for motors. Break limit can be set for Joints, and a function will be called when it is exceeded.

T supports ball, hinge and maybe some slider (not sure - docs unclear). Looks like limit parameters are restricted to min/max angle (2 angles for ball) - no arbitrary limit planes. Some motors supported - but probably only for hinge (?). There are joint controllers... I thought they would allow implementation of joint breakage, but from the T forum, it looks like T does not provide all required data fot it at the callback (?). A function for setting some damping factor for joint provided (but no docs or use samples?)
There is also another type of "breakage" in T (it has nothing to do with joints though) - in a rigid body made of several shapes, a shape can break when collision force is greater then specified, and new rigid body will be automatically created (with this shape). So we have kind of "fixed" joint with break limit.

5. collision filtering. "collision layers" and/or some (callback-based ?) approach for a object pair.

Specifying what objects can collide with what is very important - for peformance and sometimes for gameplay reasons. For example, we used it for making a separation between those bodies we need for physics and those we need for some LineOfSite/LineOfFire (essentially - ray casts) tests. Say, a car might have 2 rigid bodies: one simple (a convex or a very few boxes) - for physics collision, and one more complex (axtual tri mesh or bigger box list) - for testing LOF. The "LOF body" would be key-framed to position of "physics body". Flags exclude LOF body from physics calculations and physics body from LOF checks. Same for some static objects - you might want more details for bullets, but not for physics, or making glass/fences transparent for LOS but not LOF checks.

N supports 32 collision groups (object can belong to a single group, and entries in a 32x32 "table" of collisions can be specified). It also supports disabling collision for pairs of bodies (I wonder how it cam be done efficiently... some hash table?).

T seem to have similar group filter, and it probably allows more then 32 groups... it is unclear if it can be more then 64. It does not have direct per-pair filter. For the group filter, T allows not only to allow ot ignore collision, but also to call a callback (it is not clear if callback is allowed to change passed collision point data?).

6. Ray casting (with all the collision filtering - see above). Ray testing version (faster, "early out" version - with true/false result only and no computed collision info). Finding closest collision versus all collisions, callback to allow to ignore some bodies (for example, not shotting self or your own weapon, even if starting bullet point happened to be a bit inside).

N has all test/closest/all versions, allows specifying what groups to cast, and even allows to cast AABBs only or actual shapes. There is only a callback in "find all" mode (and it allows to terminate farther collision tests). So if you want closest collision (or just ray test) but want to exclude "self obstacle", you will have to use "all" mode... to say nothing about actually computing self-collision. But the thing that puzzles me (I hope I dont understand something!) is how ray end point is specified? It looks like the ray has start point and normalized direction... Where is end point? Obviously, infinite rays are a significant performance loss and they are almost never needed in practice anyway...

T does not have ray-casting... it has "sensors". Sensors are essentially rays, attached to rigid bodies (those that are dynamic, not static). At least, direction does not seem to be unit length, so maybe finite rays possible. But no filtering. Also, the collision info for sensor is available only inside some rigid body simulation callback, making it not an "instant" call (?), so much needed for AI etc. All this makes ray casting in T unusable (?).

7. "Shape casting". Almost always overlooked but very important for AI feature. It is possible to do it in H - though even in H it required some minor coding - mostly writing custom callbacks. M is planning on adding similar support in the future. Need to be able to place a simple shape (AABB, OBB, sphere) and get collision point, separation normal, penetration depth. Same as with rays - test only/closest (in this case - deepest penetration) versions, filters, excluding obstacles with some callback or something.
AI uses it to figure out dynamic avoidance and lots of other things. For example, AI character checks a box somewhat in front of itself... if collision, it begins to check boxes in a clock wise order around it with some angle between them... when something free found, it might do another cast(s) between occupied and free positions to improve presicion for it's new direction of movement. Note, that this is "immediate" call (as ray casts) - the results needed immediatly, not at the next simulation step or as a callback from it. This functionality essentially requires 2 things: "broad phase" collection of potentially intersecting bodies with AABB (or whatever else engine is using) of the "cast" shape, and more presice "narrow phase" shape-body collision detection. Also note, that as the calls are kind of random, so probably no between-frame coherence can be used, potentially making such calls slow - but I dont know how to solve this problem.

This feature does not seem to be implemented in N and T. I'm not sure what hacks can be used instead (?)

8. "Phantom" shapes and triggers. "Phantoms" are somewhat similar to shape casting... they report contacts of a simple shape with world, while no forces is applied. But shape casting is "random" query while phantom exist for many frames, so can use interframe coherence. Phantoms are generally faster, but sometimes shape casting is hard to avoid. Triggers are more obvious static things generating Enter/Stay/Leave events.

N has triggers. No Phantoms directly supported though (maybe can be done with notifications and some custom force application callback, that does not apply any force to/from phantom?).
T does not seem to have this functionality.

9. Events (contacts points, joint breakage etc).

In N, there are contact (start/touch/end) notifications, joint breakage notifications.
In T, there is a collision callback. No joint breakage (but "shape breakage" - see above).

10. Materials. Specifying restitution/friction coefs etc. Some kind of material table.

N has a material table. Shape or individual triangle can have a 16-bit index into it. Material support static/dynamic friction, restitution. Interesting, that there seem to be support for anisotropic friction (you specify direction of anisotropy, and it will be converted by shape's matrix to world space during calculations). There seem to be lots of extensions not implemented yet, but planned (different material combination modes for 2 interacting objects, moving surfaces, spin and roll friction coefs).

T has 32- bit indices (somewhat of a waste). "Material" is friction and restitution coefs.

11. Reliable, fast solver, capable of handling large worlds.

I'm leaving actual math considerations out of here

N demos look good, T demos look good too (even though they do not have complex scenes).
It is kinda funny, that all the 20-levels high stacks and lots of other demos are not really needed for games... What would be cool is to have variable number of characters and cars, helicopters on a hilly terrain and inside city-like environment... - something much closer to what is really needed...

12. Lots of engine (crucial!) optimizations and variables: collision tolerence, body activation/deactivation criteria, number of iterations, broad phase collision algorithm tuning (including sweep/prune AABB, AABB/OBB or whatever else), use of between-frame coherence inside engine for collision detection, ability to have custom memory allocator and internal default fast allocator for small objects, visual debugging.

N allows to set separatoin distance (tolerance within wich interpenetrating objects will not be pushed apart), sleep linear/angular velocities threshold, bounce velocity threshold (will not bounce below that), maximum angular velocity to prevent instability with very fast spinning. It also provides some scaling for penalty force and static/dynamic frictions - not sure how usefull are they.
Solver defaults to 4 interations. Interesting, that number of iterations can be requested per body.
Joints can be simulated with Lagrangian or some "reduced" method... there are some restriction on what can be done with what - see headers...
For broad phase, there is a choice of just O(n*n) method ("for debugging"), some O(n) method that uses some space partitioning, and another O(n) method that also uses temporal coherence. It is not recommened in the doc to change default setting though, so consider it as one method
N allows to overwrite memory allocator, error reporting, has a visualizer (user can supply simple actual render functions, default OpenGL implementation provided).
There is some built-in performance reporting.

T has some sleeping parameter... but I have no idea why it is only one value and in what units/what for it is (?). Interesting, that it is per body, not per scene. Also, accuracy (error threshold) and number of iterations can be specified per join. I'm not sure where/how collision tolerance is specified and what kind of collision used on broad phase (?).
T allows to overwrite memory manager, has some performance reporting and some error logging that can be overwritten. Some initial values for number of rigid bodies, body controllers, shapes, constraints, overlapped pairs etc must be specified. I'm not sure what the behavior is when those limits reached... will it allocate twice the initial amount, or use some allocation step or will not allow to create body at all? Docs on this do not exist.

13. Vehicle module. Ready to use "raycast vehicle" (casts rays from each wheel, drives on whatever support was found). Suspension parameters.

No "pre-maid" vehicles in N and T. Both have some vehicle samples though.

14. Documentation, samples. Last, but not the least!

N has nice overview doc, well commented headers, samples.

One of the major problems of T - documentation is far from being complete, headers are not well enough commented, questions on forums not always answered.


Comments, error fixes etc are welcome!
Post Reply