btKinematicCharacterController

meuns
Posts: 5
Joined: Wed Sep 29, 2010 3:05 pm

btKinematicCharacterController

Post by meuns »

Hi,

I tested the btKinematicCharacterController class, made some code cleanups, added a second colliding object and adapted the simple character demo for loading an obj, controlling the scale of the scene and various constants and fixed some GL stuffs.

The second colliding object (a capsule in my test) if used for recovering from the penetrations while the first (a slightly bigger capsule) is used for stepping on the ground.
It helped me for reducing the shaking character problem.

I created a patch with Subversion from the revision 2211 (see the linked file, maybe it can be useful).

Thanks
You do not have the required permissions to view the files attached to this post.
SteveSegreto
Posts: 32
Joined: Sun Sep 12, 2010 10:25 am

Re: btKinematicCharacterController

Post by SteveSegreto »

This sounds like a great idea, I just increased the size of the ghost object capsule for my kinematic controller and I was able to "climb" steps again, but I like the idea of using two ghost objects, because I really didn't want the character to be that big just so he could climb (because then he has trouble squeezing through doors).

Can you post the modified files in addition to the patch? I can't get access to SVN from work, but I'd like to take a look at this?
meuns
Posts: 5
Joined: Wed Sep 29, 2010 3:05 pm

Re: btKinematicCharacterController

Post by meuns »

I hope i didn't forget some files.
You do not have the required permissions to view the files attached to this post.
Brutal
Posts: 14
Joined: Mon Jul 26, 2010 8:03 am

Re: btKinematicCharacterController

Post by Brutal »

Very cool, thank you for this. I am just about to add a Kinematic Character Controller to my project, and I was worried because everything I read says "stay away from it". Most of this stuff is from a year or two ago though so I am assuming it is pretty stable for usage now?
meuns
Posts: 5
Joined: Wed Sep 29, 2010 3:05 pm

Re: btKinematicCharacterController

Post by meuns »

Not really stable but you can use it with some "tuned" settings and scenes.
Brutal
Posts: 14
Joined: Mon Jul 26, 2010 8:03 am

Re: btKinematicCharacterController

Post by Brutal »

Thank you :) I had added another CharacterController from a different thread here yesterday, but after Steve mentioned this one (atleast I think he was saying he used this one) I checked it out, and decided to switch. I am running into one problem I wanted to ask about though. In your initPhysics() you are using your world size vectors, and scaleGeometry. I am using Ogre's new paging terrain system, so I don't really have a defined world size to use.

I am using mOverlappingPairCache = new btDbvtBroadphase(pairCache); instead of btAxisSweep3 so I didn't need to pass that data in there. However, in my character controller creation function, it is referring back to this quite a bit, so what exactly should I do?

Here is my relevant code thus far, it is not completely functional yet

Code: Select all

void PhysicsManager::init(Ogre::SceneManager *sceneMgr)
{
	mDynamicsWorld = NULL;

	// Compute and cache all the object pairs possibly colliding
	btOverlappingPairCache *pairCache = new btSortedOverlappingPairCache();
	pairCache->setInternalGhostPairCallback(new btGhostPairCallback());

	mOverlappingPairCache = new btDbvtBroadphase(pairCache);
	mCollisionConf = new btDefaultCollisionConfiguration();
	mDispatcher = new btCollisionDispatcher(mCollisionConf);
	mSolver = new btSequentialImpulseConstraintSolver;

    // The world
    mDynamicsWorld = new btDiscreteDynamicsWorld(mDispatcher, mBroadphase, mSolver, mCollisionConf);
    mDynamicsWorld->setGravity(btVector3(0,-10,0));

	//mDynamicsWorld->getPairCache()->setOverlapFilterCallback( new MyFilterCallback() );
	//btContactSolverInfo& info = mDynamicsWorld->getSolverInfo();
	//info.m_numIterations = 10;

	// Debug Draw
	mDebugDraw = new DebugDraw(sceneMgr->getRootSceneNode(), mDynamicsWorld);
	mDynamicsWorld->setDebugDrawer(mDebugDraw);

	// Physics World is Active
	m_bActive = true;
}

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

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

Code: Select all

CharacterController* PhysicsManager::createCharacterController()
{
	// Capsule is at the Origin
	btTransform transform;
	transform.setIdentity();

	// External Ghost Capsule
	mExternalGhostObject = new btPairCachingGhostObject();
	mExternalGhostObject->setWorldTransform(transform);

	btScalar externalCapsuleHeight = 1.8;
	btScalar externalCapsuleWidth = 0.5;

	mExternalCollisionShape = new btCapsuleShape(scaleGeometry * externalCapsuleWidth, scaleGeometry * externalCapsuleHeight);
	mExternalCollisionShape->setMargin(0.04);

	mExternalGhostObject->setCollisionShape(externalCollisionShape);
	mExternalGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);

	// Internal Ghost Capsule
	mInternalGhostObject = new btPairCachingGhostObject();
	mInternalGhostObject->setWorldTransform(transform);
	
	btScalar internalCapsuleHeight = scaleGeometry * 1.8;
	btScalar internalCapsuleWidth = scaleGeometry * 0.45;

	mInternalCollisionShape = new btCapsuleShape(internalCapsuleWidth, internalCapsuleHeight);
	mInternalCollisionShape->setMargin( 0.04 );

	mInternalGhostObject->setCollisionShape(mInternalCollisionShape);
	mInternalGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);

	// Create Character Controller
	mCharacter = new CharacterController(mExternalGhostObject, mInternalGhostObject, btScalar(scaleGeometry * 0.4), scaleGeometry);

	// Add Ghost Capsule's and Character Controller to the World
	mDynamicsWorld->addCollisionObject(mExternalGhostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
	mDynamicsWorld->addCollisionObject(mInternalGhostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
	mDynamicsWorld->addAction(mCharacter);

	return mCharacter;
}
meuns
Posts: 5
Joined: Wed Sep 29, 2010 3:05 pm

Re: btKinematicCharacterController

Post by meuns »

scaleGeometry is just an attribute for testing Bullet at various world scale (and cursing the hard coded constants, float precision problems...). You should just consider scaleGeometry is 1.f and remove it from your application. , If you consider 1 meter is 1 Bullet unit, there is "no problem" for colliding with relatively small terrains.
Brutal
Posts: 14
Joined: Mon Jul 26, 2010 8:03 am

Re: btKinematicCharacterController

Post by Brutal »

Thank you, that through me off a little bit but makes sense now. I do have one more question for you if you don't mind. I am still extremely new to Bullet, and I have basically just copy/pasted your Character Controller so I could get it working, then go through and figure out what everything is doing to learn from.

With dynamic objects, I was able to create my own MotionState class, and use that to update the relevant SceneNode's in Ogre (so that my Ogre .mesh files would have accurate positions based on the collision objects). I started looking into attaching my Player model to the Character Controller last night, and realized it doesn't use a MotionState, but uses the btActionInterface instead. What would be the best way to sync up the actual model with the character controller? I assume I just need to add some sort of getPosition() function to the Character Controller to call from my Ogre code. I figured I would ask as I like to be as efficient as possible even when learning (bad habits die hard, best not to start them lol).

Thank you again!
meuns
Posts: 5
Joined: Wed Sep 29, 2010 3:05 pm

Re: btKinematicCharacterController

Post by meuns »

I just made some tests with the collision system proposed by Bullet and ignored the interactions between the character and the world.