# Bullet Physics Terrain

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

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

## 1 Answer

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
{
public:
Map()
{
data = LoadHeightfieldData();
heightfield = new btHeightfieldTerrainShape(..., &data[0], ...);
}

private:
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.

• 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 :]
– Dan
Mar 2 '12 at 15:51
• @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? Mar 2 '12 at 16:22
• 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.
– Dan
Mar 2 '12 at 16:28
• @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? Mar 2 '12 at 16:42
• I will give this a go when I get a chance, Thank You
– Dan
Mar 2 '12 at 17:17