btKinematicCharacterController, forward dir is not forward

konri100
Posts: 3
Joined: Sun Aug 25, 2013 10:44 pm

btKinematicCharacterController, forward dir is not forward

Post by konri100 »

So i've got problem with btKinematicCharacterController.

White lines are bullet debug lines.
Red arrow is where the forward dir is supposed to be.
Red lines is where the front of the object is supposed to be.
Green arrow is where the forward dir really is, at least in this direction the object is going to.

Ogre mesh has inverted rotation so it faces the right direction.

Image
Image
Image

Some code:

Code: Select all

    Ogre::Entity* ent = pSceneMgr->createEntity("SinbadBody", "Sinbad.mesh");
    Ogre::SceneNode* sphereNode = pSceneMgr->getRootSceneNode()->createChildSceneNode();
    sphereNode->attachObject(ent);
    Ogre::Vector3 halfsize = ent->getBoundingBox().getHalfSize();
    ent->setCastShadows(true);

    sphereNode->setPosition(0,20,0);

    btConvexShape* capsule = new btBoxShape(ToBullet(halfsize));
    characterBody = pBullet->addGhostObject(sphereNode->getPosition(), capsule, sphereNode);

    btScalar stepHeight = btScalar(0.35);
    Character = new btKinematicCharacterController(characterBody,capsule,stepHeight);
    Character->setJumpSpeed(15);
    pBullet->getWorld()->addCollisionObject(characterBody,btBroadphaseProxy::CharacterFilter,     btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
    pBullet->getWorld()->addAction(Character);
in main loop:

Code: Select all

//character
    Ogre::SceneNode* characterNode = (Ogre::SceneNode*)(characterBody->getUserPointer());

    bool forward = false, backward = false, left = false, right = false, jump = false;

    if(pKeyboard->isKeyDown(OIS::KC_A))
    {
        left = true;
    }
    else if(pKeyboard->isKeyDown(OIS::KC_D))
    {
        right = true;
    }

    if(pKeyboard->isKeyDown(OIS::KC_W))
    {
        forward = true;
    }
    else if(pKeyboard->isKeyDown(OIS::KC_S))
    {
        backward = true;
    }
    if(pKeyboard->isKeyDown(OIS::KC_SPACE))
    {
        jump = true;
    }

    btTransform xform;
    xform = characterBody->getWorldTransform();

    btVector3 forwardDir = xform.getBasis()[2];
    btVector3 upDir = xform.getBasis()[1];
    btVector3 strafeDir = xform.getBasis()[1];
    forwardDir.normalized();
    upDir.normalized();
    strafeDir.normalized();
    btVector3 walkDirection(0,0,0);
    btScalar walkVelocity(1.1*8.0);// 4 km/h -> 1.1 m/s
    btScalar walkSpeed(walkVelocity*(DeltaTime/1000.0f));

    Ogre::SceneNode* node = static_cast<Ogre::SceneNode*>(characterBody->getUserPointer());

    if(left)
    {
        turnAngle -= DeltaTime * 0.003f;
    }

    if(right)
    {
        turnAngle += DeltaTime * 0.003f;
    }
    xform.setRotation(btQuaternion (btVector3(0.0, 1.0, 0.0), turnAngle));
    characterBody->setWorldTransform (xform);

    //here is inverted(?) turnAngle of ogre mesh, so it faces the right direction that the bullet kinematic character is going to
    node->setOrientation(Ogre::Quaternion(-(Ogre::Radian)turnAngle, Ogre::Vector3(0.0, 1.0, 0.0)));

    if(forward)
    {
        walkDirection += forwardDir;
    }

    if(backward)
    {
        walkDirection -= forwardDir;
    }

    if(jump && Character->canJump())
    {
        Character->jump();
    }

    Character->setWalkDirection(walkDirection * walkSpeed);
in main loop:

Code: Select all

    World->stepSimulation(Delta, 60);

    for(list<btRigidBody*>::iterator It = Objects.begin(); It != Objects.end(); ++It)
    {
        Ogre::SceneNode* node = static_cast<Ogre::SceneNode*>((*It)->getUserPointer());

        btVector3 Point = (*It)->getCenterOfMassPosition();
        node->setPosition(Ogre::Vector3((float)Point[0], (float)Point[1], (float)Point[2]));

        btQuaternion btq = (*It)->getOrientation();
        Ogre::Quaternion quart = Ogre::Quaternion(btq.w(),btq.x(),btq.y(),btq.z());
        node->setOrientation(quart);

	}

	for(list<btPairCachingGhostObject*>::iterator it = GhostObjects.begin(); it != GhostObjects.end(); ++it)
    {
		Ogre::SceneNode* node = static_cast<Ogre::SceneNode*>((*it)->getUserPointer());
        btVector3 Point = (*it)->getWorldTransform().getOrigin();
        node->setPosition(Ogre::Vector3(Point[0], Point[1], Point[2]));
	}

	World->debugDrawWorld();
EDIT:

I did some more tests and here is the code that works perfectly, but i get forward dir not from bullet but from ogre, so maybe i did something wrong with bullet or the forward dir from bullet is wrong:

Code: Select all

    btTransform xform;
    xform = characterBody->getWorldTransform();

    btVector3 walkDirection(0,0,0);
    btScalar walkVelocity(1.1*8.0);// 4 km/h -> 1.1 m/s
    btScalar walkSpeed(walkVelocity*(DeltaTime/1000.0f));

    Ogre::SceneNode* node = static_cast<Ogre::SceneNode*>(characterBody->getUserPointer());
    btVector3 forwardDir = ToBullet(node->getOrientation() * Ogre::Vector3(0, 0, 1));
    forwardDir.normalized();

    if(left)
    {
        turnAngle += DeltaTime * 0.003f;
    }

    if(right)
    {
        turnAngle -= DeltaTime * 0.003f;
    }
    xform.setRotation(btQuaternion (btVector3(0.0, 1.0, 0.0), turnAngle));
    characterBody->setWorldTransform (xform);

    if(forward)
    {
        walkDirection = forwardDir;
    }

    if(backward)
    {
        walkDirection = -forwardDir;
    }

    if(jump && Character->canJump())
    {
        Character->jump();
    }

    Character->setWalkDirection(walkDirection * walkSpeed);
in main loop:

Code: Select all

    for(list<btPairCachingGhostObject*>::iterator it = GhostObjects.begin(); it != GhostObjects.end(); ++it)
    {
		Ogre::SceneNode* node = static_cast<Ogre::SceneNode*>((*it)->getUserPointer());
        btVector3 Point = (*it)->getWorldTransform().getOrigin();
        node->setPosition(Ogre::Vector3(Point.getX(), Point.getY(), Point.getZ()));

        btQuaternion btq = (*it)->getWorldTransform().getRotation();
        Ogre::Quaternion quart = Ogre::Quaternion(btq.w(),btq.x(),btq.y(),btq.z());
        node->setOrientation(quart);
	}
So did i just get forward dir from bullet in wrong way or it's buggy?