[solved] 1.5 and IrrNewt: Terrain and getMeshBufferForLOD

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
Eigen
Competition winner
Posts: 375
Joined: Fri Jan 27, 2006 2:01 pm
Location: Estonia
Contact:

[solved] 1.5 and IrrNewt: Terrain and getMeshBufferForLOD

Post by Eigen »

I was trying to update my project to work with Irrlicht 1.5 beta, so for that I also needed to compile IrrNewt with the newest version. It compiled fine until in collision.cpp it came up with this:

Code: Select all

 C:\IrrNewt_SDK_0_4\source\IrrNewt_src\collision.cpp In function `NewtonCollision* CreateCollisionTreeTerrain(irr::newton::IWorld*, irr::scene::ISceneNode*, irr::s32, unsigned int&)': 
37 C:\IrrNewt_SDK_0_4\source\IrrNewt_src\collision.cpp no matching function for call to `irr::scene::ITerrainSceneNode::getMeshBufferForLOD(irr::scene::SMeshBufferLightMap&, irr::s32&)' 
 note C:\irrlicht15\trunk\include\ITerrainSceneNode.h:87 candidates are: virtual void irr::scene::ITerrainSceneNode::getMeshBufferForLOD(irr::scene::IDynamicMeshBuffer&, irr::s32) const 
Here is the code

Code: Select all

scene::SMeshBufferLightMap mb2;
((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.getVertices(); 
u16 *indices = mb2.getIndices();

...
I understand that SMeshBufferLightMap was replaced with IDynamicMeshBuffer in getMeshBufferForLOD, but how exactly do I replace it. Simply putting IDynamicMeshBuffer instead of SMeshBufferLightMap won't work. Or is there another way to get the mesh buffer for certain LOD level. I think it doesn't need to use the dynamic mesh buffers in this case, because it's only used to convert it to internal Newton mesh and is not used for rendering. So maybe a method to use the old implementation as well?

Thanks in advance.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Hmm, you need to find the proper dynamic buffer type somehow and create an object of that type. I'll move this post to the bug thread and hope that it gets fixed before we release 1.5!
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

I have got similar problem, in IDynamicMeshBuffer you have problem with Indices... I can't grab properly terrain indices via IDynamicMeshBuffer and him IndexBuffer... so I add to my Irrlicht version overload function with SMeshBufferLightMap support.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
matgaw
Posts: 45
Joined: Sat Oct 06, 2007 11:33 am

Post by matgaw »

Is there any solution yet? I have the same problem.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, simply check the code of example 12.
matgaw
Posts: 45
Joined: Sat Oct 06, 2007 11:33 am

Post by matgaw »

Thanks, it worked somehow but I can't still create a Newton body with > 65535 indicies/vertices... Code crashes at "NewtonTreeCollisionEndBuild".

Is it possible to workaround this somehow? (question for Newton programmers or IrrNewt users).
matgaw
Posts: 45
Joined: Sat Oct 06, 2007 11:33 am

Post by matgaw »

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.
Post Reply