/** * @file tri_intersect.h * @brief 三角形-三角形 / 三角形-AABB 相交检测 * * 基于分离轴定理 (SAT) 的三角形间相交检测。 * 包括快速布尔测试和详细交点段提取。 * * @ingroup collision */ #pragma once #include "vde/core/triangle.h" #include "vde/core/aabb.h" namespace vde::collision { using core::Triangle3D; using core::AABB3D; using core::Point3D; /** * @brief 三角形-三角形相交检测(布尔测试) * * 使用分离轴定理在两组三角形之间检测相交。 * 候选分离轴包括: * - 每个三角形的面法线(2 轴) * - 每对边的叉积(3×3 = 9 轴) * - 共 11 轴(三角形退化为共面时可能有更多) * * 若存在一条轴使得两三角形投影区间不重叠 → 不相交。 * * 复杂度 O(1)(固定 11+ 轴检测)。 * * @param t1 三角形 1 * @param t2 三角形 2 * @return 相交返回 true * * @code{.cpp} * Triangle3D t1 = {p0, p1, p2}; * Triangle3D t2 = {q0, q1, q2}; * if (tri_tri_intersect(t1, t2)) { * // 处理碰撞 * } * @endcode * * @see tri_tri_intersect_detailed, sat_intersect */ bool tri_tri_intersect(const Triangle3D& t1, const Triangle3D& t2); /** * @brief 三角形-三角形相交线段 */ struct TriTriIntersection { bool intersects; /**< 是否相交 */ Point3D p0; /**< 交点段起点 */ Point3D p1; /**< 交点段终点 */ }; /** * @brief 三角形-三角形详细相交检测 * * 返回两三角形相交的交点线段(两个端点)。 * 适用于需要精确接触几何的场景,如: * - 物理引擎的接触流形生成 * - CSG 构造体几何的精确分割线 * - 网格自交修复 * * 算法: * 1. 用平面方程计算各顶点到对方平面的有符号距离 * 2. 找到边-平面交点形成交集段 * 3. 限制交集段到两个三角形内部 * * @param t1 三角形 1 * @param t2 三角形 2 * @return TriTriIntersection:相交标志 + 交点段端点 * * @note 共面情况交集段可能退化为单点(p0 == p1) * * @code{.cpp} * auto sect = tri_tri_intersect_detailed(t1, t2); * if (sect.intersects) { * Vector3D contact_normal = (t1.normal() + t2.normal()).normalized(); * Point3D midpoint = (sect.p0 + sect.p1) * 0.5; * } * @endcode * * @see tri_tri_intersect */ TriTriIntersection tri_tri_intersect_detailed(const Triangle3D& t1, const Triangle3D& t2); /** * @brief 三角形-AABB 快速相交测试 * * 使用分离轴定理在三角形和轴对齐包围盒之间检测。 * 候选分离轴包括(共 13 轴): * - 3 条 AABB 面法线 * - 1 条三角形面法线 * - 9 条边×边叉积(3 条 AABB 边 × 3 条三角形边) * * 复杂度 O(1)。 * * @param tri 三角形 * @param box 轴对齐包围盒 * @return 相交返回 true * * @note AABB 碰撞比三角剖分后的三角-三角检测更高效, * 常用于空间划分结构中的 rejection test。 * * @code{.cpp} * if (tri_aabb_overlap(tri, node_bounds)) { * // 需要进一步检测节点内的三角形 * } * @endcode * * @see tri_tri_intersect, ray_aabb_intersect */ bool tri_aabb_overlap(const Triangle3D& tri, const AABB3D& box); } // namespace vde::collision