这是我之前解决的一个问题的后续。
我正在尝试开发一种网格碰撞方法,以惩罚相互渗透。出于这个原因,我开始使用 CGAL,并且我通过密切关注此示例("查找相交 3D 三角形的示例")进行了第一次尝试。
但是,它似乎将所有相邻的三角形情况检测为碰撞(现在似乎很明显该方法会这样做)。
有没有办法只检测非相邻三角形的实际碰撞?理想情况下,碰撞检测方法应在创建输出之前处理好这个问题,从而避免需要过滤掉碰撞三角形的最终向量以及随之而来的计算负担。
我的三角形的结构是一个三角形汤,即存储在没有特定排序的向量中。
我找到的解决方案如下(尽管不确定这是否是最佳解决方案):
在碰撞检查的回调函数中
- 首先读取三角形的 ID
id1 = a.handle() - coll_Triangles.begin();
id2 = b.handle() - coll_Triangles.begin();
- 检查三角形是否退化(如果为真,则返回)
a.handle()->is_degenerate()
- 检查三角形的顶点 ID。如果它们共享顶点 ID,则返回
这是显而易见的,不是这里的伪代码:)
- 只有当上述情况成立时,才进行三角形之间的实际交集测试
CGAL::d o_intersect( *(a.handle()), *(b.handle())
- 如果最后一个命令返回 true,则有两个不相邻的三角形发生碰撞。恭喜:)
在所有其他测试之后,do_intersect必须作为最后一步进行,否则计算负载非常大且徒劳无功。
另一种可能的加速是使用半开式而不是封闭式盒子。我发现在所有三角形对之间进行贪婪检查期间,这会导致加速(~50%),但我认为这可能会导致错过一些碰撞(例如在触摸的情况下)。
CGAL::Box_intersection_d::HALF_OPEN
CGAL::Box_intersection_d::CLOSED