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;
}
Happy codding!