gContactDestroyedCallback issues

Singular
Posts: 13
Joined: Tue Sep 13, 2011 2:20 pm
Location: ru

gContactDestroyedCallback issues

Post by Singular »

Hey, guys. Need your help to point out stupid, probably irrelevant mistake. i use Bullet 2.78.
My problem is, obviously, ContactDestroyedCallback not being called.

Conditions:

Basic Init:

Code: Select all

   collisionConfiguration = snew btDefaultCollisionConfiguration();
	dispatcher = snew btCollisionDispatcher(collisionConfiguration);
	overlappingPairCache = snew btDbvtBroadphase();
	solver = snew btSequentialImpulseConstraintSolver;
	dynamicsWorld = snew btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);

	dynamicsWorld->setGravity(btVector3(0, Gravity, 0));
	[b]dynamicsWorld->getSolverInfo().m_solverMode = SOLVER_RANDMIZE_ORDER | SOLVER_USE_WARMSTARTING;[/b]

	gContactAddedCallback  = &sContactAddedCallback;
	gContactDestroyedCallback = &sContactDestroyedCallback;
then i create bunch of compound objects, add boxes\spheres to them as ChildShape's and add them to world as rigid bodies;
every rigid body has btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK flag set;

every simulation frame i check if(gContactDestroyedCallback != MyCallback), pointer is ok.
so , i apllied every fix i found on google but callback never fired. also, there's no demo featuring that functionality and no documentation. so..any ideas?
Last edited by Singular on Mon Oct 03, 2011 5:22 pm, edited 1 time in total.
User avatar
Dr.Shepherd
Posts: 168
Joined: Tue Jan 04, 2011 11:47 pm

Re: gContactDestroyedCallback not called with all known fixe

Post by Dr.Shepherd »

I think you can put your code in a executable file and we may have a small test, that's the best way
User avatar
Dr.Shepherd
Posts: 168
Joined: Tue Jan 04, 2011 11:47 pm

Re: gContactDestroyedCallback not called with all known fixe

Post by Dr.Shepherd »

Dr.Shepherd wrote:I think you can put your code in a executable file and we may have a small test, that's the best way
I don't mean a binary one, sorry, just to be clear, like a BasicDemo
Singular
Posts: 13
Joined: Tue Sep 13, 2011 2:20 pm
Location: ru

Re: gContactDestroyedCallback not called with all known fixe

Post by Singular »

i think, that would be ok: http://pastebin.com/jsvSQKSr
it's lightened version of initialization code(removed some internal routine and object positioning), i think, it's the only part that can affect problem? if no, i'll try to do modified basic demo.

also, gContactAddedCallback works fine and gContactDestroyedCallback contains only output to log file.
User avatar
Dr.Shepherd
Posts: 168
Joined: Tue Jan 04, 2011 11:47 pm

Re: gContactDestroyedCallback not called with all known fixe

Post by Dr.Shepherd »

hi, first, let's say I get the most information from this post:
http://bulletphysics.org/Bullet/phpBB3/ ... f=9&t=2243

Then I reproduce it in my own BasicDemo, as is attached in the file.

However, I don't quite understand why there should be such a gGlobalValue. I will dig it up in the future. Hope this could give some hints to you.

Code: Select all

int gGlobalValue = 42;

static bool sContactDestroyedCallback( void* userData ) {
   printf( "custom destroyed callback!\n");
   return false;
}

static bool sContactAddedCallback( btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0, int index0,const btCollisionObject* colObj1,int partId1,int index1 ) {
   cp.m_userPersistentData = &gGlobalValue;
   printf( "custom added callback!\n" );
   return false;
}
You do not have the required permissions to view the files attached to this post.
Singular
Posts: 13
Joined: Tue Sep 13, 2011 2:20 pm
Location: ru

Re: gContactDestroyedCallback not called with all known fixe

Post by Singular »

