【问题标题】:Avoid ground collision with Bullet避免与子弹的地面碰撞
【发布时间】:2014-10-25 16:07:49
【问题描述】:

我正在尝试使用 Bullet 物理引擎创建一个 3D 世界。

我的角色身体上有一个胶囊形状,我的地面由一些静态块组成,粘在一起,这里有一个示意图来说明我的话:

当我的角色从一个街区跑到另一个街区时出现问题:子弹检测到碰撞,我的角色开始在 y 轴上跳跃一点。

我怎样才能避免这个问题?

【问题讨论】:

  • 你的碰撞块是否在 x 轴上重叠?
  • 子弹是否有像 box2d 这样的边缘(链)形状?
  • aduch:块 1 右边缘 = 块 2 左边缘。所以,不是真的:/ @LearnCocos2D:不,但我尝试用盒子形状替换胶囊形状,一切都变得更好,这很奇怪哦

标签: c++ game-engine bulletphysics


【解决方案1】:

我为克服这个问题所做的工作如下:

我没有让胶囊在地面上滑动,而是在弹簧顶部进行动态胶囊骑行。 我将弹簧实现为来自胶囊底部的几个射线投射。 弹簧的长度大约为半米或更短,它会拉动和推动胶囊进出地面。 抓地力/拉力很重要,因此角色不会意外跳跃。 弹簧刚度控制着你有多少摆动。

这有以下效果

  • 不会与地板上的几何图形边缘发生意外碰撞,因为胶囊会漂浮
  • 隐式实施了走楼梯和斜坡。弹簧只会“踩”上楼梯的台阶并将角色胶囊向上推。
  • 跳跃的实施只是释放弹簧对地面的抓地力并给身体一个冲动。
  • 跳跃或坠落后的着陆角色会自动显示“膝盖弯曲”,正如您所期望的那样
  • 总体上令人愉悦的垂直运动平滑。比如电梯平台等。
  • 由于抓地力/拉地,即使在下坡时,角色也不会像您在某些游戏中所体验的那样开始“飞行”(我觉得这通常很烦人)。
  • 闪避字符 = 减少弹簧和/或胶囊的长度。
  • 滑下坡?您可以通过检查弹簧撞击的射线投射的地板区域的角度来完全控制它。

我不得不在弹簧的刚度、弹簧的长度、握把的长度等方面进行了很多尝试,但最后我很高兴这很简单,但效果很好。

【讨论】:

  • 嘿,我知道已经有一段时间了,但是春天到底是什么?我的意思是,这是 Bullet 的课程还是物理概念? Google 帮不上什么忙
  • 当我这样做时,Bullet 2.7x 中不存在开箱即用的 spring 实现。所以我在谷歌上阅读了弹簧物理学并自己做了。无论如何,我需要对细节进行更多控制,比如阻尼弹簧等。
  • 这似乎是一种非常复杂且迂回的解决问题的方法。虽然如果您列出意图的效果可能是一个很好的解决方案,但如果您的意图是简单地解决所要求的问题,那么它就不合适了。
  • @NicoHeidtke 你为什么使用多条光线?它帮助你完成了什么?你是如何使用它们的? (我已经让它与单条射线一起工作,并且工作得很好,只是有一些小错误)
  • @akaltar 我一直在尝试实施您的解决方案,但它一直在上下波动。我错过了什么? pastebin.com/7HKSxCpe
【解决方案2】:

您的问题来电者“内部边缘碰撞”。几个小时前我刚刚找到了解决方案。 如果你的世界使用 btHeightfieldTerrainShape,那么你必须使用 btBvhTriangleMeshShape 来解决这个问题。

这就是答案。

添加此回调:

static bool CustomMaterialCombinerCallback(btManifoldPoint& cp,const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
{
   btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1);
   return true;
}

extern ContactAddedCallback gContactAddedCallback;

然后创建btBvhTriangleMeshShape 并添加此代码,其中pGround 是您的btBvhTriangleMeshShape

// Enable custom material callback
pGround->setCollisionFlags(pGround->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
btGenerateInternalEdgeInfo(pGroundShape, triangleInfoMap);

或者你可以打开Bullet中的InternalEdgeDemo的例子,看看具体如何实现。

【讨论】:

  • 如何将此解决方案扩展到更通用的情况(btBvhTriangleMeshShape 除外)?
  • 不,你不能。它仅适用于 btBvhTriangleMeshShape。
  • 这应该是真正的解决方案。这个对我有用。一些有趣的链接github.com/godotengine/godot/issues/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-03
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多