Heightmap terrain with irrlicht and bullet

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
jwatson1993
Posts: 37
Joined: Fri Nov 04, 2011 12:15 am

Heightmap terrain with irrlicht and bullet

Post by jwatson1993 »

I'm trying to put the heightmap classes of irrlicht and bullet together, but apparently I'm bad at vector algebra. For some reason I just can't manipulate the coordinates so that they match up perfectly. I really don't want to get ya'll to do the math for me, but I've tried so many ways and I can't get it. I'm using an algorithm I took off this forum, but I can't remember who. I created a class that derives from CTerrainSceneNode and it creates a heightfield shape and rigid body.

Code: Select all

 
IrrlichtDevice* device =  m_gameInstance->getIrrlicht()->getDevice();
    IImage* image = device->getVideoDriver()->createImageFromFile(heightmap);
    if(!this->loadHeightMap(this->FileSystem->createAndOpenFile(heightmap),SColor(255,255,255,255),20))
        std::cout<<"failed to load height map"<<endl;
    this->setMaterialTexture(0,texture);
    vector3df extent = getBoundingBox().getExtent();
    const core::aabbox3df bb = getBoundingBox();
    f32 minHeight = 10000000.f, maxHeight = -1000000.f;
    int gridSize = image->getDimension().Height;
    float * heightVal = new f32[gridSize*gridSize];
    const f32 stepWidthX = extent.X / (f32)gridSize;
    const f32 stepWidthZ = extent.Z / (f32)gridSize;
    u32 runVal = 0;
    for (f32 z = bb.MinEdge.Z; z < bb.MaxEdge.Z; z+=stepWidthZ)
    {
        for (f32 x = bb.MinEdge.X; x < bb.MaxEdge.X; x+=stepWidthX)
        {
            const f32 curVal = this->getHeight(x, z);
            heightVal[runVal++] = curVal;
            if (curVal > maxHeight)
                maxHeight = curVal;
            if (curVal < minHeight)
                minHeight = curVal;
        }
    }
 
 
    shape = new btHeightfieldTerrainShape(gridSize, gridSize, heightVal, 1.f, minHeight, maxHeight, 1, PHY_FLOAT, true);
    shape->setLocalScaling(btVector3(scale.X,1.f,scale.Z));
    vector3df irrTrans = getTerrainCenter();
    irrTrans.Y *=scale.Y;
    btVector3 trans(irrTrans.X, irrTrans.Y, irrTrans.Z);
    btQuaternion quat = GamePhysics::eulerToQuat(rotation);
    shape->setMargin(.01);
    btTransform bulletTransform(quat,trans);
    shape->setMargin(.01);
    btDefaultMotionState *MotionState = new btDefaultMotionState(bulletTransform);
    btVector3 LocalInertia;
    shape->calculateLocalInertia(0, LocalInertia);
    btTerr = new btRigidBody(0, MotionState, shape, LocalInertia);
    btTerr->setUserPointer((void*)fizzObj);
    fizzObj = new CPhysicsObject(this, btTerr, ginst);
    m_gameInstance->getPhysics()->getWorld()->addRigidBody(btTerr);
    image->drop();
I need this to work no matter how I rotate, translate, or scale it. Thanks in advance. Is it better to just use a triangle mesh than this? I feel like this is easier, but I just can't get the math right.
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: Heightmap terrain with irrlicht and bullet

Post by zerochen »

hi,

first of all wrong forum^^

then you have a memleak here:

Code: Select all

float * heightVal = new f32[gridSize*gridSize];
next i use this snippet that works perfect:

Code: Select all

    
node->updateAbsolutePosition();
 
    core::vector3df scale = node->getScale();
 
    core::aabbox3d<f32> box = node->getBoundingBox();
    const core::vector3df size = box.getExtent() / scale;
    f32 minHeight = ((scene::ITerrainSceneNode*)node)->getHeight(0, 0);
    f32 maxHeight = minHeight;
 
    heightVal = new f32[gridSize*gridSize];
    const f32 stepWidthX = size.X / gridSize;
    const f32 stepWidthZ = size.Z / gridSize;
    u32 runVal = 0;
 
    core::vector3df minEdge = box.MinEdge / scale;
    core::vector3df maxEdge = box.MaxEdge / scale;
 
    for (f32 z = minEdge.Z; z < maxEdge.Z; z+=stepWidthZ)
    {
        for (f32 x = minEdge.X; x < maxEdge.X; x+=stepWidthX)
        {
            const f32 curVal = ((scene::ITerrainSceneNode*)node)->getHeight(x, z);
 
            heightVal[runVal++] = curVal;
 
            if (curVal > maxHeight)
                maxHeight = curVal;
            if (curVal < minHeight)
                minHeight = curVal;
        }
    }
    
    shape = new btHeightfieldTerrainShape(gridSize, gridSize, heightVal, 1.f, minHeight, maxHeight, 1, PHY_FLOAT, false);
 
Regards
zerochen
Post Reply