我目前正在使用Bullet物理来模拟我的世界中的物理。现在,我有一个可以用ApplyForce移动的可控播放器,但它还不能旋转。
但是,我将角度移动锁定到Y轴(俯仰),但它似乎不起作用:
在初始化时:
// Player.cpp
m_physicsBodyComp->LockRotation({0.f, 1.f, 0.f});
// PhysicsBodyComponent.cpp
void tse::PhysicsBodyComponent::LockRotation(const TSVector3 & a_axis) {
if(m_rigidBody)
m_rigidBody->setAngularFactor(btVector3(a_axis.GetX(), a_axis.GetY(), a_axis.GetZ()));
}另外,可能引起问题的是:在物理模拟之前,我将刚体的变换设置为变换分量的变换,而在物理模拟之后,我将变换分量的变换设置为刚体变换。
// Before physics simulation
void tse::PhysicsBodyComponent::UpdateTransformComponent() {
if(m_rigidBody) {
if(m_transformComponent->m_wasDirty && m_transformComponent->IsValid()) {
btQuaternion _quat;
_quat.setEuler(m_transformComponent->m_rotation.GetY(), m_transformComponent->m_rotation.GetX(), m_transformComponent->m_rotation.GetZ());
btTransform _trans;
_trans.setRotation(_quat);
_trans.setOrigin(m_transformComponent->m_position.GetVecBt());
m_rigidBody->setWorldTransform(_trans);
m_transformComponent->m_wasDirty = false;
Activate();
}
}
}
// After physics simulation
void tse::PhysicsBodyComponent::Update(float a_deltaTime) {
if(m_rigidBody) {
if(m_bodyType == PhysicsBodyType::DYNAMIC) {
btTransform & _trans = m_rigidBody->getWorldTransform();
DirectX::XMVECTOR _rotation;
btQuaternion _quat = _trans.getRotation();
_rotation.m128_f32[0] = _quat.getX();
_rotation.m128_f32[1] = _quat.getY();
_rotation.m128_f32[2] = _quat.getZ();
m_transformComponent->SetPosition(TSVector3(_trans.getOrigin()));
m_transformComponent->SetRotation(_rotation);
}
}
}所以,问题是我锁定了x和z轴的旋转,但它仍然改变了x和z轴的旋转(问题的GIF如下所示)。就像我之前说的,我还没有轮换球员。你在下面的GIF中看到的每一次旋转都是纯粹由Bullet Physics完成的。我只用AddForce来移动播放器。
是我做了什么完全错误的事情,还是这是子弹物理学中的一个已知错误?提前感谢..!

发布于 2018-01-18 20:08:22
您是为玩家创建动力学刚体还是运动学刚体?
运动学刚体只能由用户移动/动画,动态对象也可以通过其他对象移动...请参阅bullet user manual p. 19+20
因此,如果您的球员仅应使用addForce()等进行移动,请创建运动学身体。
如何创建运动学刚体:( C#中的示例,C++应该类似)
// Create rigid Body
float mass = 0.0f; // kinematic bodies have no mass
RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, new DefaultMotionState(), collisionShape);
RigidBody rigidBody = new RigidBody(rbInfo);
rbInfo.Dispose();
// Mass=0 -> static/kinematic possible -> use flag distinguish
rigidBody.CollisionFlags = CollisionFlags.KinematicObject;https://stackoverflow.com/questions/47054416
复制相似问题