No Collision between Heightfield and Cube?

Brutal
Posts: 14
Joined: Mon Jul 26, 2010 8:03 am

No Collision between Heightfield and Cube?

Post by Brutal »

I finally got Bullet working in my game tonight, and I used the Hello World sample as the first test. Initially, my debug drawer class showed my terrain heightfield was a few hundred units under my terrain. When this was the case, my falling cube collided with it correctly (from what I could tell).

I adjusted the code and fixed it so that the heightfield is actually in the correct place now (only adjustment was to .setOrigin() on the heightfield body), but for some reason the cube just falls through it, and keeps falling infinitely. I have absolutely no idea whats wrong as it was working before I fixed the location of the terrain. Now I watch it just fall right through. I am hoping someone might have an idea as to why this is. Here is the code I believe would be pertinent to diagnosing this issue.

Code: Select all

void PhysicsManager::update(float delta)
{
	if(m_bActive)
	{
		mDynamicsWorld->stepSimulation(delta, 10);

		if(InputManager::getSingletonPtr()->getKeyboard()->isKeyDown(OIS::KC_F3))
		{
			mDebugDraw->step();
		}
	}
}
Create Cube...

Code: Select all

PhysicsObject* PhysicsManager::createCube(Ogre::SceneNode *boxNode)
{
	btCollisionShape *boxShape = new btBoxShape(btVector3(1,1,1));
	mCollisionShapes.push_back(boxShape);

	// Create Dynamic Objects
	btTransform startTransform;
	startTransform.setIdentity();

	btScalar mass(1.f);

	bool isDynamic = (mass != 0.f);

	btVector3 localInertia(0,0,-1);
	if(isDynamic)
	{
		boxShape->calculateLocalInertia(mass, localInertia);

		startTransform.setOrigin(btVector3(0,750,0));
		startTransform.setRotation(btQuaternion(btVector3(1.0, 1.0, 0.0), 0.6)); // Do this to give it a slight twist for effect

		MyMotionState *motionState = new MyMotionState(startTransform, boxNode);
		btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, boxShape, localInertia);
		btRigidBody *body = new btRigidBody(rbInfo);

		mDynamicsWorld->addRigidBody(body);
	}

	return NULL; //fix this to return proper object later
}
Create Heightfield...

Code: Select all

PhysicsObject* PhysicsManager::createHeightfieldShape(int size, float* data, const Ogre::Real& minHeight, const Ogre::Real& maxHeight, const Ogre::Vector3& position, const Ogre::Real& scale)
{
	// Convert height data in a format suitable for the physics engine
	float *terrainHeights = new float[size * size];
	assert(terrainHeights != 0);

    for (int i = 0; i < size; i++)
	{
		memcpy(terrainHeights + size * i, data + size * (size - i - 1), sizeof(float) * size);
	}

	btScalar heightScale = 1.f;
	btVector3 localScaling(scale, heightScale, scale);

	btHeightfieldTerrainShape *terrainShape = new btHeightfieldTerrainShape(size, size, terrainHeights, 1/*ignore*/, minHeight, maxHeight, 1, PHY_FLOAT, true);
	terrainShape->setUseDiamondSubdivision(true);
	terrainShape->setLocalScaling(localScaling);
	mCollisionShapes.push_back(terrainShape);

	//Create Rigid Body using 0 mass so it is static
	btRigidBody *body = new btRigidBody(INFINITE_MASS, new btDefaultMotionState(), terrainShape);
	body->setFriction(0.8f);
	body->setHitFraction(0.8f);
	body->setRestitution(0.6f);
	body->getWorldTransform().setOrigin(btVector3(position.x, position.y + (maxHeight - minHeight) / 2, position.z));
	body->getWorldTransform().setRotation(Convert::toBullet(Ogre::Quaternion::IDENTITY));
	body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);

	mDynamicsWorld->addRigidBody(body);

	return NULL; //fix this to return proper object later
}
SteveSegreto
Posts: 32
Joined: Sun Sep 12, 2010 10:25 am

Re: No Collision between Heightfield and Cube?

Post by SteveSegreto »

The issue is that changing the world transform of the heightfield will not work if the rigid body for it has been declared as btCollisionObject::CF_STATIC_OBJECT, try changing it to btCollisionObject::CF_KINEMATIC_OBJECT.
Brutal
Posts: 14
Joined: Mon Jul 26, 2010 8:03 am

Re: No Collision between Heightfield and Cube?

Post by Brutal »

Still falls through with it set to kinematic as well. There is a whole thread on bullet and terrain on the Ogre forums and all of them are using static object and worldTransform on the body without any issue, so I can't see why mine would be any different in that aspect. Anything else it could be?
SteveSegreto
Posts: 32
Joined: Sun Sep 12, 2010 10:25 am

Re: No Collision between Heightfield and Cube?

Post by SteveSegreto »

What broadphase algorithm do you use? My experience has shown that moving static rigid bodies by changing their world transforms does not work correctly because it confuses the axis sweep broadphase since the BVH hasn't been recomputed.

After changing to the DBVT broadphase and changing all the rigid body types to KINEMATIC, my problems went away.

Step through the code and figure it out for yourself.
Brutal
Posts: 14
Joined: Mon Jul 26, 2010 8:03 am

Re: No Collision between Heightfield and Cube?

Post by Brutal »

I use the btDbvtBroadphase. At risk of sounding like a complete moron, what should I be stepping through? This is my first time with Bullet and I am not sure what function I am supposed to be looking in at runtime. I don't think setting up a collision callback would be of much use since it isn't colliding, and I can't think of anywhere else to step through to find more information.
Brutal
Posts: 14
Joined: Mon Jul 26, 2010 8:03 am

Re: No Collision between Heightfield and Cube?

Post by Brutal »

Turns out the issue was my collision mesh for the cube was too small so it was just falling right through the heightmap. Thank you for the help.