Page 1 of 1

Getting a heightfieal out of a ITerrainSceneNode

Posted: Tue Nov 17, 2009 1:34 pm
by enif
Hi!

I am playing with Bullet and ITerrainScenenodes and as a part of my research got this pice of code. It should make a heightfield out of a ITerrainSceneNode object.

Code: Select all

f32 *CTerrain::getRawHeightfieldData(scene::ITerrainSceneNode* node, btScalar& minHeight, btScalar& maxHeight)
{
	scene::CDynamicMeshBuffer* buffer = NULL;
	u32 vertexCount = 0;
	f32* heightMap = NULL;

	// we need to know the total number of vertices
	const u32 numVertices = node->getMesh()->getMeshBuffer(0)->getVertexCount();

	try
	{	
		// a fount this in the Irllicht's sources of CTerrainSceneNode
		if (numVertices <= 65536)
		{
			//small enough for 16bit buffers
			buffer = new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT);
		}
		else
		{
			//we need 32bit buffers
			buffer = new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_32BIT);
		}

		// get the mesh data for LOD 0
		node->getMeshBufferForLOD(*buffer, 0);

		// should be the same as the numVertices - you can test for that
		vertexCount = buffer->getVertexCount();

		// get some memory for the heightmap
		heightMap = new f32[vertexCount];
	}
	catch (std::bad_alloc)
	{
		// If the heightMap allocation fails, this will be already allocated.
		if (buffer != NULL) buffer->drop();

		return NULL;
	}

	// initialize the min/max
	m_minHeight = heightMap[0];
	m_maxHeight = m_minHeight;

	f32* hm = &heightMap[0];
	for (u32 i = 0; i < vertexCount; i++)
	{
		f32 height = buffer->getVertexBuffer()[i].Pos.Y;

		// update min/max
		if (height < m_minHeight) 
		{
			m_minHeight = height;
		}

		if (height > m_maxHeight) 
		{
			m_maxHeight = height;
		}

		// store the height
		*hm++ = height;
	}

	buffer->drop();

	if (m_maxHeight < -m_minHeight) 
	{
		m_maxHeight = -m_minHeight;
	}

	if (m_minHeight > -m_maxHeight) 
	{
		m_minHeight = -m_maxHeight;
	}

	return heightMap;
}
This heightfield can be used for example as an imput for the Bullet's btHeightfieldTerrainShape() method. (See their TerrainDemo.)

Happy codding!