thanks for your effort, Dr.Shepherd. surprisingly, i don't think i can count this case as my mistake;
it seems totally undocumented and not mentioned in any post as required line or even explained anywhere.
after reading your basic demo modification without any hope i've just added line "cp.m_userPersistentData = &randomVariable;" into my contact added callback...and gContactDestroyedCallback now being called. i doubt it being called correctly(it doesn't seem like amount of added and destroyed contact points match);

i don't get, is m_userPersistentData a pointer i get as gContactDestroyedCallback argument? then why, i beg you why it is required to set it? or it has some meaning for bullet, then what is it for? it looks like just pointer storage for user.

P.S. dear admin, if you reading this, for the some mythical creature's sake get some volunteers from forum to update wiki. it's incredibly useless now: e.g. http://www.bulletphysics.org/mediawiki- ... d_Triggers here for callbacks vital conditions for them to work not mentioned. and no explanation of the code and most of the code has it's context(too much of context and no real explanation of it's lines\structure then needed, and variables defined outside of example code cause additional confusion), all code examples are pretty bad. Theyre readable without problems for someone who already knows how everything work, but not for someone who's trying to figure out.
User avatar
Dr.Shepherd
Posts: 168
Joined: Tue Jan 04, 2011 11:47 pm

Re: gContactDestroyedCallback not called with all known fixe

Post by Dr.Shepherd »

Seriously speaking, I am not quite sure how this userPersistentData works. Actually in my BasicDmo, I lost one line in the DestroyCallback:

Code: Select all

   btAssert( userPersistentData == &gGlobalValue );
After testing some values, this userPersistentData seems to be ok for any value, no matter you set it as 42, 21, 423, 5349 (Any as you like). And it is mutable:

Code: Select all

mutable void*   m_userPersistentData;
So I suppose it is something used only by USER and to specify the added and destroyed contact point are the same one !

Jesus, I don't quite understand it either. Currently working on these stuff, if I got more ideas, I will post it in the forum. Anyone knows it, please help.

Cheers.
Singular
Posts: 13
Joined: Tue Sep 13, 2011 2:20 pm
Location: ru

Re: gContactDestroyedCallback not called with all known fixe

Post by Singular »

ok, cp.m_userPersistentData is just a user pointer required to be not NULL; and gContactDestroyedCallback's argument is set by it, not by btRigidBody::setUserPointer();

But i still don't get how it works:

how should i determine for what pair of bodies gContactDestroyedCallback was called? in gContactAddedCallback, i supposed to set cp.m_userPersistentData to something that will help me determine that later. but what? wouldn't it be more straight forward to give 2 pointer storage for 2 bodies?
Singular
Posts: 13
Joined: Tue Sep 13, 2011 2:20 pm
Location: ru

Re: gContactDestroyedCallback issues

Post by Singular »

Code: Select all

bool sContactAddedCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
{
	int p1, p2;

	p1 = colObj0->getCollisionShape()->parentID; //Custom variables in btCollisionShape to store parent object ID for my class
	p2 = colObj1->getCollisionShape()->parentID;

	cp.parentID0 = p1; //Custom variables in btManifoldPoint created by me to store index of colliding objects 
	cp.parentID1 = p2; //for that particular point

	cp.m_userPersistentData = &cp;

	physObjects[p1].numContacts++;
	physObjects[p2].numContacts++;

	return 0;
}

