I just decided it myself.
I found an example of how to accomplish this in the downloadable source code associated with this article:
http://www-cs-students.stanford.edu/~eparker/files/PhysicsEngine/
In particular, the WorldState.cs file starts at line 221.
But the idea is that you assign all static objects with a level of -1 and with each other an object with a different level by default of -2. Then for each collision with bodies at level -1, you add the body into which it collided, and list it at 0.
After that, using the while while loop (list.Count> 0), check the bodies that encounter it and set the levels there to body.level + 1.
After that, for each body in the simulation that still has a default level (I said -2 before), set its level to the highest level.
There are a few more minor details, but looking at the code in the example will explain this better than ever.
Hope this helps!
Corresponding code from Evan Parker's code. [Stanford]
{{{ // topological sort (bfs) // TODO check this int max_level = -1; while (queue.Count > 0) { RigidBody a = queue.Dequeue() as RigidBody; //Console.Out.WriteLine("considering collisions with '{0}'", a.Name); if (a.level > max_level) max_level = a.level; foreach (CollisionPair cp in a.collisions) { RigidBody b = (cp.body[0] == a ? cp.body[1] : cp.body[0]); //Console.Out.WriteLine("considering collision between '{0}' and '{1}'", a.Name, b.Name); if (!b.levelSet) { b.level = a.level + 1; b.levelSet = true; queue.Enqueue(b); //Console.Out.WriteLine("found body '{0}' in level {1}", b.Name, b.level); } } } int num_levels = max_level + 1; //Console.WriteLine("num_levels = {0}", num_levels); ArrayList[] bodiesAtLevel = new ArrayList[num_levels]; ArrayList[] collisionsAtLevel = new ArrayList[num_levels]; for (int i = 0; i < num_levels; i++) { bodiesAtLevel[i] = new ArrayList(); collisionsAtLevel[i] = new ArrayList(); } for (int i = 0; i < bodies.GetNumBodies(); i++) { RigidBody a = bodies.GetBody(i); if (!a.levelSet || a.level < 0) continue; // either a static body or no contacts // add a to a level bodiesAtLevel[a.level].Add(a); // add collisions involving a to a level foreach (CollisionPair cp in a.collisions) { RigidBody b = (cp.body[0] == a ? cp.body[1] : cp.body[0]); if (b.level <= a.level) // contact with object at or below the same level as a { // make sure not to add duplicate collisions bool found = false; foreach (CollisionPair cp2 in collisionsAtLevel[a.level]) if (cp == cp2) found = true; if (!found) collisionsAtLevel[a.level].Add(cp); } } } for (int step = 0; step < num_contact_steps; step++) { for (int level = 0; level < num_levels; level++) { // process all contacts foreach (CollisionPair cp in collisionsAtLevel[level]) { cp.ResolveContact(dt, (num_contact_steps - step - 1) * -1.0f/num_contact_steps); } } } }}}
mu-kow
source share