In last few months I had suspicious problems of bodies that obviously
didn't interact even when physically overlapping (one going through
another). As a result of me writing from scratch InsertionSortCollider,
thinking that PersistentSAPCollider might be wrongly detecting contacts,
I have the following conclusions for interactions:
1. Some colliders (jsut 2: InsertionSort and PersistentSAP, which uses
the same algo but is slower ;-) ) only see interactions when either the
AABB's didn't overlap in last step and now do, or the other way
(inversion in the ordering, using the computing terminology).
2. For non-cohesive interactions (those that should exist only if there
is overlap of bodies, therefore of AABBs), we used to delete interaction
by saying I->isReal=false. That returns the interaction back to
potential state, as the collider will set I->isNew=true. If there is
again real overlap, the InterGeom and InterPhys functors will create the
interaction again. If there is no overlap, the collider will delete the
interaction for good at the point the AABBs don't overlap anymore.
3. For cohesive (that is, possibly distant) interactions, this doesn't
work anymore. Suppose a constitutive law wants to delete an interaction
when normal elongation of the contact exceeds some positive value (think
tensile damage). If you use I->isReal=false, then the interaction falls
to the potential state. Now: if the AABBs don't overlap at this point
anymore, the interaction will be in the potential state possibly
forever, since the collider will never see such interaction again, as
the AABBs have already separated _before_ the contact was marked
isReal=false. This slows down the computation by keeping useless
interactions around. (PersistentSAPCollider has an extra loop over
interactions, that detects such cases; but it slows down).
4. If I set I->isReal=false, it doens't follow that the collider will
also set I->isNew=true, as it will not see the interaction unless AABBs
enter/quit the overlap. I->isNew is NOT always equal to
(bool)I->interactionPhysics or (bool)I->interactionGeometry: a once
existing interaction, after setting I->isReal=false, will still have
I->isNew=false. If geometry/physics functor sees such interaction, it
will only UPDATE (not create a new) geometry and physics for the
interactions, i.e. using values of internal variables from the
interaction before!
The solution I created is to hint the collider that an interaction is
not needed anymoer and let it decide whether to really erase it or what
else to do. Instead of saying I->isReal=false, you call
interactions->requestErase(id1,id2) and the collider will, at the next
step, look at the pair; if there is still AABB overlap, the interaction
is kept as potential; if there is no AABB overlap anymore, it will
delete the interaction for good. Then the list of interactions to delete
is cleared. (this solves point 3.)
Moreover, interactions->requestErase will call Interaction::reset()
which will make sure that interactionGeometry, interactionPhysics,
isReal, isNew, ... are reset to the initial state of an interaction that
was never real. (this solves point 4.)
(At this point, I think we are ready to remove haveDistantTransient flag
from the colldiers.)
I will try to go through the code to erradicate all occurences of
isReal=false and such. Maybe we better get rid of isNew as well, instead
of having to keep it in sync with (bool)I->interactionPhysics and (bool)
I->interactionGeometry all the time?
Best regards, Vaclav
_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to : yade-dev@xxxxxxxxxxxxxxxxxxx
Unsubscribe : https://launchpad.net/~yade-dev
More help : https://help.launchpad.net/ListHelp