Im trying to Load an RGB image (.BMP) into bullet's btHeightfieldTerrainShape

Im using a loader that creates a openGL height map, it stores the data in a vector float, but I cant get the btHeightfieldTerrainShape to accept it.

I changed the vector float into a float array which contains height data according to the debugger, when loaded it takes forever to load the terrain, and when its loaded it is a flat terrain.

It is alot of code, but I can add it if needed.

The Code

  • \$\begingroup\$ You don't need to add all the code, just how you're creating the heightfield. \$\endgroup\$ Commented Mar 2, 2012 at 12:43

1 Answer 1


First of all, since the elements of a std::vector are guaranteed to be contiguous, you can pass it to Bullet with a simple trick:

std::vector<float> dataVector = LoadHeightMap();
float* data = &dataVector[0];

But realize that data is just a pointer, and the data is still stored within the vector. So make sure you keep the vector alive for as long as you need (more on this further below).

About btHeightfieldTerrainShape I'm not sure but I think it makes sense to assume that when passing it an array of floats, they should be normalized in the [0-1] range. Is that what your debugger shows you?

Other than that, make sure you're passing PHY_FLOAT as the heightDataTypeparameter to the constructor, and choose a reasonable minHeight and maxHeight pair of values. It would help if you showed the relevant part of your code.

Also notice this note on the documentation:

The caller is responsible for maintaining the heightfield array; this class does not make a copy.

So make sure you're keeping your vector alive. So if for instance you're just using the vector inside the load method and not storing it somewhere else, your data will be gone by the time the load method returns. Store it as a member variable of your class instead, and then get a pointer to its data with the trick above.

In other words something like:

class Map
        data = LoadHeightfieldData();
        heightfield = new btHeightfieldTerrainShape(..., &data[0], ...);

    vector<float> data;
    btHeightfieldTerrainShape* heightfield;

And finally, the length of your data array should obviously correspond to the width * length you specify when creating the heightfield.

  • \$\begingroup\$ I have added the code to the original question, The values are normalized and the array is the correct size, the vector is kept alive. Thank you for your help :] \$\endgroup\$
    – Dan
    Commented Mar 2, 2012 at 15:51
  • \$\begingroup\$ @Dan So it was none of those problems? I looked through that code, but didn't notice anything unusual. Have you made sure that the problem isn't only with the rendering code, not the physics? \$\endgroup\$ Commented Mar 2, 2012 at 16:22
  • \$\begingroup\$ Its defiantly not the render function, as the rendering works fine if you disable the physics. What I have just seams to make a flat plane under the 'visual terrain' when the physics are enabled. \$\endgroup\$
    – Dan
    Commented Mar 2, 2012 at 16:28
  • 1
    \$\begingroup\$ @Dan Another idea to debug - call processAllTriangles() on the terrain object using a callback that prints all the vertices. Is the Y coordinate of all the vertices really 0? \$\endgroup\$ Commented Mar 2, 2012 at 16:42
  • \$\begingroup\$ I will give this a go when I get a chance, Thank You \$\endgroup\$
    – Dan
    Commented Mar 2, 2012 at 17:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .