Implementations of btCollisionShape::getAabb()

User avatar
Carsten
Posts: 14
Joined: Thu Sep 25, 2008 1:36 pm
Location: Germany

Implementations of btCollisionShape::getAabb()

Post by Carsten »

Hi all,

I have a question regarding various implementations of the btCollisionShape::getAabb() method (in Bullet 2.74).

The documentation about this method says
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
However, some derived classes implement this method like this (btHeightfieldTerrainShape is very similar as well):

Code: Select all

void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
	btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
	localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
	btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
	
	btMatrix3x3 abs_b = trans.getBasis().absolute();  

	btVector3 center = trans(localCenter);

	btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
		   abs_b[1].dot(localHalfExtents),
		  abs_b[2].dot(localHalfExtents));
	aabbMin = center - extent;
	aabbMax = center + extent;
}
This does not properly compute the aabb of trans(m_localAabb). In fact, you can end with too small results and even e.g. aabbMin.x > aabbMax.x, so I believe this implementation is wrong.
This one seems correct, from btSoftBodyInternals.h:

Code: Select all

	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
	{
		/* t should be identity, but better be safe than...fast? */ 
		const btVector3	mins=m_body->m_bounds[0];
		const btVector3	maxs=m_body->m_bounds[1];
		const btVector3	crns[]={t*btVector3(mins.x(),mins.y(),mins.z()),
			t*btVector3(maxs.x(),mins.y(),mins.z()),
			t*btVector3(maxs.x(),maxs.y(),mins.z()),
			t*btVector3(mins.x(),maxs.y(),mins.z()),
			t*btVector3(mins.x(),mins.y(),maxs.z()),
			t*btVector3(maxs.x(),mins.y(),maxs.z()),
			t*btVector3(maxs.x(),maxs.y(),maxs.z()),
			t*btVector3(mins.x(),maxs.y(),maxs.z())};
		aabbMin=aabbMax=crns[0];
		for(int i=1;i<8;++i)
		{
			aabbMin.setMin(crns[i]);
			aabbMax.setMax(crns[i]);
		}
	}
So my question, is the above code actually wrong, or is it me not comprehending something? :?:
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Implementations of btCollisionShape::getAabb()

Post by Erwin Coumans »

Code: Select all

This does not properly compute the aabb of trans(m_localAabb). In fact, you can end with too small results and even e.g. aabbMin.x > aabbMax.x, so I believe this implementation is wrong.
Can you explain how it is wrong, and why it is possible that aabbMin.x > aabbMax.x?

Or even better, can you create a small testbed that reproduces any wrong AABB calculated using that method?
Thanks a lot,
Erwin
User avatar
Carsten
Posts: 14
Joined: Thu Sep 25, 2008 1:36 pm
Location: Germany

Re: Implementations of btCollisionShape::getAabb()

Post by Carsten »

Argh!! I'm very sorry - my fault! :oops:
When I found the two different implementations of getAabb() in btTriangleMeshShape and btSoftBodyCollisionShape, blindness crept over me and I overlooked the call to btMatrix3x3::absolute() in the former.
My apologies!