我正在开发一款涉及宇宙飞船的游戏。我们正在使用 OGRE 和 Bullet。
玩家的船应该用鼠标进行俯仰和偏航——例如,向左移动鼠标将使船向左偏航。问题是,我不知道如何在 Bullet 中应用扭矩。
在我们开始集成 Bullet 之前,我们的解决方案是像这样直接修改 OGRE 场景节点(使用 OIS 进行输入):
bool Game::mouseMoved(const OIS::MouseEvent &event) {
shipNode->yaw(Ogre::Degree(-event.state.X.rel));
shipNode->pitch(Ogre::Degree(event.state.Y.rel));
return true;
}
这很好用。
现在我们正在使用 Bullet,我的计划是对刚体施加扭矩,如下所示:
bool Game::mouseMoved(const OIS::MouseEvent &event) {
//shipNode->yaw(Ogre::Degree(-event.state.X.rel));
//shipNode->pitch(Ogre::Degree(event.state.Y.rel));
shipRigidBody->applyTorqueImpulse(btVector3(-event.state.X.rel, event.state.Y.rel, 0));
return true;
}
然后,在逐步模拟之后,更新场景节点的方向,如下所示:
void Game::update(const Ogre::FrameEvent &event) {
// ... snip ...
physicsWorld->stepSimulation(event.timeSinceLastFrame, 10);
btTransform shipTransform;
shipMotionState->getWorldTransform(shipTransform);
shipNode->setPosition(shipTransform.getOrigin().x(), /* ... snip ... */);
shipNode->setOrientation(shipTransform.getRotation().getAngle(), shipTransform.getRotation().getAxis().x(), /* ... snip ... */);
}
但是有了这个设置,我根本无法确定船的方向。
(100, 10, 200)
接下来,我尝试无论如何都对每一帧施加一个扭矩脉冲,然后打印出来shipTransform.getRotation().getAngle())
。始终为 0。此时,我变得非常困惑,因为您会认为始终施加扭矩会使身体的方向发生变化。
所以,我的问题是:我错过了什么愚蠢的东西btRigidBody::applyTorqueImpulse()
吗?还是我完全找错了树?
PS:shipRigidBody
构造如下:
shipMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 100, 0)));
shipShape = new btBoxShape(btVector3(50, 20, 75));
shipShape->calculateLocalInertia(btScalar(1), btVector3(0, 0, 0));
shipRigidBody = new btRigidBody(btRigidBody::btRigidBodyConstructionInfo(1, shipMotionState, shipShape));
我还有代码可以根据键盘输入向前或向后加速船,并且该代码(使用btRigidBody::applyCentralImpulse()
)工作正常。