使用 youyou 大神的物理 demo 工程,物体切割出错问题求助

前置条件

  1. 工程和代码均使用 physics-example-master
  2. 在工程里面的 cutting-object.fire 场景文件里,添加测试节点,绑定 PhysicsPolygonCollider 并编辑 points ,下图为编辑完毕后的效果:
  3. 运行预览,鼠标滑动使切割线经过 C 点附近,松开鼠标,出错,具体操作步骤见下方 gif 图

操作步骤

出错堆栈

CCPolygonSeparator.js:337 Uncaught TypeError: Cannot read property 'x' of undefined
    at Area (CCPolygonSeparator.js:337)
    at Right (CCPolygonSeparator.js:219)
    at Reflex (CCPolygonSeparator.js:207)
    at ConvexPartition (CCPolygonSeparator.js:77)
    at ConvexPartition (CCPolygonSeparator.js:154)
    at Object.ConvexPartition (CCPolygonSeparator.js:155)
    at cc_PhysicsPolygonCollider._createShape (CCPhysicsPolygonCollider.js:56)
    at cc_PhysicsPolygonCollider.__init (CCPhysicsCollider.js:172)
    at CCClass.pushDelayEvent (CCPhysicsManager.js:180)
    at cc_PhysicsPolygonCollider._init (CCPhysicsCollider.js:153)

一些线索

  1. 这个问题很容易复现,只要保证切割线经过 C 点的附近,而且是在刚体的外部(注意上图 C 点附近是 2 个挨得很近小白点)
  2. 浏览器断点到 CCPolygonSeparator.js:337,设置条件为 a===undefined
  3. 复现问题,步骤 2 条件断点触发了,可以定位到用户代码是 cutting-boject.js -> onTouchEnd -> collider.apply() 行
  4. 尝试编辑器里新建物理多边形 collider 节点,将 maxPointsResult 数据作为 points,如下图,依然看不出问题,但中间有个可疑点
  5. 放大可疑点
  6. 可以看到 C 点在切割线右方,而其他点在切割线左边,这应该是问题所在了。

进一步挖掘

仔细研读 cutting-object.js 源码,发现 maxPointsResult 的数据与下面这段代码有很大关系


这段的意图应该是说,一个碰撞器可能包含了多个 fixture,所以一次 raycast 过程可能会穿过内部 fixture,我们需要将他们从 result 数组里移除。而这里判断是否为内部 fixture 的关键是 r.point.sub(result.point).magSqr() <= POINT_SQR_EPSILON,如果 2 个点的距离小于 POINT_SQR_EPSILON 常亮 5,即认为是内部 fixture 碰撞点,需要移除掉。
结合操作步骤,猜测我们切割的线其实是穿过多边形的 BC/CD 边的,而因为两个点太靠近,导致判断 POINT_SQR_EPSILON 时被认为是内部 fixture 碰撞点,导致后续 maxPointsResult 的错误。

我的问题

以上是我对这个问题的理解和探索,我尝试将 POINT_SQR_EPSILON 缩小为 0.01,好像能减小问题出现的概率,但还是会出现,即无法根本解决。
研究了几天,实在不知如何解决,还请各位小伙伴和大神们支招:3::3::3:

应该是凹多边形问题

想问问多边形的处理,有人实现了吗?

你想做什么处理?

这个问题解决了没?

都是高难度,解决成本万儿八千都不一定找得到人。这个介绍了多边形裁剪。

多边形裁剪图片(非mask,使用mesh),新增 gizmo 支持 - Creator - Cocos中文社区