[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