bool sContactDestroyedCallback(void* userPersistentData)
{
	physObjects[static_cast<btManifoldPoint*>(userPersistentData)->parentID0].numContacts--;
	physObjects[static_cast<btManifoldPoint*>(userPersistentData)->parentID1].numContacts--;

	return 0;
}
Both of them called, all variables\pointers seem right, but resulting numContacts is not proper, it is always > 0 after object collided something(even if it is floating in the air, at the end of simulations it's pretty big number if object collided much). At this point, i have no clue wtf is wrong with it...
User avatar
Dr.Shepherd
Posts: 168
Joined: Tue Jan 04, 2011 11:47 pm

Re: gContactDestroyedCallback issues

Post by Dr.Shepherd »

Me either. I am trying to figure out how this works out, it takes sometime when there is little reference.

I am summarizing what I got, and after it is kind of ok, I will put it straight into the tutorials in the Wiki. It really feels aweful when the references are so little, and bullet is becoming more and more popular.
User avatar
Dr.Shepherd
Posts: 168
Joined: Tue Jan 04, 2011 11:47 pm

Re: gContactDestroyedCallback issues

Post by Dr.Shepherd »

I didn't try it out yet. But do you need to add and delete the number of contacts all by ourselves? Shoudn't bullet take care of this stuff ?
Singular wrote:

Code: Select all

bool sContactAddedCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
{
	int p1, p2;

	p1 = colObj0->getCollisionShape()->parentID; //Custom variables in btCollisionShape to store parent object ID for my class
	p2 = colObj1->getCollisionShape()->parentID;

	cp.parentID0 = p1; //Custom variables in btManifoldPoint created by me to store index of colliding objects 
	cp.parentID1 = p2; //for that particular point

	cp.m_userPersistentData = &cp;

	physObjects[p1].numContacts++;
	physObjects[p2].numContacts++;

	return 0;
}

bool sContactDestroyedCallback(void* userPersistentData)
{
	physObjects[static_cast<btManifoldPoint*>(userPersistentData)->parentID0].numContacts--;
	physObjects[static_cast<btManifoldPoint*>(userPersistentData)->parentID1].numContacts--;

	return 0;
}
Both of them called, all variables\pointers seem right, but resulting numContacts is not proper, it is always > 0 after object collided something(even if it is floating in the air, at the end of simulations it's pretty big number if object collided much). At this point, i have no clue wtf is wrong with it...
Singular
Posts: 13
Joined: Tue Sep 13, 2011 2:20 pm
Location: ru

Re: gContactDestroyedCallback issues

Post by Singular »

Umm...If it does, there are they stored? I think i could survive if i will know actual pair of objects only then they've collided;
Scheb
Posts: 2
Joined: Sat Jun 08, 2013 1:06 pm

Re: gContactDestroyedCallback issues

Post by Scheb »

Hi,

I guess you do not ask you anymore longer question (2 years after: p) but maybe some visitors like me will ask this question.
I'm beginner with Bullet and now I wanted to use as callbacks. It is true that bullet lacks some tutorials and examples (but it is our job to write it ;-), but I find that the source code of the engine is very clear.

Here is my conclusion from the Doxygen documentation:
gContactDestroyedCallback, typedef:

Code: Select all

typedef bool (* ContactDestroyedCallback) (
userPersistentData void *);
receives "userPersitentData" parameter. This is your user data. It will especially allow you, for example, to find the two objets that were in contact in your gContactDestroyedCallback. So yes, userPersitentData must be non-null. Else gContactDestroyedCallback is considered useless.

Regarding your code:

Code: Select all

p1 = colObj0->getCollisionShape()->parentID; //Custom variables in btCollisionShape to store parent object ID for my class
p2 = colObj1->getCollisionShape()->parentID;

cp.parentID0 = p1; //Custom variables in btManifoldPoint created by me to store index of colliding objects 
cp.parentID1 = p2; //for that particular point
Here you wish to find the class that owns your object.
You do not need to create these custom variables, Bullet already contains everything you need so that you can find your personal data.

The btCollisionShape may contain user data using get / setUserPointer.
Example usage to find parent class:

Code: Select all

class MyObjectClass
{
	public:
	uint numContacts; // Your numContacts variable

	// Somewhere where you create your collision shape
	void Example()
	{
		myCollisionShape->setUserPointer(this); // Add Just this line in your object class
	}
};


bool sContactAddedCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
{
   MyObjectClass* physObject = static_cast<MyObjectClass*>(colObj0->getCollisionShape()->getUserPointer());

   physObject->numContacts++;
   cp.m_userPersistentData = physObject;

   return false; // "If your function returns false, then Bullet will assume that you did not modify the contact point properties at all."
}

bool sContactDestroyedCallback(void* userPersistentData)
{
	MyObjectClass* physObject = static_cast<MyObjectClass*>(userPersistentData);
	physObject->numContacts--;

   return false;
}
PS: sorry for my English language skills .... I'm french ^ ^