Implement a Character Controller

Post Reply
Smjert
Posts: 6
Joined: Tue Sep 01, 2009 5:18 pm

Implement a Character Controller

Post by Smjert »

I really don't know how to implement it.
I know that there's the demo but.. the code isn't commented so it doesn't explain why something has been done like that etc.
Also why some functions like preStep and playerStep are re-implemented?

I didn't found any docs.. where i'm supposed to see to understand how to create a character controller? (also how to handle the dynamics of a character body?).
Thnx..
Smjert
Posts: 6
Joined: Tue Sep 01, 2009 5:18 pm

Re: Implement a Character Controller

Post by Smjert »

There's a thing i cannot understand, starting from line 72 of CharacterDemo.cpp there's:

Code: Select all

#ifdef DYNAMIC_CHARACTER_CONTROLLER
	m_character = new DynamicCharacterController ();
#else
	
	btTransform startTransform;
	startTransform.setIdentity ();
	startTransform.setOrigin (btVector3(0.0, 4.0, 0.0));

	m_ghostObject = new btPairCachingGhostObject();
	m_ghostObject->setWorldTransform(startTransform);
	sweepBP->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
	btScalar characterHeight=1.75;
	btScalar characterWidth =1.75;
	btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight);
	m_ghostObject->setCollisionShape (capsule);
	m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);

	btScalar stepHeight = btScalar(0.35);
	m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight);
#endif
Then at line 226 there's this line:

Code: Select all

xform = m_ghostObject->getWorldTransform ();
If i define DYNAMIC_CHARACTER_CONTROLLER how it is possible that it use m_ghostObject? (is not istanced anywhere else and there's no other pre-processors to stop compiling that code).
Moreover in the header there's:

Code: Select all

#ifdef DYNAMIC_CHARACTER_CONTROLLER
	btCharacterControllerInterface* m_character;
#else
	btKinematicCharacterController* m_character;
	class	btPairCachingGhostObject* m_ghostObject;
#endif
So if the pre-processors is defined m_ghostObject is even not defined?!?!?

How this could work??
And what m_ghostObject is for?
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Implement a Character Controller

Post by Flix »

I'm not an expert about the character controller, but I think that in that demo, only the kinematic character controller works (i.e. you shouldn't define DYNAMIC_CHARACTER_CONTROLLER).

About the ghost object, it seems to be used to handle the collisions between the character and the other bodies (there must be a method called recoverFromCollisions(...) or something like that inside the character controller class in the Bullet library itself to do that).

AFAIK kinematic character controllers perform better than dynamic ones because you can move them directly assigning their transform (so there is a better control on their position); since these objects must be able to collide with both static and dynamic objects they must do it through a ghost object. Anyway I think you can always use a normal rigid body instead of a kinematic character controller, if you feel more confortable with it (a rigid body collides with both static and dynamic bodies by default: no need for a ghost object in this scenario).

I don't have good advices for you on how to use it: I'd stick to the demo, trying to reproduce the same behavior.

Hope it helps.
Smjert
Posts: 6
Joined: Tue Sep 01, 2009 5:18 pm

Re: Implement a Character Controller

Post by Smjert »

Well yes, it was helpful.
So now i can understand which function of KinematicCharacterController is used to move it.. and what to prepare.. thnx
Smjert
Posts: 6
Joined: Tue Sep 01, 2009 5:18 pm

Re: Implement a Character Controller

Post by Smjert »

Ah just a little thing.. is every Bullet header file safe to be included somewhere without other dependancies?.
Because if this is true, btKinematicCharacterController.h uses btConvexShape in it but it doesn't include the header (so everytime i include one i need to include btConvexShape before it).
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: Implement a Character Controller

Post by sparkprime »

That is probably a bug
lathe
Posts: 2
Joined: Thu Oct 29, 2009 10:33 pm

Re: Implement a Character Controller

Post by lathe »

hey I'm having some difficulty with the KinematicCharacterController, it seems to ignore rigid bodies in my dynamicsWorld.

I have a character setup ripped from the CharacterDemo.cpp I also have the HelloWorld code for the static rigid body plane and the nonstatic cube that falls on it (cube falls and bounces off the plane just fine).

The ghostObject tied to the the KinematicCharacterController objeys the gravity but does not collide with the floor plane. Ideas? I must be missing something but I've stared at the CharacterDemo and forums long enough to need another perspective

here is the setup for the kinematic body

Code: Select all

	// make the character
    	{
			btTransform startTransform;
			startTransform.setIdentity ();
			startTransform.setOrigin (btVector3(0.0, 80.0, 0.0));
			btAxisSweep3* sweepBP = new btAxisSweep3(worldMin,worldMax);
			m_overlappingPairCache = sweepBP;


			m_ghostObject = new btPairCachingGhostObject();
			m_ghostObject->setWorldTransform(startTransform);
			sweepBP->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
			btScalar characterHeight=1.75;
			btScalar characterWidth =1.75;
			btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight);
			m_ghostObject->setCollisionShape (capsule);
			m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);
			btScalar stepHeight = btScalar(0.35);
			m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight);

	        ///only collide with static for now (no interaction with dynamic objects)
	        dynamicsWorld->addCollisionObject(m_ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
	        dynamicsWorld->addAction(m_character);
    	}
and the code for the plane

Code: Select all

    	

       	// ground plane, 1500, 1500
       	btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(1500.),btScalar(1.),btScalar(1500.)));

       	collisionShapes.push_back(groundShape);

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

       	{
       		btScalar mass(0.);

       		//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);

       		//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
       		btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
       		btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
       		btRigidBody* body = new btRigidBody(rbInfo);

       		//add the body to the dynamics world
       		dynamicsWorld->addRigidBody(body);
       	}
lathe
Posts: 2
Joined: Thu Oct 29, 2009 10:33 pm

Re: Implement a Character Controller

Post by lathe »

Whoops, issue was that I had created a new overlappingPairCache that was not the one used to create the dynamics world.

within the character creation code this was not needed

Code: Select all

btAxisSweep3* sweepBP = new btAxisSweep3(worldMin,worldMax);
m_overlappingPairCache = sweepBP;
Post Reply