Gazebo Rendering

API Reference

7.4.2
Heightmap

This example shows how to add a heightmap to the scene.

It loads 2 different heightmaps (image and Digital Elevation Model (DEM)) with different parameters.

Compile and run the example

Clone the source code, create a build directory and use cmake and make to compile the code:

git clone https://github.com/gazebosim/gz-rendering
cd gz-rendering/examples/heightmap
mkdir build
cd build
cmake ..
make

Example 1 (image heightmap):

./heightmap

You'll see:

[Msg] Loading plugin [gz-rendering7-ogre]
[Msg] Loading heightmap: scene::Heightmap(65528)
[Msg] Heightmap loaded. Process took 217 ms.
===============================
TAB - Switch render engines
ESC - Exit
===============================

Example 2 (DEM heightmap):

./heightmap --dem

Code

A heightmap is a terrain defined by a 2D grid of height values. The example 1 demo, loads the heights from a grayscale image, where the color black represents the lowest point and white represents the heights. Example 2, loads the heights from the DEM file itself.

The heightmap's information is stored in the HeightmapDescriptor class. In addition to the height data, the heightmap descriptor also exposes functionality such as:

  • Its size in meters in XYZ space.
  • The position of its origin in the world.
  • The textures to use according to the height.
  • How to blend these textures.

Here's the snippet of code from examples/heightmap/Main.cc that adds an image heightmap to the scene:

auto data = std::make_shared<common::ImageHeightmap>();
data->Load(common::joinPaths(RESOURCE_PATH, "heightmap_bowl.png"));
HeightmapDescriptor desc;
desc.SetName("example_bowl");
desc.SetData(data);
desc.SetSize({17, 17, 10});
desc.SetSampling(2u);
desc.SetUseTerrainPaging(false);
HeightmapTexture textureA;
textureA.SetSize(1.0);
textureA.SetDiffuse("../media/dirt_diffusespecular.png");
textureA.SetNormal("../media/flat_normal.png");
desc.AddTexture(textureA);
HeightmapBlend blendA;
blendA.SetMinHeight(2.0);
blendA.SetFadeDistance(5.0);
desc.AddBlend(blendA);
HeightmapTexture textureB;
textureB.SetSize(1.0);
textureB.SetDiffuse("../media/grass_diffusespecular.png");
textureB.SetNormal("../media/flat_normal.png");
desc.AddTexture(textureB);
HeightmapBlend blendB;
blendB.SetMinHeight(4.0);
blendB.SetFadeDistance(5.0);
desc.AddBlend(blendB);
HeightmapTexture textureC;
textureC.SetSize(1.0);
textureC.SetDiffuse("../media/fungus_diffusespecular.png");
textureC.SetNormal("../media/flat_normal.png");
desc.AddTexture(textureC);
auto heightmapGeom = _scene->CreateHeightmap(desc);
auto vis = _scene->CreateVisual();
vis->AddGeometry(heightmapGeom);
_root->AddChild(vis);

And a snippet that adds a DEM heightmap to the scene:

auto data2 = std::make_shared<common::Dem>();
data2->Load(common::joinPaths(RESOURCE_PATH, "moon.tif"));
HeightmapDescriptor desc2;
desc2.SetName("example_moon");
desc2.SetData(data2);
desc2.SetSize({20, 20, 6.85});
desc2.SetSampling(2u);
desc2.SetUseTerrainPaging(false);
HeightmapTexture textureA2;
textureA2.SetSize(20.0);
textureA2.SetDiffuse("../media/moon_diffuse.png");
textureA2.SetNormal("../media/moon_normal.png");
desc2.AddTexture(textureA2);
desc2.SetPosition({0, 0, std::abs(data2->MinElevation())});
auto heightmapGeom2 = _scene->CreateHeightmap(desc2);
auto vis2 = _scene->CreateVisual();
vis2->AddGeometry(heightmapGeom2);
_root->AddChild(vis2);

Note, since DEMs encode elevation data, the minimum elevation for the moon.tif DEM is -212.296. We need to translate the DEM for it to be at z = 0 by setting the descriptor's z position to be 212.296 or desc2.SetPosition({0, 0, std::abs(data2->MinElevation())});.