问题描述
在Bullet Physics引擎中使用刚性体(特别是蹲伏功能)的角色控制器进行工作。我遇到了一个问题,其中Bullet将身体的世界变换的原点重置为手动设置之前的样子。调用stepSimulation()
时似乎正在发生这种情况。感觉好像有一个我未设置的参数,尽管此时可能回避了什么。我已上传以下video which shows exactly what I'm trying to explain:
- 0:00-09:00没有提供输入
- 按下10:00蹲伏键(碰撞形状正确缩放,然后转换回原点,而不是停留在设置位置的地面上)
- 释放12:00蹲伏钥匙
- 按下13:00蹲伏键
- 按下16:00向前移动键(向身体施加力会使它跌落到地面)
下面是我缩放碰撞对象并转换刚体原点的代码:
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);
}
执行此代码后,原点是正确的,直到执行stepSimulation()
,然后将刚体对象转换回执行上述代码块之前的原点。
是否有任何明显的东西让我可能忽略的人脱颖而出?
解决方法
通过以下方法完全删除,重置刚体并将其读入动力学世界来解决此问题:
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));
this->clientBody->setAngularVelocity(btVector3(0,0));
this->clientBody->getWorldTransform().setOrigin(newOrigin);
this->ghostObject->getWorldTransform().setOrigin(newOrigin);
this->collisionWorld->dynamicsWorld->addRigidBody(this->clientBody);
}