History: BloodyMess Ogre::Terrain Heightfield
Source of version: 6 (current)
Copy to clipboard
{INCLUDE(page="BloodyMess tpl")}{INCLUDE}
%help%~hs~__Help:__ For any problems you encounter while working with these code, please visit the [http://www.ogre3d.org/addonforums/viewtopic.php?f=6&t=10859|thread in the NxOgre forum].
!!{img src="img/wiki_up/NxOgreCube.png" alt="NxOgreCube.png"} BloodyMess Ogre::Terrain heightfield
This code shows how to create a matching heightfield from the new Ogre::Terrain, a new feature in Ogre 1.7.
It does everything in realtime, so there is no need to use flour to create an .xhf or flip and rotate the ((-Height Map|heightmap)).
Thanks to XpLoDWilD for solving an issue with vertex under the origin.
{CODE(wrap="1", colors="c++")}void loadTerrainGeometry(const Ogre::String& name, float* data, Ogre::uint16 size, Ogre::Real worldSize, Ogre::Real minHeight, Ogre::Real maxHeight, const Ogre::Vector3& position)
{
// Create the manual heightfield
NxOgre::ManualHeightField *mhf = OGRE_NEW_T(NxOgre::ManualHeightField, Ogre::MEMCATEGORY_GENERAL)();
mhf->begin(size, size);
Ogre::Real normMin = -32768.0f;
Ogre::Real normMax = 32767.0f;
// Sample the data to the manual heightfield
for(int x = 0; x < size; ++x)
{
NxOgre::Enums::HeightFieldTesselation tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;
for(int z = size-1; z >= 0; --z)
{
Ogre::Real height = data[(size * z) + x];
short sample = (short)(((height - minHeight) / (maxHeight - minHeight)) * (normMax - normMin) + normMin);
mhf->sample(sample, 0, 0, tess);
if(tess == NxOgre::Enums::HeightFieldTesselation_NE_SW)
tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;
else
tess = NxOgre::Enums::HeightFieldTesselation_NE_SW;
}
}
// Create the actual heightfield
NxOgre::HeightField *hf = mhf->end(name.c_str());
Ogre::Real hf_size = worldSize + (worldSize / size);
Ogre::Real hf_height = (maxHeight - minHeight) / 2.0f;
Ogre::Real hf_pose_x = position.x - (worldSize / 2.0f);
Ogre::Real hf_pose_y = position.y + ((maxHeight + minHeight) / 2.0f);
Ogre::Real hf_pose_z = position.z - (worldSize / 2.0f);
#if NxOgreVersionMajor <= 1 && NxOgreVersionMinor <= 5
NxOgre::HeightFieldGeometry* hfg = new NxOgre::HeightFieldGeometry(hf, NxOgre::Vec3(hf_size, hf_height, hf_size));
hfg->setLocalPose(NxOgre::Matrix44(NxOgre::Vec3(hf_pose_x, hf_pose_y, hf_pose_z)));
mScene->createSceneGeometry(hfg);
#else
NxOgre::HeightFieldGeometryDescription desc(hf, NxOgre::Vec3(hf_size, hf_height, hf_size));
mScene->createSceneGeometry(desc, NxOgre::Matrix44(NxOgre::Vec3(hf_pose_x, hf_pose_y, hf_pose_z)));
#endif
// Free memory
OGRE_DELETE_T(mhf, ManualHeightField, Ogre::MEMCATEGORY_GENERAL);
}{CODE}
You can use it like that, with "terrain" being a pointer to your Ogre::Terrain.
{CODE(wrap="1", colors="c++")}loadTerrainGeometry(terrain->getMaterialName(), terrain->getHeightData(), terrain->getSize(),
terrain->getWorldSize(), terrain->getMinHeight(), terrain->getMaxHeight(), terrain->getPosition());{CODE}
Or you can supply the data yourself.
{INCLUDE(page="NxOgre tpl")}{INCLUDE}
---
Alias: (alias(BloodyMess_Ogre::Terrain_Heightfield))