实际上限制了Box2D中的最大速度
Actually limiting maximum speed in Box2D
我想限制身体可以行驶的最大速度。
问题是,即使我做这样的事情,这个答案也建议:
/* after applying forces from input for example */
b2Vec2 vel = body->GetLinearVelocity();
float speed = vel.Normalize();//normalizes vector and returns length
if ( speed > maxSpeed )
body->SetLinearVelocity( maxSpeed * vel );
例如,如果在夹紧速度之前,我正在对身体施加一些巨大的力怎么办?即使线速度暂时限制在maxSpeed,在下一个时间步中,Box2D也会考虑b2Body::m_force值,并有效地移动我的身体比maxSpeed更快。
所以我想出了这个(不得不将b2Body::m_force移动到公共):
if ( speed > maxSpeed ) {
body->SetLinearVelocity( maxSpeed * vel );
body->m_force = b2Vec2(0, 0)
}
然而,这仍然不能正确处理问题。
如果速度略小于 maxSpeed 这样就不会达到条件,但m_force值仍然足够大以增加速度太多怎么办?
关键是我无法准确预测力将如何影响速度,因为我使用增量累加器步进,我不知道目前需要多少物理步长。
除了在 Box2D 源代码中集成位置之前直接限制速度之外,还有什么方法可以解决这个问题吗?
我解决这个问题的第一次尝试是简单地执行上面的代码片段,不是每个循环,而是每个物理子步骤,这意味着如果我的增量累加器告诉我必须执行 n b2World::Step
,我也会限制速度 n 次:
// source code taken form above link and modified for my purposes
for (int i = 0; i < nStepsClamped; ++ i)
{
resetSmoothStates_ ();
// here I execute whole systems that apply accelerations, drag forces and limit maximum velocities
// ...
if ( speed > maxSpeed )
body->SetLinearVelocity( maxSpeed * vel );
// ...
singleStep_ (FIXED_TIMESTEP);
// NOTE I'M CLEARING FORCES EVERY SUBSTEP to avoid excessive accumulation
world_->ClearForces ();
}
现在,虽然无论帧速率如何,这都能为我提供恒定的速度(这是我最关心的问题,因为我的运动抖动),但它并不总是<= maxSpeed
.同样的场景:想象一下在限制速度和超过b2World::Step
之前施加的巨大力。
现在,我可以简单地根据当前速度计算要施加的实际力,因为我知道在下一次验证之前,该力只会施加一次,但是我已经提到并最终坚持了另一种简单的解决方案:
- 转到 Box2D\Dynamics\b2Body.h
- 添加
float32 m_max_speed
公共成员并使用-1.f
对其进行初始化,因此最初我们不会限制任何实体的速度。 - 转到 Box2D\Dynamics\b2Island.cpp。
- 找到第 222 行。
添加以下 if 条件:
m_positions[i].c = c; m_positions[i].a = a; if (b->m_max_speed >= 0.f) { float32 speed = v.Normalize(); if (speed > b->m_max_speed) v *= b->m_max_speed; else v *= speed; } m_velocities[i].v = v; m_velocities[i].w = w;
即使没有我上面描述的子步进,这也将起作用,但请记住,如果您要模拟空气阻力,则每个子步都施加阻力可以保证模拟的正确性,即使帧速率不同。
首先,自己回答,谁可以对身体施加力量。Box2D本身可以通过接触和重力撞击物体。接触不是使用力,而是冲动。要管理它们,请设置联系人侦听器并修改正常脉冲和切线脉冲。我认为重力不能对身体产生很大影响,但它也可以通过b2BodyDef::gravityScale进行控制。如果您的代码采用一些手动强制,那么引入一些代理接口来管理它们可能会很有用。
我看不到一些简单的方法,因为每一步 box2d 都会进行几次速度和位置迭代。因此,在步骤开始时施加在其上的力和脉冲将相应地导致位置变化。
我无法想象这种方式,如果不破解 box2d 源代码,速度有多严格。顺便说一句,我认为它不是坏的变体。例如,在 Dynamics/b2Island.cpp:219 (b2Island::Solve) 中插入对 w 和 v 变量的限制。
- 为什么在读取文件大小时文件IO速度会发生变化
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 文件系统:复制功能的速度秘诀是什么
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 两个连续的 OpenMP 并行区域会相互减慢速度
- 查找标准::hash_map与标准::矢量的速度
- 加快在C++中读取/处理日志文件的速度
- 为什么这些算法的运行速度比它们应该的要快?
- 如何提高文件的读取速度?
- 通过libpqxx提高PostgreSQL数据库的更新速度
- 使用 IMFSinkWriter 编码的视频的播放速度会根据宽度而变化
- 计算车辆之间的距离并设置速度,使距离保持不变,例如 5 米
- 如何加快大字符串的解析速度?
- 如何比较两个函数的速度和性能
- 线程相互减慢速度
- 实际上限制了Box2D中的最大速度
- Cocos2D/Box2d只在一个轴上设置速度
- 在box2d中为精灵设定恒定和递增的速度
- IOS Box2D-主体遵循一个特定的路径,基于一个具有波动速度的点阵列