[SOLVED] Check if rigidbody intersections are resolved

Post Reply
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

[SOLVED] Check if rigidbody intersections are resolved

Post by benelot »

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?
Last edited by benelot on Tue Aug 18, 2015 1:28 pm, edited 1 time in total.
johnsonalpha
Posts: 73
Joined: Fri May 01, 2015 8:23 pm

Re: Check if rigidbody intersections are resolved

Post by johnsonalpha »

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
}


}
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: Check if rigidbody intersections are resolved

Post by benelot »

Oh, thanks a lot for your answer! I will try that out.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Check if rigidbody intersections are resolved

Post by drleviathan »

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.
benelot
Posts: 350
Joined: Sat Jul 04, 2015 10:33 am
Location: Bern, Switzerland
Contact:

Re: Check if rigidbody intersections are resolved

Post by benelot »

@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

Code: Select all

gContactProcessedCallback = processContactCallback;
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.

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;
}
Post Reply