Bug with wrong normals on edges in btBvhTriangleMeshShape

Post Reply
Pacha
Posts: 26
Joined: Sat Jun 15, 2013 2:29 am

Bug with wrong normals on edges in btBvhTriangleMeshShape

Post by Pacha »

Video of the bug:
https://www.youtube.com/watch?v=VCtwTpABrQo

I have the following situation, a couple of btCollisionObjects, and a btRigidBody. When the btRigidBody is falling vertically without horizontal speed, the normals are calculated wrongly and it gets through the collision objects on the edges. There are 2 normals in the contact manifold (btManifoldPoint) with inverse normals (0, -1, 0), and it passes through the collision object (see the video for reference). This only happens when falling at a relative high speed and crashes in a place with an edge, and sometimes when jumping at the same spot with edges vertically. It works well when not touching the edges when falling.

You can see in the video, top left, the normals (inverted ones when falling through, normal ones when no bugs). I am using btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK on all my bodies, and this is my gContactAddedCallback function:

Code: Select all

static bool CustomMaterialCombinerCallback(btManifoldPoint& cp,	const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{
	
	btAdjustInternalEdgeContacts(cp,colObj1Wrap,colObj0Wrap, partId1,index1);
	//if (enable)
	{
		//btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE);
		//btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED);
	}

	float friction0 = colObj0Wrap->getCollisionObject()->getFriction();
	float friction1 = colObj1Wrap->getCollisionObject()->getFriction();
	float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution();
	float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution();

	if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
	{
		friction0 = 1.0;//partId0,index0
		restitution0 = 0.f;
	}
	if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
	{
		if (index1&1)
		{
			friction1 = 1.0f;//partId1,index1
		} else
		{
			friction1 = 0.f;
		}
		restitution1 = 0.f;
	}

	cp.m_combinedFriction = calculateCombinedFriction(friction0,friction1);
	cp.m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1);
	//cp.m_combinedFriction = calculateCombinedFriction(0.0,0.0);
	//cp.m_combinedRestitution = calculateCombinedRestitution(0.0,0.0);

	//this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction
	return true;
}
Does somebody know how to solve this before I report a bug? Thanks.
Post Reply