Problem with IrrNewt FIXED! Now we're able to load terrain bodies with heightmaps bigger than 129x129 without problems in Irrlicht 1.5
Here's fixed IrrNewt CreateCollisionTreeTerrain function:
Code: Select all
NewtonCollision* CreateCollisionTreeTerrain(
IWorld* world,
scene::ISceneNode* node,
irr::s32 LOD,
unsigned int& PolyCount) {
NewtonWorld* nWorld = const_cast<NewtonWorld*>(world->getNewtonWorld());
NewtonCollision* nCollision;
//part of newton
nCollision = NewtonCreateTreeCollision(nWorld, NULL);
NewtonTreeCollisionBeginBuild(nCollision);
int v1i, v2i, v3i;
irr::f32 vArray[9]; // vertex array (3*3 floats)
int tmpCount = 0;
scene::CDynamicMeshBuffer mb2(video::EVT_2TCOORDS,video::EIT_32BIT);
((scene::ITerrainSceneNode*)node)->getMeshBufferForLOD(
mb2,
LOD //level of detail
);
//mb2.Indices.set_free_when_destroyed(false);
//mb2.Vertices.set_free_when_destroyed(false);
video::S3DVertex2TCoords *vertices = (video::S3DVertex2TCoords*)mb2.getVertexBuffer().getData();
u32 *indices = (u32*)mb2.getIndexBuffer().getData();
core::vector3df mapsize = node->getScale();
// create collision tree faces
for (int i = 0; i < mb2.getIndexCount() ; i += 3)
{
v1i = indices[i];
v2i = indices[i + 1];
v3i = indices[i + 2];
// build face data
vArray[0] = vertices[v1i].Pos.X*mapsize.X* IrrToNewton;
vArray[1] = vertices[v1i].Pos.Y*mapsize.Y* IrrToNewton;
vArray[2] = vertices[v1i].Pos.Z*mapsize.Z* IrrToNewton;
vArray[3] = vertices[v2i].Pos.X*mapsize.X* IrrToNewton;
vArray[4] = vertices[v2i].Pos.Y*mapsize.Y* IrrToNewton;
vArray[5] = vertices[v2i].Pos.Z*mapsize.Z* IrrToNewton;
vArray[6] = vertices[v3i].Pos.X*mapsize.X* IrrToNewton;
vArray[7] = vertices[v3i].Pos.Y*mapsize.Y* IrrToNewton;
vArray[8] = vertices[v3i].Pos.Z*mapsize.Z* IrrToNewton;
// make sure we do not add degenerated polygons to the tree
core::vector3df irrvArray[3] ={
core::vector3df(vArray[0],vArray[1],vArray[2]),
core::vector3df(vArray[3],vArray[4],vArray[5]),
core::vector3df(vArray[6],vArray[7],vArray[8])
};
core::vector3df e0 (irrvArray[1] - irrvArray[0]);
core::vector3df e1 (irrvArray[2] - irrvArray[0]);
// the area of the face is the cross product
core::vector3df area (e0.crossProduct (e1));
// skip faces with very small area
irr::f32 mag = area.dotProduct (area);
if (mag > 1.0e-6f) {
// add face to tree
NewtonTreeCollisionAddFace(nCollision , 3, (float*)vArray, 12, 11);
PolyCount++;
}// if (mag > 1.0e-6f) {
}
NewtonTreeCollisionEndBuild(nCollision, 0);
//set
return nCollision;
}
Changes you should notice:
- CMeshBuffer instead of S....LightMap
- getVertexBuffer().getData(); and getIndexBuffer().getData() instead of getVertices() and getIndicies();
- indicies changed to u32 to work properly when it's more than 65535 indicies
- NewtonTreeCollisionEndBuild(nCollision,
0) - if this parameter is left to 1 (optimization turned on), Newton seems to crash eating tons of memory in infinite loop (maybe it's finite but on 2 GB virtual RAM it just crashes)
- I don't know how the "Indices.set_free_when_destroyed(false); mb2.Vertices.set_free_when_destroyed(false); " functions work so I left them commented
Thank's hybrid and others for your help.