[ODE] Difference in collision behavior of Trimesh between Linux and WIndows

nospam@hardgeus.com nospam at hardgeus.com
Sat May 20 11:23:55 MST 2006


I am developing on two machines, one is a Gentoo Linux machine with ODE
0.5, and the other is a Windows machine also with ODE 0.5.  On the Windows
machine I am using MingW.  I have developed a relatively simple test app
using the Irrlicht graphics engine that is based on the example found at:

http://thomas.webtracker.ch/jahia/Jahia/pid/481

The basic idea of what I am doing is creating a few objects in Irrlicht,
copying their data over to data the structures that ODE desires, running
physics and collisions, and then reflecting any changes to position and
orientation back to the Irrlicht nodes.

There are two different ways I get the data to ODE.  For some objects, I
use the coarse bounding box and call dCreateBox.  This is working fine in
both Windows and Linux.  For other objects I copy the data from Irrlicht's
mesh objects over to an ODE trimesh.

This is where the problems occur.  The trimesh works perfectly in Linux,
but in Windows, no collisions occur.  When a collision *should* occur, the
collision callback is firing with the correct geoms, but when I then call
dCollide with them, it is reporting no contacts.

I feel confident that I am copying the mesh data over correctly (or at
least if there's a bug, it's subtle), as it works perfectly in Linux.  I'm
a little lost as to how I can go about debugging this.  Is there any sort
of verbose output I can tell ODE to report in dCollide?  Below is the code
where I copy over the Irrlicht mesh data over to the ODE trimesh.  Note
that I have the code commented out that uses dCreateBox, which works on
both Linux and Windows.  Note also that I am not creating a body for this
object, as it is my "ground"...my other entities use a different chunk of
code (which generates a body and a geom box with dCreateBox).



//Setup refined collission detection for this object
void CPhysicsObject::setGeomData(){
	vector3df obScale = m_node->getScale();
	irr::core::vector3df pos = m_node->getPosition();


/*
//FIXME FIXME
//This commented section works both in Linux and WIndows

	printf("Creating box Geom data\n");

	irr::core::aabbox3d<irr::f32> box = m_node->getBoundingBox();
	irr::core::vector3df extent = box.getExtent();

	extent.X *= obScale.X;
	extent.Y *= obScale.Y;
	extent.Z *= obScale.Z;


	m_geom = dCreateBox(
m_space,(dReal)extent.X,(dReal)extent.Y,(dReal)extent.Z );
	dGeomSetData( m_geom,(void*)this );
	dGeomSetPosition( m_geom,pos.X,pos.Y,pos.Z );

return;
//FIXME FIXME
*/

	printf("Creating refined geom data\n");

	if(m_mesh==NULL || m_node==NULL) {
		printf("Null mesh or node error in creating refined geom data\n");
		return; // do nothing if the mesh or node is NULL
	}
	int i,j,ci,cif,cv;
	m_indexcount=0;
	m_vertexcount=0;
	// count vertices and indices
	for(i=0;i<m_mesh->getMeshBufferCount();i++){
		irr::scene::IMeshBuffer* mb=m_mesh->getMeshBuffer(i);
		m_indexcount+=mb->getIndexCount();
		m_vertexcount+=mb->getVertexCount();
	}
	// build structure for ode trimesh geom
	m_vertices=new dVector3[m_vertexcount];
	m_indices=new int[m_indexcount];
	// fill trimesh geom
	ci=0;
	cif=0;
	cv=0;
	for(i=0;i<m_mesh->getMeshBufferCount();i++){
		irr::scene::IMeshBuffer* mb=m_mesh->getMeshBuffer(i);
		// fill indices
		irr::u16* mb_indices=mb->getIndices();
		for(j=0;j<mb->getIndexCount();j++){
			m_indices[ci]=cif+mb_indices[j];
			ci++;
		}
		cif=cif+mb->getVertexCount();
		// fill vertices
		if(mb->getVertexType()==irr::video::EVT_STANDARD){
			irr::video::S3DVertex*
mb_vertices=(irr::video::S3DVertex*)mb->getVertices();
			for(j=0;j<mb->getVertexCount();j++){
				m_vertices[cv][0] = mb_vertices[j].Pos.X * obScale.X;
				m_vertices[cv][1] = mb_vertices[j].Pos.Y * obScale.Y;
				m_vertices[cv][2] = mb_vertices[j].Pos.Z * obScale.Z;
				m_vertices[cv][3] = 0; //Johnm added
				cv++;
			}
		}else if(mb->getVertexType()==irr::video::EVT_2TCOORDS){
			irr::video::S3DVertex2TCoords*
mb_vertices=(irr::video::S3DVertex2TCoords*)mb->getVertices();
			for(j=0;j<mb->getVertexCount();j++){
				m_vertices[cv][0] = mb_vertices[j].Pos.X * obScale.X;
				m_vertices[cv][1] = mb_vertices[j].Pos.Y * obScale.Y;
				m_vertices[cv][2] = mb_vertices[j].Pos.Z * obScale.Z;
				m_vertices[cv][3] = 0; //Johnm added
				cv++;
			}
		}
	}
	// build the trimesh data
	dTriMeshDataID data = dGeomTriMeshDataCreate();
	dGeomTriMeshDataBuildSimple(
data,(dReal*)m_vertices,m_vertexcount,m_indices,m_indexcount );
	// build the trimesh geom
	m_geom=dCreateTriMesh( m_space,data,0,0,0 );
	// set the geom position
	dGeomSetPosition(m_geom,pos.X,pos.Y,pos.Z);
	// lets have a pointer to our bounceable, we could need this in the
collision callback
	dGeomSetData(m_geom,(void*)this);
	// in our application we don't want geoms constructed with meshes (the
terrain) to have a body
	dGeomSetBody(m_geom,0);

	printf("Created geom of %d vertices\n", m_vertexcount);
} //setGeomData




More information about the ODE mailing list