I was happy to set up physics under Bullet to drive the kinematic bodies around via a custom MotionState,
But when it came to finding collisions between two kinematic bodies, I was deeply depressed.
You see, Bullet does not apply physics response forces to kinematic bodies.. only dynamic ones (the third type, static, are not even worth mentioning). Since it doesn't need a response, it won't bother to generate any contacts for those collisions. So you can't use a 'OnContactSomething' callback to receive notification of a collision.. you are left with having to poll for it, or you will never know it happened. I guess that Erwin expected that there will only ever be one kinematic body and it's your guy smashing stuff out of the way? Not good enough.
So why were we using kinematic bodies in the first place, if dynamic bodies generate contacts like we wanted? Because you can't directly control dynamic bodies as such - you have to use forces to push them around, and this doesn't give you a reliable control mechanism when you just wanted to specify where something is at a particular time.
Our workaround was rather novel so I thought I would blog it here.
For each animation-driven kinematic body, glued to some bone (joint) by a MotionState, we would create a dynamic body, which shared the same CollisionShape, had the same world translation and orientation, and had the same local origin/pivot - and we would then create a constraint to glue the dynamic child to the kinematic parent.
We used a "Generic 6DOF" constraint, with "all degrees of freedom locked" to basically transfer motion from the kinematic body to the dynamic one.
This made the collision pipeline go absolutely crazy (debug build) since there was some bodies that are always 'perfectly intersecting' - the GJK separation solver runs about 1000 iterations per frame and keels over, ugh this is not good...
Then we used the most coarse level of collision filtering offered ('Collision Groups' basically) to eliminate the kinematic bodies from the collision pipeline, leaving only the dynamic ones to collide.
Now we were able to 'directly' drive dynamic bodies from outside the simulator, as well as rely on the contact callback notification of the collision event(s).