子弹物理 - 角度系数不适用

问题描述 投票:0回答:2

我目前正在使用子弹物理来模拟我的世界中的物理现象。现在,我有一个可控制的播放器,可以通过 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 中看到的每一次旋转都完全由 BulletPhysics 完成。我只用 AddForce 移动玩家。

我做的事情是完全错误的还是这是 Bullet 物理中的一个已知错误?预先感谢..!

c++ quaternions bulletphysics euler-angles
2个回答
1
投票

您是否为您的玩家创建动态或运动学刚体?

运动刚体只能由用户移动/设置动画,动态对象也可以通过所有其他对象移动...请参阅项目符号用户手册第 14 页。 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;

0
投票

我遇到了同样的问题,但是如果你在每一帧调用 setAngularFactor() ,它应该可以工作

© www.soinside.com 2019 - 2024. All rights reserved.