btHeightfieldTerrainShape

JohnBoyManbullet

20-09-2011 22:20:13

hello i have created a btHeightfieldTerrainShape with my heightmap data. The problem is that this collision object is not aligned the same as the heigh map normally is , so i had to adjust the heightmap to match it. It works but it causes all sorts of problems for the rest of my program. Is there a way to move just the collision object to fit the height maps original alignment and position. my code looks like this, thanks.



std::string terrainFileStr = "terrain.cfg";

Ogre::DataStreamPtr configStream = Ogre::ResourceGroupManager::getSingleton().openResource(terrainFileStr, Ogre::ResourceGroupManager::getSingleton().getWorldResourceGroupName());
Ogre::ConfigFile config;
config.load(configStream);

Ogre::String widthStr = config.getSetting("PageSize");
int width = atoi(widthStr.c_str());

Ogre::String imgFile = config.getSetting("Heightmap.image");

Ogre::Image* heightmap = new Ogre::Image();
heightmap->load(imgFile, Ogre::ResourceGroupManager::getSingleton().getWorldResourceGroupName());

Ogre::String maxHeightStr = config.getSetting("MaxHeight");
btScalar maxHeight = atof(maxHeightStr.c_str());
btScalar heightScale = maxHeight / 256;

// This code for the localScaling is taken directly from the TerrainSceneManager, adapted to a btVector3
btVector3 localScaling(1, 1, 1);
localScaling.setX(atof(config.getSetting("PageWorldX").c_str()) / (width -1));
localScaling.setZ(atof(config.getSetting("PageWorldZ").c_str()) / (width -1));





// And now, we actually call Bullet. heightmap needs to be on the heap, as bullet does not copy it.
btHeightfieldTerrainShape* mGroundShape = new btHeightfieldTerrainShape(width, width, heightmap->getData(), heightScale, 0, maxHeight, 1, PHY_UCHAR, false);
mGroundShape->setLocalScaling(localScaling);
// Ogre::Root *mRoot;

mGroundShape->getAabb(btTransform::getIdentity(), min, max);

Ogre::SceneNode *tNode = mSceneMgr->getSceneNode("Terrain");
tNode->setPosition(BtOgre::Convert::toOgre(min)+Ogre::Vector3(0,0,0)); //

btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-2,0));

{
btScalar mass(7.);

//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass = 0.f);

btVector3 localInertia(0,0,0);
if (isDynamic)
groundShape->calculateLocalInertia(mass,localInertia);

btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,mGroundShape,localInertia);
body = new btRigidBody(rbInfo);
body->setFriction(0.8f);