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 : [email protected] Unsubscribe : https://launchpad.net/~yade-dev More help : https://help.launchpad.net/ListHelp _______________________________________________ yade-dev mailing list [email protected] https://lists.berlios.de/mailman/listinfo/yade-dev
