I'm working at extending the CTerrainSceneNode class to add a method with loads a heightmap from an array of values. Right now my function looks like this:
Code: Select all
bool CTerrainSceneNode::loadHeightMapFromArray(irr::f32* heights[], int width, video::SColor vertexColor, s32 smoothFactor)
{
const u32 startTime = os::Timer::getTime();
Mesh.MeshBuffers.clear();
TerrainData.Size = width;
switch (TerrainData.PatchSize)
{
case ETPS_9:
if (TerrainData.MaxLOD > 3)
{
TerrainData.MaxLOD = 3;
}
break;
case ETPS_17:
if (TerrainData.MaxLOD > 4)
{
TerrainData.MaxLOD = 4;
}
break;
case ETPS_33:
if (TerrainData.MaxLOD > 5)
{
TerrainData.MaxLOD = 5;
}
break;
case ETPS_65:
if (TerrainData.MaxLOD > 6)
{
TerrainData.MaxLOD = 6;
}
break;
case ETPS_129:
if (TerrainData.MaxLOD > 7)
{
TerrainData.MaxLOD = 7;
}
break;
}
scene::CDynamicMeshBuffer *mb=0;
const u32 numVertices = TerrainData.Size * TerrainData.Size;
if (numVertices <= 65536)
{
mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT);
RenderBuffer->getIndexBuffer().setType(video::EIT_16BIT);
}
else
{
mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_32BIT);
RenderBuffer->getIndexBuffer().setType(video::EIT_32BIT);
}
mb->getVertexBuffer().reallocate(numVertices);
video::S3DVertex2TCoords vertex;
vertex.Normal.set(0.0f, 1.0f, 0.0f);
vertex.Color = vertexColor;
const f32 tdSize = 1.0f/(f32)(TerrainData.Size-1);
float fx=0.f;
float fx2=0.f;
for (s32 x = 0; x < TerrainData.Size; ++x)
{
float fz=0.f;
float fz2=0.f;
for (s32 z = 0; z < TerrainData.Size; ++z)
{
vertex.Pos.Y = heights[x*width+z];
vertex.Pos.Z = fz;
vertex.TCoords.X = vertex.TCoords2.X = 1.f-fx2;
vertex.TCoords.Y = vertex.TCoords2.Y = fz2;
mb->getVertexBuffer().push_back(vertex);
++fz;
fz2 += tdSize;
}
++fx;
fx2 += tdSize;
}
smoothTerrain(mb, smoothFactor);
calculateNormals(mb);
Mesh.addMeshBuffer(mb);
const u32 vertexCount = mb->getVertexCount();
RenderBuffer->getVertexBuffer().set_used(vertexCount);
for (u32 i = 0; i < vertexCount; i++)
{
RenderBuffer->getVertexBuffer()[i] = mb->getVertexBuffer()[i];
RenderBuffer->getVertexBuffer()[i].Pos *= TerrainData.Scale;
RenderBuffer->getVertexBuffer()[i].Pos += TerrainData.Position;
}
mb->drop();
// calculate all the necessary data for the patches and the terrain
calculateDistanceThresholds();
createPatches();
calculatePatchData();
// set the default rotation pivot point to the terrain nodes center
TerrainData.RotationPivot = TerrainData.Center;
// Rotate the vertices of the terrain by the rotation specified. Must be done
// after calculating the terrain data, so we know what the current center of the
// terrain is.
setRotation(TerrainData.Rotation);
// Pre-allocate memory for indices
RenderBuffer->getIndexBuffer().set_used(
TerrainData.PatchCount*TerrainData.PatchCount*
TerrainData.CalcPatchSize*TerrainData.CalcPatchSize*6);
const u32 endTime = os::Timer::getTime();
c8 tmp[255];
snprintf(tmp, 255, "Generated terrain data (%dx%d) in %.4f seconds",
TerrainData.Size, TerrainData.Size, (endTime - startTime) / 1000.0f);
os::Printer::log(tmp);
return true;
}
Code: Select all
vertex.Pos.Y = heights[x*width+z];