Problems with triangle collision meshes

SeanTasker
Posts: 2
Joined: Tue Nov 13, 2007 1:21 am

Problems with triangle collision meshes

Post by SeanTasker »

Using Bullet 2.64...

I've had a few problems when using triangle collision meshes.

in
void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const

the indicestype is always set to PHY_INTEGER. Which causes the switch after the call to the function in

void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const

to be redundant. This is fine for index arrays of 4 byte ints but causes problems when the indices are stored as (2 byte) ints. Which is exactly what I am storing them as. I cannot change the storage type as the render system is limited to 1 or 2 byte indices and I do not want to copy the data.

Additionally
void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const

assumes that the index type is PHY_INTEGER always (which is normally true). I have modified the function to check for the type and use short int* OR int* (like in InternalProcessAllTriangles).

Code: Select all

//perform bvh tree traversal and report overlapping triangles to 'callback'
void	btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{

#ifdef DISABLE_BVH
	//brute force traverse all triangles
	btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax);
#else

	//first get all the nodes

	
	struct	MyNodeOverlapCallback : public btNodeOverlapCallback
	{
		btStridingMeshInterface*	m_meshInterface;
		btTriangleCallback*		m_callback;
		btVector3				m_triangle[3];


		MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
			:m_meshInterface(meshInterface),
			m_callback(callback)
		{
		}
				
		virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
		{
			const unsigned char *vertexbase;
			int numverts;
			PHY_ScalarType type;
			int stride;
			const unsigned char *indexbase;
			int indexstride;
			int numfaces;
			PHY_ScalarType indicestype;
			

			m_meshInterface->getLockedReadOnlyVertexIndexBase(
				&vertexbase,
				numverts,
				type,
				stride,
				&indexbase,
				indexstride,
				numfaces,
				indicestype,
				nodeSubPart);

			switch(indicestype)
			{
				case PHY_SHORT:
				{
					short int* gfxbase = (short int*)(indexbase+nodeTriangleIndex*indexstride);

					const btVector3& meshScaling = m_meshInterface->getScaling();
					for (int j=2;j>=0;j--)
					{

						int graphicsindex = gfxbase[j];


	#ifdef DEBUG_TRIANGLE_MESH
						printf("%d ,",graphicsindex);
	#endif //DEBUG_TRIANGLE_MESH
						btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);

						m_triangle[j] = btVector3(
							graphicsbase[0]*meshScaling.getX(),
							graphicsbase[1]*meshScaling.getY(),
							graphicsbase[2]*meshScaling.getZ());
	#ifdef DEBUG_TRIANGLE_MESH
						printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
	#endif //DEBUG_TRIANGLE_MESH
					}
				}break;
				case PHY_INTEGER:
				{
					int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride);

					const btVector3& meshScaling = m_meshInterface->getScaling();
					for (int j=2;j>=0;j--)
					{

						int graphicsindex = gfxbase[j];


	#ifdef DEBUG_TRIANGLE_MESH
						printf("%d ,",graphicsindex);
	#endif //DEBUG_TRIANGLE_MESH
						btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);

						m_triangle[j] = btVector3(
							graphicsbase[0]*meshScaling.getX(),
							graphicsbase[1]*meshScaling.getY(),
							graphicsbase[2]*meshScaling.getZ());
	#ifdef DEBUG_TRIANGLE_MESH
						printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
	#endif //DEBUG_TRIANGLE_MESH
					}
				}break;
			}
			m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
			m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
		}

	};

	MyNodeOverlapCallback	myNodeCallback(callback,m_meshInterface);

	m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);


#endif//DISABLE_BVH


}
My modification to getLockedReadOnlyVertexIndexBase, follows, but assumes that index data is going to be contiguous. Unless I modify the way the btTriangleIndexVertexArray is created I couldn't think of a simple way to determine the index type other than this way.

Code: Select all

	if(indexstride==6)
		indicestype = PHY_SHORT;
	else
		indicestype = PHY_INTEGER;
Lastly

the protoype for the constructor for btTriangleIndexVertexArray differs from the implementation. The first parameter is named numTriangleIndices where as the implementation is named numTriangles. This caused issues when I interpreted numTriangleIndices as the number of indices total (ie. num triangels * 3).

Code: Select all

//just to be backwards compatible
btTriangleIndexVertexArray(int numTriangleIndices,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride);

Code: Select all

btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride)
I realise the comment says just to be backwards compatible, which indicates some changes.. but it still tricked me!

I hope all that made sense - I haven't had a coffee today. heh

- Sean Tasker
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Problems with triangle collision meshes

Post by Erwin Coumans »

Support for short integer indices has been added recently and is available in the current SVN source repository, so it will be available in Bullet 2.65.
See also:
http://www.bulletphysics.com/Bullet/php ... f=9&t=1649

Indeed, the name in the headerfile was misleading, I just changed it in 'numTriangles'.
Thanks for the feedback!
Erwin