我希望在我的跟踪管道中有一个碰撞检测模块,用于检测两个不同的网格何时碰撞/相互穿透,或者铰接网格是否存在自渗透。根据渗透的深度,应该有一个惩罚来对抗这种现象。为此,我应该获得碰撞面/顶点的列表。
在研究了几个选项后,我决定开始使用CGAL。
在此链接中,有一个有趣的答案指向一些示例。(这个和这个)。这些示例使用 AABB(轴对齐边界框),这是非刚性网格的建议方法,因为需要经常更新它们。对于自交集情况,这些示例很清楚,但以下对我来说不是很清楚:
- 除了为每个三角形创建一个 B.Box 之外,我猜在引擎盖下没有创建树结构来加快搜索过程。是这样吗?如果是,有什么提示吗?
- 在 2 个单独的网格的情况下,我想将所有三角形/框合并到一个向量中并遵循示例并不好(尽管这里提到了它作为解决方案,但听起来并不那么优雅)。有什么好做法的提示吗?是否应该通过创建三角形/盒子树来混合这些示例?虽然对于AABB树,提到:
请注意,此组件不适合查找所有相交对象对的问题。我们指的是 dD Iso 定向框的组件相交序列,它可以找到所有相交对的 iso-定向框。
- 函数 CGAL::box_intersection_d 动态创建段树,以加快相交 AA 边界框对的计算速度。
- 据我所知,推荐的方法是将两个表面合并到一个自定义框的向量中,其中框有一个字段来指示三角形所属表面的标识符。这有助于从同一表面上快速丢弃成对的盒子。
我的回答实际上是对 lrineau 内容丰富的答案的评论,但它有点长,所以我将其作为我自己的答案发布。CGAL 的多边形网格处理包具有一个名为 CGAL::Polygon_mesh_processing::do_intersect()
的函数,该函数接受两个三角形网格作为输入,并返回一个布尔值,用于描述网格是否相交。不幸的是,它没有告诉你相交的面对。
但是,do_intersect()
内部调用一个未记录的函数CGAL::Polygon_mesh_processing::internal::compute_face_face_intersection()
(该函数又调用CGAL::box_intersection_d()
),该函数将相交的面对返回到向量中。下面是一些示例代码,演示如何调用它:
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
typedef std::pair<face_descriptor, face_descriptor> face_descriptor_pair;
namespace PMP = CGAL::Polygon_mesh_processing;
Mesh mesh_a, mesh_b;
std::vector<face_descriptor_pair> tri_pairs;
PMP::internal::compute_face_face_intersection(
mesh_a,
mesh_b,
std::back_inserter(tri_pairs),
PMP::parameters::vertex_point_map(get(CGAL::vertex_point, mesh_a)),
PMP::parameters::vertex_point_map(get(CGAL::vertex_point, mesh_b))
);