[SOLVED] btKinematicCharacterController: reference?

Latin1
Posts: 6
Joined: Mon Aug 01, 2011 10:16 pm

[SOLVED] btKinematicCharacterController: reference?

Post by Latin1 »

Hello,

As a novice with Bullet physics (2.79), I've managed to build a few basic applications using Bullet and the Ogre rendering engine. I'm posting to find out how to create a character who can move on heightfield-based terrain and collide with static scenery and kinematic objects.

In the forums, I've often seen it recommended to use the btKinematicCharacterController class rather than btRigidBody. However, I've found very little information on this class beyond its modest reference page and somewhat lightly commented source code. I've examined the Character demo, but like the other demos it mixes Bullet code with OpenGL, of which I know nothing at all.

Is there a reference somewhere that explains the basic structure and functions of btKinematicCharacterController?

It seems to be quite a popular class, so I feel it would help many others as well. If there is no outside documentation, would it be possible to add brief descriptions of the functions in the API reference? It may be simple for some to understand what a given function does and how to use it, but beginners don't necessarily know about all the implications of using a particular class.

Thank you, I've already seen just how powerful Bullet is, and I'm very excited to learn more about it.
Last edited by Latin1 on Tue Nov 29, 2011 4:52 pm, edited 2 times in total.
Martin Felis
Posts: 13
Joined: Sat Oct 29, 2011 9:32 pm

Re: btKinematicCharacterController: reference?

Post by Martin Felis »

Hi Latin1,

just recently I went through the code and tried to extend the documentation for both the interface and the code itself. You can find it at:
https://github.com/martinfelis/bulletphysics2.

You can use http://doxygen.org to create reference pages which will contain more documentation for the btKinematicCharacterController.

Cheers,
Martin
Latin1
Posts: 6
Joined: Mon Aug 01, 2011 10:16 pm

Re: btKinematicCharacterController: reference?

Post by Latin1 »

Outstanding, thank you! I've just looked through the header file and the usage seems much clearer now.

If I may, I'd like to ask two questions to make things a bit clearer:

1. From what I've read, a ghost object is basically a body that doesn't collide with anything; it's usually used as a sensor of sorts, to trigger an event when something goes through it. What precisely does the class need it for?

2. The setWalkDirection() method doesn't look like it takes gravity into account. How can I apply the gravity on the object constantly, whether it is moving or not? (Does updateAction() take care of this?)

I don't ask for full, detailed answers, because I plan to test out the class shortly, but any insight you can offer will be much appreciated.

Thanks again for the commented code :D .
Martin Felis
Posts: 13
Joined: Sat Oct 29, 2011 9:32 pm

Re: btKinematicCharacterController: reference?

Post by Martin Felis »

Latin1 wrote:1. From what I've read, a ghost object is basically a body that doesn't collide with anything; it's usually used as a sensor of sorts, to trigger an event when something goes through it. What precisely does the class need it for?
Correct.
Latin1 wrote:2. The setWalkDirection() method doesn't look like it takes gravity into account. How can I apply the gravity on the object constantly, whether it is moving or not? (Does updateAction() take care of this?)
Gravity is taken into account in function btKinematicCharacterController::playerStep() fairly at the beginning. The vertical velocity is adjusted so that it also contains the integrated value of the acceleration:

Code: Select all

m_verticalVelocity -= m_gravity * dt;
The function setWalkDirection() simply is used to tell bullet where the character intends to go. Bullet itself then takes care of the physical interpretation of it.
Latin1 wrote:Thanks again for the commented code :D .
I'm glad it was worth it :) .
Latin1
Posts: 6
Joined: Mon Aug 01, 2011 10:16 pm

Re: btKinematicCharacterController: reference?

Post by Latin1 »

To go back to the first question - is the ghost object just there to check for collisions? I think so, seeing as it's the ghost, not the controller, that receives the collision shape and flags.

Also, on the subject of collision flags, I have one more question.

I've managed to add the kinematic controller to my discrete dynamics world, and the gravity seems to be working well. There's only one problem: no collision detection. I basically started with the Character demo's code, which gives the ghost object a collision flag, then one filter group and two filter masks when it's added to the world:

Code: Select all

mGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);

/*...*/

mDynWorld->addCollisionObject(mGhostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
The character falls through three rigid bodies with zero mass each. I tried adding the CF_CHARACTER_OBJECT flag to those bodies, but it didn't change anything; I think I must be missing something about collision flags.

Is there a particular flag I need to attribute to the other rigid bodies, or is there something else I need to do?

I feel like this is the last piece of the puzzle, at least for what I'm trying to do right now.


Edit:

I've done a test with a dynamic rigid body, and as with regular kinematic bodies, it is pushed by the kinematic character controller (and collides with the other bodies).

I remember reading two things about the class in btKinematicCharacterController.h:
  • "It uses a ghost object and convex sweep test to test for upcoming collisions."
  • "Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicitly implemented by the user."
I'm starting to get an idea of what the ghost object is for; I guess I'm just not quite sure what to do with it.
Latin1
Posts: 6
Joined: Mon Aug 01, 2011 10:16 pm

Re: btKinematicCharacterController: reference?

Post by Latin1 »

Okay. It seems there are two reasons the character goes through certain objects.

1. I didn't realize I had to register a "ghost pair callback" at the start of the application for the ghost object to be updated every simulation tick :

Code: Select all

broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
2. Once I added the callback, collision started working with the rigid body that had been created from a btBoxShape. The two other rigid bodies (which the object still goes through) are not primitive convex shapes like the cube. One is a btStaticPlaneShape, and the other is a btHeightfieldTerrainShape. When I changed the shapes to simple boxes, the kinematic character controller's ghost object detected collisions with them.

I keep hearing that btKinematicCharacterController is still very experimental, so I suppose that might be the root of these problems, but I hope there's a way to get it working. If I find one, I'll post it here.

If anyone else knows how to make a btKinematicCharacterController collide with a rigid body based on a btStaticPlaneShape or a btHeightfieldTerrainShape, please post it. Thank you.
Latin1
Posts: 6
Joined: Mon Aug 01, 2011 10:16 pm

Re: btKinematicCharacterController: reference?

Post by Latin1 »

Solution: I needed to set the btGhostPairCallback right after the broadphase was initialised:

Code: Select all

broadphase = new btDbvtBroadphase();

// Add this IMMEDIATELY after the broadphase's initialisation, not later on
broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
Don't know why the collision still worked with the cube shape.

Thank you Martin Felis, for helping me figure out the character controller.
Martin Felis
Posts: 13
Joined: Sat Oct 29, 2011 9:32 pm

Re: [SOLVED] btKinematicCharacterController: reference?

Post by Martin Felis »

Hi Latin1,

Wow, seems you solved most problems yourself. But I am still very glad the documentation was of help.

Martin