c++collision-detectionphysics-enginebulletphysicsbullet

Bullet Physics resetting rigidbody origin after manually setting


Working on a character controller in Bullet Physics engine that uses a rigidbody, specifically crouch functionality. I've run into an issue where Bullet is resetting the origin of the world transform for the body back to what it was before I set it manually. This appears to be happening when stepSimulation() is called. It feels like there may be a parameter that I'm not setting, although what it could be evades me at this time. I have uploaded the following video which shows exactly what I'm trying to explain:

Below is the code where I'm scaling the collision object and transforming the rigidbody origin:

if (this->input.keyLeftControl && !this->crouching)
{
    this->crouching = true;

    //Set scale
    btVector3 scale = this->clientBody->getCollisionShape()->getLocalScaling();
    scale.setY(crouchScale);
    this->clientBody->getCollisionShape()->setLocalScaling(scale);
    this->ghostObject->getCollisionShape()->setLocalScaling(scale);
    this->collisionWorld->dynamicsWorld->updateSingleAabb(this->clientBody);


    auto clientOrigin = this->clientBody->getWorldTransform().getOrigin();
    btVector3 newOrigin = btVector3(clientOrigin.getX(), clientOrigin.getY() - 0.525, clientOrigin.getZ());
    clientBody->getWorldTransform().setOrigin(newOrigin);
    this->ghostObject->getWorldTransform().setOrigin(newOrigin);    
}

After this code executes, the origin is correct until stepSimulation() executes, at which point the rigidbody object is transformed back to the origin it was at prior to the above code block being executed.

Is there anything glaringlyobvious that stands out to anyone that I may be overlooking?


Solution

  • Resolved this by completely removing, resetting, and readding the rigid body to the dynamics world via the following:

    if (this->input.keyLeftControl && !this->crouching)
    {
        this->crouching = true;
        this->crouchNeedFall = true;
    
        //Set scale
        btVector3 scale = this->clientBody->getCollisionShape()->getLocalScaling();
        scale.setY(crouchScale);
        this->clientBody->getCollisionShape()->setLocalScaling(scale);
        this->ghostObject->getCollisionShape()->setLocalScaling(scale);
        this->collisionWorld->dynamicsWorld->updateSingleAabb(this->clientBody);
    
        auto clientOrigin = this->clientBody->getWorldTransform().getOrigin();
        btVector3 newOrigin = btVector3(clientOrigin.getX(), clientOrigin.getY() - 0.525, clientOrigin.getZ());
    
        this->collisionWorld->dynamicsWorld->removeRigidBody(this->clientBody);
    
        this->clientBody->clearForces();
        this->clientBody->setLinearVelocity(btVector3(0, 0, 0));
        this->clientBody->setAngularVelocity(btVector3(0, 0, 0));
        this->clientBody->getWorldTransform().setOrigin(newOrigin);
    
        this->ghostObject->getWorldTransform().setOrigin(newOrigin);
    
        this->collisionWorld->dynamicsWorld->addRigidBody(this->clientBody);
    
    }