[ODE] Autodisable collision detection
Oles V. Shishkovtsov
oles at gsc-game.kiev.ua
Fri May 28 13:52:20 MST 2004
Hello Joe,
Friday, May 28, 2004, 12:31:39 AM, you wrote:
>> Hello Joe,
>>
>> This is exactly the same thing as we do in S.T.A.L.K.E.R. :)
>> And I have to admit it works really well, so it is proven to work.
>>
>> And another one thing to note: enabling can be done at collision
>> level, that way you don't have any issues with bodies enabled after
>> collision phase and missing contact info for one physics step.
JA> Hi Oles,
JA> This is exactly the issue I am having right now with autodisable.
JA> When I don¹t do collision detection between two disabled bodies in the
JA> wallstack no joint is created. Thus the objects miss out the contact joint
JA> for one physics step, which makes the stacks wave up and down and never come
JA> to rest.
JA> You can see the problem at work by adding the following code inside
JA> nearcallback of test_crash.cpp:
JA> if (b1 &&b2)
JA> {
JA> if (!dBodyIsEnabled (b1) && !dBodyIsEnabled (b2))
JA> return;
JA> }
JA> Oles, how exactly did you solve this issue? Can you share the code that does
JA> it?
We use enabling at collision level. But to make everything clear, I
should state that we don't use any ODE collision related stuff. We do
use solvers only.
So, the outline:
* two lists: active and inactive bodies
iterate on active
perform query (approximate)
perform collision (exact)
if disabled body in contact -> move it to the end
of active-list
end-of-collision-phase
* so, there is no "broad phase" in ODE ideology
* the above "query" means access to DB for dynamic stuff
* the DB is organized in a way similar to "loose-octree", but it has no
geometric size and fully dynamic by nature + pretty fast at perfoming
approximate queries like "does something intersect this volume".
And another note: this way you don't need islands at all except for
classical big-matrix solver.
JA> As far as I can see there are two ways of solving it:
JA> - persistent contacts for disabled bodies
JA> When two bodies get disabled. A persistent contact joint is generated and
JA> stored in a separate joint group.
JA> The problem I see is that its hard to get right in a general way and has
JA> many pitfalls eg. What happens if you move a static collider. There is no
JA> way to find that out and remove the static collider in a general way.
And another one: memory usage (but I don't think this is relevant to
ODE's common users).
JA> - enabling at collision level.
JA> When a collision between a sleeping and awake body happens the sleeping body
JA> is enabled and is stored in a list.
JA> After collision detection is done. All bodies in the list are collided
JA> against all disabled bodies again, to see if they penetrate any other
JA> disabled bodies.
JA> This has to be done iteratively until no bodies became enabled.
JA> I am not sure if it is necessary to iterate at all but it sure seems
JA> (I am not sure if this is actually necessary, but it seems more correct.)
JA> Anyway while that seems like a viable solution, to me it seems that the
JA> usage of ode just gets a lot more complex in order to get autodisable
JA> running with the full benefit.
JA> Because what you need to get it running is:
JA> A) 2 callbacks when a body gets enabled/disabled, which moves two bodies
JA> from an enabled space to an disabled space.
JA> B) You need to call dSpaceCollide on the enabled space and dSpaceCollide2 on
JA> enabled/disabled spaces.
JA> C) You need to iteratively enable bodies that are colliding with through
JA> collision detection enabled bodies.
JA> To me it seems that this functionality should be moved more into the spaces.
JA> So a user doesn¹t have to bother about all this. He just gets optimal
JA> performance for sleeping bodies out of the box.
JA> Any ideas?
JA> Are there simpler ways to get this working properly?
JA> Joe Ante
JA> www.otee.dk
--
Best regards,
Oles V. Shishkovtsov
GSC-Game World
oles at gsc-game.kiev.ua
More information about the ODE
mailing list