Bullet物理引擎,如何冻结一个物体?

17
使用 Bullet 2.76,我想要冻结一个物体(刚体),使其立即停止运动但仍对碰撞做出反应。
我尝试将其活动状态设置为 DISABLE_SIMULATION,但是这样它对其他对象来说几乎不存在。此外,如果当它被禁用时,其他对象与之“碰撞”,奇怪的事情开始发生(对象穿过静态体等)。
我认为,暂时将其转换为静态刚体可能有效,但是否有现成的 Bullet 内置方法可以实现此目的?
编辑:是否有一种方法可以关闭特定物体的重力?
6个回答

9
文档有些欠缺,但可以假定下面的方法可以用于禁用特定物体上的重力:
void btRigidBody::setGravity(const btVector3 &acceleration)

这就是它!在碰撞后,人们必须注意去激活等等,但它有效!完美!非常感谢! - sunside

9

链接已失效。 - sunside
这是一个新链接:https://github.com/bulletphysics/bullet3/blob/master/examples/HelloWorld/HelloWorld.cpp,但对我来说将质量设为0并没有起作用。 - Jespertheend

6

对于btRigidBody,有两个名为setLinearFactor(x,y,z)setAngularFactor(x,y,z)的函数,它们允许您限制沿特定轴线的运动和绕特定轴线的旋转。将这两个函数都使用参数0调用可以停止所有运动。再次使用参数1调用它们将重新允许运动。


5

将激活状态设置为零。这是对象自然休眠时发生的情况。重力等效应不会生效,直到它再次被唤醒。

rigidBody->setActivationState(0);

然后像任何休眠的物体一样,当它发生碰撞或者你对其施加力时它会被唤醒。


那么,你如何唤醒它? - MiniGod
@MiniGod 施加力量,可以直接施加或通过碰撞施加。 - weston
这意味着我们也可以让它在空中睡觉吗?不幸的是,这似乎在JMonkeyEngine子弹包装器中没有暴露。 - Aquarius Power

3
为了使用这种方法停止您的演员,您必须在每个更新帧中调用它。
void StopActor()
{
    m_pRigidBody->setLinearVelocity(btVector3(0,0,0));
}

1

将速度和动量设为零,并将质量设为一个非常大的数字。


还没有测试过,但是这真的会将对象冻结在半空中吗?(并且,保持在那里?) - sunside
如果您使用真正的重力方程式,它就会生效: F = G * (m1 * m2) / r^2。然而,大多数引擎不会使用这个方程式,而只是假设恒定重力(F = m * g),因此您还需要关闭物体的重力和任何其他恒定力。但是,这对于任何弹性力和碰撞引擎(可能使用弹性力)都应该有效。 - eeeeaaii
那么问题是:我如何在 Bullet 中关闭特定对象的重力? - sunside
抱歉,我的大部分经验都是在构建物理引擎方面的,但我没有使用Bullet的具体经验。您能指定哪些力适用于哪些对象/物体吗?是否有配置文件或类似的东西? - eeeeaaii
我很好奇,所以我阅读了一些关于Bullet的文档。看起来他们并没有让修改力量变得容易。将你的物体类型更改为静态可能会更容易些。 - eeeeaaii
这个想法是正确的,禁用重力导致了解决方案。Staffan指出了要使用的函数。也非常感谢你! - sunside

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接