Archive 17/01/2023.

Kinematic character control with Bullet

mazataza

i am trying to implement character control with bullet
i use the following code to initialise the ghost object

const Vector3 &postion = _cameraNode->GetWorldPosition();
const Quaternion &rot = _cameraNode->GetWorldRotation();
startTransform.setOrigin (ToBtVector3(postion + rot * Vector3::ZERO));
startTransform.setRotation(ToBtQuaternion(rot));
physicsWorld_->GetWorld()->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
ghostObject = new btPairCachingGhostObject();
ghostObject->setWorldTransform(startTransform);
btScalar characterHeight=1;
btScalar characterWidth =0.5;
ghostShape = new btCapsuleShape(characterWidth,characterHeight);
ghostObject->setCollisionShape (ghostShape);
ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);

btScalar stepHeight = btScalar(0.35);
btVector3 up(0.0,1.0,0.0);
characterController = new btKinematicCharacterController (ghostObject,ghostShape,stepHeight, up);

but then the ghost has rotation in x-axis which i can’t understand

i update the node transform like

btTransform &worldTrans = ghostObject->getWorldTransform();
Quaternion newWorldRotation = ToQuaternion(worldTrans.getRotation());
const Vector3 &rot = newWorldRotation * Vector3::ZERO;
Vector3 newWorldPosition = ToVector3(worldTrans.getOrigin()) - rot;

_cameraNode->SetWorldPosition(newWorldPosition);
_cameraNode->SetWorldRotation(newWorldRotation);

the rotatotion matrix is
w= 0.7
x= -0.7
y=0
z=0

this what without appling transformation
urho3d_cc1

and this with transformation
urho3d_cc2

when i dont set UP vector to (0.0,1.0,0.0) the character fall in x-axis

i will be happy if someone can guide me what i am doing wrong.

Modanung

The first thing I notice is:

and

Rotating a { 0, 0, 0 } vector (which is what Vector3::ZERO is) will always return a zero vector.
You’ll probably want to replace ZERO with FORWARD or BACK.

Also, what’s the _cameraNode's rotation at this point?

…since it’s rotation relies on the ghost object’s rotation.

I must add I have hardly any experience with directly using bt objects.

mazataza

the rotation is zero (w=1 x=0 y=0 z=0)

no it is {0 1 0} (x y z)

Modanung

Check :white_check_mark:

mazataza

i don’t understand what you mean but here can check the coordinate system on bullet

http://bulletphysics.org/mediawiki-1.5.8/index.php/Coordinate_system

Modanung

I meant you’re right. :slight_smile:

mazataza

the problem i found that when i set

ghostObject->setWorldTransform(startTransform);

before the kinematic controller this got rotated because the up vector got changed

but when i set after creation of kinematic the rotation doesn’t done, and the character can now move, but i have some trouble but i will check if i could solve them by myself

Modanung

Glad to hear you’re making progress.

mazataza

I still stuck with the conversion betweeen bullet to urho3d… as i know bullet use right hand coordinate and urho3d use left hand.
the following code which i use at first to update ghostobject walking direction

    btTransform xform;
    xform = ghostObject->getWorldTransform ();
    btVector3 forwardDir = xform.getBasis()[2];
    forwardDir.normalize ();
    ....
    btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
    ...
    if (gForward) {
        walkDirection += forwardDir;
    }
    ...
    characterController->setWalkDirection(walkDirection*walkSpeed);

this code works when there is no rotation. if there is a rotation then the object move very strange for me
now i use following code and it works but i can’t understands why it works and that what I don’t like - to have a code which i can’t understand totaly.

  btTransform xform;
  xform = ghostObject->getWorldTransform ();
  Quaternion newWorldRotation = ToQuaternion(xform.getRotation());
  const Vector3 &forwardDir= newWorldRotation * Vector3::FORWARD;
  
  if (gForward) {
    walkDirection += forwardDir;
  }
  ...
  characterController->setWalkDirection(walkDirection*walkSpeed);

as you see i use urho3d quaterion and calculate forward direction.

then i use following code to update character node in urho3d

btTransform &worldTrans = ghostObject->getWorldTransform();
Quaternion newWorldRotation = ToQuaternion(worldTrans.getRotation());
const Vector3 &rot = newWorldRotation * Vector3::FORWARD;
Vector3 newWorldPosition = ToVector3(worldTrans.getOrigin()) - rot;

_cameraNode->SetWorldPosition(newWorldPosition);
_cameraNode->SetWorldRotation(newWorldRotation);

if someone can explain me how urho3d handle these differences between bullet and urho3d i will be happy

1vanK

Kinematic Character Controllers

mazataza

thank you for the link…
i have some question there but i will write them there