Skip to main content

History: BloodyMess Ogre::Terrain Heightfield

Source of version: 5

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 (currently in SVN trunk).

It does everything in realtime, so there is no need to use flour to create an .xhf or flip and rotate the 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))
        

History

Information Version
Tue 27 of Jul, 2010 11:19 GMT-0000 Beauty removed note "Ogre 1.7 in SVN" + linked word 6
Mon 26 of Jul, 2010 03:22 GMT-0000 Matheus Martino 5
Sat 01 of May, 2010 10:31 GMT-0000 jacmoe 4
Thu 24 of Dec, 2009 15:53 GMT-0000 jacmoe 3
Thu 24 of Dec, 2009 15:52 GMT-0000 jacmoe 2
Mon 31 of Aug, 2009 06:08 GMT-0000 Illidanz 1