btKinematicCharacterController and dynamic rigid bodies.

Chitation
Posts: 1
Joined: Thu Nov 03, 2011 9:54 pm

btKinematicCharacterController and dynamic rigid bodies.

Post by Chitation »

I looked in the Bullet API in the btKinematicCharacterController section and it says "Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user."

I have been struggling with this for a while now because I am not sure how to implement this on my own. Right now the character I have implemented just stops when it hits a dynamic rigid body, but i would like to know how to move the rigid body based on its weight. Does anyone know a good way to implement this maybe with an example or just explain how I could achieve this?

Please let me know. Thank you very much!!!
gogiii
Posts: 8
Joined: Sat Oct 08, 2011 1:00 pm

Re: btKinematicCharacterController and dynamic rigid bodies.

Post by gogiii »

well, you can reject using kinematiccontroller and try to make your own.
I'm using something like this:

// creating character somewhere in sceneInit

Code: Select all

btVector3 localInertia(0,0,0);  // use zero inertia so the character won't be rotated by physics
btTransform startTransform = btTransform::getIdentity();
startTransform.setOrigin(x, y, z);
btDefaultMotionState *state = new btDefaultMotionState(startTransform);
btCapsuleShape *shape = new btCapsuleShape(0.2f, 0.05f);
btRigidBody* body = new btRigidBody(mass, state, shape, localInertia);
body->setFriction(0.5f); // this will help to move stairs later
// movement processing somewhere in sceneRender

Code: Select all

if(keyPress(MOVE_FORWARD)) {

  body->activate(true);  // activate him each frame so he won't stuck

  // process some turning/rotation of your character like
  btTransform xform = ...;
  xform.setRotation(btQuaternion(yaw ..., 0, 0));
  body->setWorldTransform(xform); // apply rotation

  // apply velocity to move in forward direction
  body->setLinearVelocity(xform.getBasis().transpose()[2]*df*70);

  // check if we need to drop him to floor
  btVector3 origin = xform.getOrigin();
  // this is just wrapped raytest with ClosestRayCallback
  if(!rayTest(m_dynamicsWorld, origin, origin + btVector3(0,-0.4,0)).hasHit()) { 
	  body->applyCentralImpulse(btVector3(0,-50,0));
  }

} else {
   // well as you see I use small friction so such character will make some ice sliding on floor by default
   // so I just slide him backwards when depending on current velocity
   btVector3 antislide = pbody->getLinearVelocity()*3;
   antislide.setY(0);
   body->applyCentralImpulse(antislide);
}
I should note that in case of not specifying inertia for a character you should follow few tips:
- getting current objects' transforms by: body->getmotionstate()->getworldtransform
- but SETTING transforms with: body->setworldtransform (not through the motionstate)
if you won't follow these tips then it will rotate fine until you apply velocity and when applied velocity it will stuck in last rotation
don't know about the activation but in my case (world is trimesh) it has been stucking until being activated each frame.