Box2D 不寻常的错误。为什么 +0 可以防止错误?

Box2D unusual bug. Why does +0 prevent an error?

我发现了一个我不明白的非常奇怪的错误。也许有人可以阐明一些问题。

问题

我正在使用 box2D 运行 物理模拟。模拟中的一件事是 body,它的线性阻尼在每一帧都设置为 0 到 2 之间的浮点数。在每个 body 上,调用以下行。

body->SetLinearDamping(value);

当添加了足够多的这些主体(大约 500 个)时,程序悄悄地中断(不知何故),内存使用量在几秒钟内从 ~50mb 上升到 300mb。在同一点,只有 1 或 2 个身体被渲染,并且只渲染几秒钟。这大概是因为 world.query returns 不正确的结果。

我确实设法确定了 program-death 内存峰值的原因。在 box2d 的解决函数中,联系人管理器添加了数千对。多余的内存几乎完全来自 b2Contact::Create.

编辑:我应该提到,在调用 b2World::Step 一定次数后,内存的增加开始了。大概是一万左右吧。我不知道如何从程序内部检测问题,所以我无法确定每次的步骤数是否相同。

错误

最初我以为我可能以某种方式滥用了 SetLinearDamping。我试图改变值的范围,所以我简单地给它们加了+1。这实际上完全解决了问题,我通过添加大约 10,000 objects 并推动它们来进行压力测试。

所以接下来我将这个值变小,试图确定我可以添加的最小值。 +0.01f 和 +1 一样有效,所以在执行 + numeric_limits::min() 之前我尝试了 +0。所以现在我的代码是:

body->SetLinearDamping(value+0);

这修复了程序。发现这一点后,我实际上对程序进行了更多开发,它 运行 完全稳定。我原以为编译器会优化它。这实际上在 c++ 中有任何功能吗?它如何防止 box2d 中出现问题?

在花费大量时间单步执行代码后,我确定了原因和解决方案。对于在 box2d 中遇到类似问题的任何人,您需要检查 NaN。我什至忘记了 c++ 甚至有这些,我必须说我觉得自己像个白痴,这超出了我的头脑。

这里的问题是偶尔,提供值的函数会 return nan。将 nan 作为线速度传递给 box2d 函数会在我的程序中产生 nans 波纹,你知道 nans 是怎样的。

在我身体的所有 x 和 y 值最终都为 nan 之后,它们基本上都在同一个地方。这导致碰撞管理器必须生成数千对,因为必须针对每个其他碰撞 body.

检查每个碰撞 body

最后,将 0 添加到 NaN 显然 returns 0。所以在回答最初的问题时,value 与 value+0 之间的函数差异是什么:

在值不是数字的情况下,值的计算结果为 0。