Problem inside addContactPoint

AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Problem inside addContactPoint

Post by AlexSilverman »

Hello,

I found a problem within btManifoldResult::addContactPoint. I'm working on manipulating the friction for the contact by changing the values in the newly added contact point that is passed to my ContactAddedCallback. The problem is that I never see any changes, even when setting the combined friction to 0. This can be seen if you alter the ConcavePhysicsDemo so that the CustomMaterialCombinerCallback assigns zero to the combined friction. The blocks still appear to have friction. This is a bit easier to notice if you replace the jagged mesh ground with a simple box shape, but the effect is the same.

I think I've narrowed down the cause of this as well. Inside btManifoldResult::addContactPoint, the contact point is added, then the user callback is called, in which the contact point can be altered. The problem is that the internal cache of contact points are copies of the contact points that get created in btManifoldResult::addContactPoint, so any changes made to the new contact point inside the callback are lost. I have resolved this by passing the callback a reference to the contact point held in cache, rather than the local copy that was created. In order to reference the contact point properly, I had to change btPersistentManifold::AddManifoldPoint() to return the index at which the point was added. I have attached a patch that makes the necessary changes.

- Alex
You do not have the required permissions to view the files attached to this post.
ryanjuckett
Posts: 13
Joined: Tue Mar 11, 2008 9:04 am

Re: Problem inside addContactPoint

Post by ryanjuckett »

I also modify contact point data in the callback, and there is another case that won't be handled properly in your example. If you were to modify the positions of the bodies from within the callback, the cached transformations are not updated. I have changed my addContactPoint() function to perform the call back before adding the point and to reevaluate the transforms.

The end of my version of the function looks like this:

Code: Select all

   //BP mod, store contact triangles.
   newPt.m_partId0 = m_partId0;
   newPt.m_partId1 = m_partId1;
   newPt.m_index0  = m_index0;
   newPt.m_index1  = m_index1;
	
// RYAN JUCKETT: moved from below and added line to reevaluate body transforms
#if 1
	//User can override friction and/or restitution
	if (gContactAddedCallback &&
		//and if either of the two bodies requires custom material
		 ((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
		   (m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
	{
		//experimental feature info, for per-triangle material etc.
		btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
		btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
		(*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);

		// recache body transforms incase they were modified in the callback
		m_rootTransA = m_body0->getWorldTransform();
		m_rootTransB = m_body1->getWorldTransform();
	}
#endif

	///todo, check this for any side effects
	if (insertIndex >= 0)
	{
		//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
		m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
	} else
	{
		m_manifoldPtr->AddManifoldPoint(newPt);
	}

// RYAN JUCKETT: moved
#if 0
	//User can override friction and/or restitution
	if (gContactAddedCallback &&
		//and if either of the two bodies requires custom material
		 ((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
		   (m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
	{
		//experimental feature info, for per-triangle material etc.
		btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
		btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
		(*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
	}
#endif
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Problem inside addContactPoint

Post by AlexSilverman »

Ryan,

I initially tried switching the order, as you did, and I got a bunch of missed collisions for some reason, but if you're using it this way with no problems then we can just assume I had some other problem in my setup :)

I added your assignments to the root transforms after the call to the ContactAddedCallback. I'm wondering if there was a reason that in the original code, the contact point is added before the callback is called? If there's no detriment to doing things this way, then your change certainly carries with it a smaller change to the existing code than mine does.

Thanks.
- Alex
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Problem inside addContactPoint

Post by AlexSilverman »

I've wrapped your change into my own and made a new patch on the most recent SVN (as of 2008.05.06), revision 1155.

- Alex
You do not have the required permissions to view the files attached to this post.