Slow Terrain Collision Mesh Generation

Yacoby

12-05-2008 10:34:13

I decided to use Newton for the physics, however, the problem I have hit is that generating the physics for my terrain is very slow. 5 minutes slow.

I know my code isn't a work of art, but there must be a faster way of generating the terrain collision mesh (the mesh is only 257x257 verts)

I am not even sure if the code works, but anyway, this is what I am doing:
OgreNewt::CollisionPrimitives::TreeCollision* col = new OgreNewt::CollisionPrimitives::TreeCollision( mWorld );

col->start();
const ET::TerrainInfo* ti = &mTerrainMgr->getTerrainInfo();
std::vector<float> terrain = ti->getHeightmapData();

Ogre::Vector3 square[4];
Ogre::Vector3 verts[3];


for ( long w = 0; w < ti->getWidth()-1; w++){
for ( long h = 0; h < ti->getHeight()-1; h++){
long arryPos = w*ti->getWidth()+h;

/*
2--3
| |
0--1
*/


square[0].y = terrain[arryPos]*ti->getScaling().y;
square[1].y = terrain[arryPos + 1]*ti->getScaling().y;
square[2].y = terrain[arryPos + ti->getWidth()]*ti->getScaling().y;
square[3].y = terrain[arryPos + ti->getWidth() + 1]*ti->getScaling().y;

//get the pos of the vertex of point 0
square[0].x = (w*ti->getScaling().x) + ti->getOffset().x;
square[0].z = (h*ti->getScaling().z) + ti->getOffset().z;

//bvase the rest of the poses off point 0
square[1].x = square[0].x + ti->getScaling().x;
square[1].z = square[0].z;

square[2].x = square[0].x;
square[2].z = square[0].z + ti->getScaling().z;

square[1].x = square[1].x;
square[1].z = square[2].z;


//add the pollys to tghe meshg.
verts[0] = square[0];
verts[1] = square[1];
verts[2] = square[2];

col->addPoly(verts, 0);
verts[0] = square[1];
verts[1] = square[3];
verts[2] = square[2];
col->addPoly(verts, 0);
}
}
col->finish();

OgreNewt::Body* body = new OgreNewt::Body(mWorld, col );

pra

12-05-2008 13:37:30

you could try to export the collision files using treecollisionserializer.

here I posted code how to do that with PLSM2 (second last post)

Yacoby

12-05-2008 23:06:19

you could try to export the collision files using treecollisionserializer.

here I posted code how to do that with PLSM2 (second last post)

Thanks for the code, that is a lot faster loading it, although my col mesh code doesn't work :(

pra

12-05-2008 23:09:24

might be due to face winding or stuff... at least I had such problems...

Yacoby

13-05-2008 10:14:55

EDIT: Fixed the problem, I patched OgreNewt_TreeColisionSerilizer (sp?), line 25, and added this:
fclose(mpfFile);

Proberbly due to the fact that my app wasn't shutting down properly that it wasn't flushing the file. Maybe. *shrugs*

might be due to face winding or stuff... at least I had such problems...
What is strange is that it it seems to work when I generate the col mesh, but not when the the exported colision data is imported instead. Strabnge


I will look into the face winding, see if that fixes it :)

EDIT:
The winding fixed one of my problems, my car now runs allong the top of my terrain, however, I still can't load collison data from a file. When I load it from a file and press F3 to view colsions, it crashes

OgreNewt::CollisionPrimitives::TreeCollision* col = new OgreNewt::CollisionPrimitives::TreeCollision( mWorld );

//try and load the mesh
OgreNewt::TreeCollisionSerializer* serializer=new OgreNewt::TreeCollisionSerializer();
Ogre::ResourceGroupManager *rgm = Ogre::ResourceGroupManager::getSingletonPtr();
if(rgm->resourceExists(group,"map.col")){
Ogre::DataStreamPtr ptr = rgm->openResource("map.col",group);
serializer->importTreeCollision(ptr,col);
OgreNewt::Body *bod = new OgreNewt::Body(mWorld,col);

delete serializer;
return; //we don't need to buid the mesh, so we can quit here
}



const ET::TerrainInfo* ti = &mTerrainMgr->getTerrainInfo();

//get the heightmap
std::vector<float> terrain = ti->getHeightmapData();

Ogre::Vector3 scaling = ti->getScaling(); //distance between verts
Ogre::Vector3 square[4];
Ogre::Vector3 verts[3];

//building the col mesh
col->start();

for ( long h = 0; h < 4-1; h++){
for ( long w = 0; w < ti->getWidth()-1; w++){
long arryPos = h*ti->getHeight()+w;

/*
this is the points that we need to build the 2 polys

2--3
| |
0--1
*/

//the y points need to be got from the terrain vector
square[0].y = terrain[arryPos]*scaling.y;
square[1].y = terrain[arryPos + 1]*scaling.y;
square[2].y = terrain[arryPos + ti->getWidth()]*scaling.y;
square[3].y = terrain[arryPos + ti->getWidth() + 1]*scaling.y;

//get the pos of the vertex of point 0
square[0].x = (w*scaling.x) + ti->getOffset().x;
square[0].z = (h*scaling.z) + ti->getOffset().z;

//now build the res of the points off the base (square[0])

//bottom right
square[1].x = square[0].x + scaling.x;
square[1].z = square[0].z;

//top left
square[2].x = square[0].x;
square[2].z = square[0].z + scaling.z;

//top right
square[3].x = square[1].x;
square[3].z = square[2].z;


//add the pollys to tghe meshg.
verts[0] = square[0];
verts[1] = square[2];
verts[2] = square[1];
col->addPoly(verts, 0);

verts[0] = square[1];
verts[1] = square[2];
verts[2] = square[3];
col->addPoly(verts, 0);
}
}
col->finish(false); //finish building, don't optomize

//export the mesh to a file to reload it later
OgreNewt::Body* body = new OgreNewt::Body(mWorld, col );
serializer->exportTreeCollision(col,"data/maps/" + group + "/map.col");

delete serializer;