btkinematiccharactercontroller -> coll.shape rotates wrong

whisp
Posts: 5
Joined: Sun Apr 01, 2012 5:17 pm

btkinematiccharactercontroller -> coll.shape rotates wrong

Post by whisp »

I've recently implemented a character controller, using the code from the Bullet charctercontroller demo.

Yet there's a somewhat strange problem:

The character has a speed and a rotation. When hitting the forward key it moves forward, when hitting the left key, it rotates left. When hitting both, forward and left, it will move a circle, i'll call it move-circle, finally arriving at the same position where it started.

It will do this move-circle in a counter-clockwise direction, when i hit the left key while moving forward. But the collisionshape rotates clockwise. And vice-versa, if i hit forward and right, the move-circle will be clockwise, as intended, but the collisionshape will rotate counter-clockwise. So basically the ghostobject and the collisionshape rotate in two different directions instead the same. This only applies to rotation, the position is correct.

The rotation is done with only this three lines of code, so actually only rotates the ghostobject:

Code: Select all

btMatrix3x3 orn = mGhostObject->getWorldTransform().getBasis();
orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0), dt * 1.57f));
mGhostObject->getWorldTransform ().setBasis(orn);
If i change the rotation to negative (e.g. by multiplying by -1.57f), the move-circle will change its direction, but also the collisionshape's rotation. So i don't manage to have the collisionshape rotate the same direction as the move-circle. But it should, in order to face the direction of the actual movement.

I can't figure out what i'm doing wrong, respectively how to change it to work right. Any ideas?

Thanks
whisp
whisp
Posts: 5
Joined: Sun Apr 01, 2012 5:17 pm

Re: btkinematiccharactercontroller -> coll.shape rotates wro

Post by whisp »

This is a link to a youtube video of the problem: http://www.youtube.com/watch?v=mfYoeylh ... e=youtu.be
You will have to play it fullscreen to be able to see the collision-shape.

It might seem obvious to just rotate the ghostobject in the other direction in order to meet the collisionshape's rotation. This would however cause the ghostobject to move a clockwise circle while the collisionshape would start rotating left.

This is the code responsible for the movement:

Code: Select all

void ControlledObject::doMovement(float deltaTimeS)
{
	float dt = deltaTimeS;

	if (mPhysics->getDynamicsWorld())
	{
		btTransform xform;
		xform = mGhostObject->getWorldTransform ();

		Ogre::Vector3 position = btToOgreV3(xform.getOrigin());

		btVector3 forwardDir = xform.getBasis()[2];
		btQuaternion rot = xform.getRotation();
		forwardDir.normalize ();

		btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
		btScalar walkVelocity = btScalar(1.1) * 4.0; // 4 km/h -> 1.1 m/s
		btScalar walkSpeed = walkVelocity * dt;

		if (mLeft)
		{

			btMatrix3x3 orn = mGhostObject->getWorldTransform().getBasis();
			orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0), dt * -1.57f));
			mGhostObject->getWorldTransform ().setBasis(orn);
		}

		if (mRight)
 		{
			btMatrix3x3 orn = mGhostObject->getWorldTransform().getBasis();
			orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0), dt * 1.57f)); //Rotation in RAD (1.57 ~ 90°)
			mGhostObject->getWorldTransform ().setBasis(orn);
		}

		if (mForward)
			walkDirection += forwardDir;

		if (mBackward)
			walkDirection -= forwardDir;

		mCharacter->setVelocityForTimeInterval(walkDirection*walkVelocity, dt );

		mSceneNode->setOrientation(-rot.getW(), rot.getX(), rot.getY(), rot.getZ());
		mSceneNode->setPosition(position);
	}
}
Thanks for any hints.

whisp