Hi,
Is there a way to check if all rigidbody interpenetrations are resolved? I randomly define "creature bodies" out of boxes and joint constraints and therefore create a lot of crap creatures. The main problem is that I add too many boxes in one place to that they interpenetrate a lot. So far so good, some of them can be resolved by the solver, whereas others can not be resolved.
How can I find out about remaining interpenetrations? Or can I find this out per constraint if they are ill-defining the constraint system so that there is no solution anymore?
[SOLVED] Check if rigidbody intersections are resolved
-
- Posts: 350
- Joined: Sat Jul 04, 2015 10:33 am
- Location: Bern, Switzerland
[SOLVED] Check if rigidbody intersections are resolved
Last edited by benelot on Tue Aug 18, 2015 1:28 pm, edited 1 time in total.
-
- Posts: 73
- Joined: Fri May 01, 2015 8:23 pm
Re: Check if rigidbody intersections are resolved
In the bullet demos check out the EPAPenDepthDemo im pretty sure that deals with penetration and you can get the depth so you could maybe do something like
pseudo code
each step simulation
{
step dynamicsworld
if (penetrationDepth < 0.0){
// if penetrating
}
}
pseudo code
each step simulation
{
step dynamicsworld
if (penetrationDepth < 0.0){
// if penetrating
}
}
-
- Posts: 350
- Joined: Sat Jul 04, 2015 10:33 am
- Location: Bern, Switzerland
Re: Check if rigidbody intersections are resolved
Oh, thanks a lot for your answer! I will try that out.
-
- Posts: 849
- Joined: Tue Sep 30, 2014 6:03 pm
- Location: San Francisco
Re: Check if rigidbody intersections are resolved
I did some experimentation with one of the demos and I learned a few things:
A btManifoldPoint between two colliding objects has a data member called distance which is negative when the objects penetrate each other. However, for one box resting on top of a second box the distance will tend to be negative but very small (I was seeing numbers on the order or -1e-7). So, rather than check for distance < 0, you should probably only consider distances less than some negative threshold to be "penetrating".
There is a wiki page about collision callbacks and triggers which has information about how to perform a collision query for one object against the world. See the section about contactTest.
A btManifoldPoint between two colliding objects has a data member called distance which is negative when the objects penetrate each other. However, for one box resting on top of a second box the distance will tend to be negative but very small (I was seeing numbers on the order or -1e-7). So, rather than check for distance < 0, you should probably only consider distances less than some negative threshold to be "penetrating".
There is a wiki page about collision callbacks and triggers which has information about how to perform a collision query for one object against the world. See the section about contactTest.
-
- Posts: 350
- Joined: Sat Jul 04, 2015 10:33 am
- Location: Bern, Switzerland
Re: Check if rigidbody intersections are resolved
@drleviathan: Thanks for your really good solution! It nearly solves my problem completely. I am still trying to find a properly separating threshold. I still find some creatures that have interpenetrations that leads to heavy jittering that are not discarded well. But I found that a margin of -1e-3 is pretty good for me. A threshold of -1e-7 is too little for me as it discards some creatures that actually have no jittering. But thanks for your hint, it solves the problem up to some misclassifications, but that is not a big problem.
Below is the ContactProcessedCallback I wrote. It is important that one should not forget to set
at some point in the code, otherwise the function will not be used. Think of the LimbModel as a limb of a creature. I check if the collision partners are both limbs, if they are I sum up the interpenetration depth of a limb with other limbs. Thereby I get numbers that tell me how heavily interpenetrating the limbs are. By that filter, I only get interpenetration numbers for creatures that jitter in my simulation. I hope somebody with a similar problem can solve the problem similarly. Just write to me if something is unclear.
Below is the ContactProcessedCallback I wrote. It is important that one should not forget to set
Code: Select all
gContactProcessedCallback = processContactCallback;
Code: Select all
bool processContactCallback(btManifoldPoint& cp, void* body0, void* body1) {
LimbModel* limbModel1 = NULL;
LimbModel* limbModel2 = NULL;
btCollisionObject* o1 = static_cast<btCollisionObject*>(body0);
btCollisionObject* o2 = static_cast<btCollisionObject*>(body1);
//check if the collision partners are limbs
if (o1->getUserPointer() != NULL) {
limbModel1 = static_cast<LimbModel*>(o1->getUserPointer());
limbModel1->activateTactioceptors();
}
//check if the collision partners are limbs
if (o2->getUserPointer() != NULL) {
limbModel2 = static_cast<LimbModel*>(o2->getUserPointer());
limbModel2->activateTactioceptors();
}
double threshold = -1e-3;
// if both were limbs (not ground or anything else)
if (limbModel1 != NULL && limbModel2 != NULL) {
if (limbModel1->getJointIndex() != limbModel2->getJointIndex()) {
// std::cout << "Interpenetration depth:" << cp.getDistance() << std::endl;
if (cp.getDistance() < threshold) {
limbModel1->setInterpenetrationDepth(
limbModel1->getInterpenetrationDepth()
+ cp.getDistance());
limbModel2->setInterpenetrationDepth(
limbModel2->getInterpenetrationDepth()
+ cp.getDistance());
}
}
}
//ignore according to the documentation.
return false;
}