AABB< - > C ++中的三角交集

时间:2015-10-24 17:45:00

标签: c++ geometry intersection

我试图让AABB和三角形之间的交叉点起作用。我正在按照这个答案:AABB/triangle intersection in C#(在那里提到的修复)

我将代码移植到C ++,它几乎可以正常工作。然而,一些三角形似乎得到误报,它看起来像这样:

enter image description here

我试图尽可能接近问题中给出的代码:

inline LVecBase3f get_box_normal(int idx) {
    return LVecBase3f(
        idx == 0 ? 1.0 : 0.0,
        idx == 1 ? 1.0 : 0.0,
        idx == 2 ? 1.0 : 0.0);
}

inline void project(const LVecBase3f &axis, const LVecBase3f &vertex,
                    float &minval, float &maxval) {
    float val = axis.dot(vertex);
    if (val < minval) minval = val;
    if (val > maxval) maxval = val;
}


inline void project_triangle(MeshSplitter::Triangle* tri, const LVecBase3f &axis,
                             float &minval, float &maxval) {
    minval = FLT_MAX;
    maxval = FLT_MIN;
    for (int vtx = 0; vtx < 3; ++vtx) {
        project(axis, tri->vertices[vtx].pos, minval, maxval);
    }
}


void project_box(const LVecBase3f &bb_min, const LVecBase3f &bb_max,
                 const LVecBase3f &axis, float &minval, float &maxval) {
    minval = FLT_MAX;
    maxval = FLT_MIN;

    // Lower side of the box
    project(axis, LVecBase3f(bb_min.get_x(), bb_min.get_y(), bb_min.get_z()), minval, maxval);
    project(axis, LVecBase3f(bb_max.get_x(), bb_min.get_y(), bb_min.get_z()), minval, maxval);
    project(axis, LVecBase3f(bb_min.get_x(), bb_max.get_y(), bb_min.get_z()), minval, maxval);
    project(axis, LVecBase3f(bb_max.get_x(), bb_max.get_y(), bb_min.get_z()), minval, maxval);

    // Upper side of the box
    project(axis, LVecBase3f(bb_min.get_x(), bb_min.get_y(), bb_max.get_z()), minval, maxval);
    project(axis, LVecBase3f(bb_max.get_x(), bb_min.get_y(), bb_max.get_z()), minval, maxval);
    project(axis, LVecBase3f(bb_min.get_x(), bb_max.get_y(), bb_max.get_z()), minval, maxval);
    project(axis, LVecBase3f(bb_max.get_x(), bb_max.get_y(), bb_max.get_z()), minval, maxval);

}

bool MeshSplitter::triangle_intersects(const LVecBase3f &bb_min,
                                       const LVecBase3f &bb_max, Triangle* tri) {

    float tri_min = 0, tri_max = 0;
    float box_min = 0, box_max = 0;


    // Test box normals (x, y, and z)
    for (int i = 0; i < 3; ++i) {
        LVecBase3f box_normal = get_box_normal(i);
        project_triangle(tri, box_normal, tri_min, tri_max);

        // No intersection, since the point was not in the box
        if (tri_max < bb_min[i] || tri_min > bb_max[i])
            return false;
    }

    // Check for triangle normal
    double tri_offs = tri->face_normal.dot(tri->vertices[0].pos);
    project_box(bb_min, bb_max, tri->face_normal, box_min, box_max);
    if (box_max < tri_offs || box_min > tri_offs)
        return false;

    // Test the edge cross products
    LVecBase3f tri_edges[3] = {
        tri->vertices[0].pos - tri->vertices[1].pos,
        tri->vertices[1].pos - tri->vertices[2].pos,
        tri->vertices[2].pos - tri->vertices[0].pos,
    };

    for (int i = 0; i < 3; ++i) {        
        for (int j = 0; j < 3; ++j) {
            LVecBase3f axis = tri_edges[i].cross(get_box_normal(j));
            project_box(bb_min, bb_max, axis, box_min, box_max);
            project_triangle(tri, axis, tri_min, tri_max);
            if (box_max < tri_min || box_min > tri_max)
                return false;
        }
    }

    return true;
}

我在移植代码时是否引入了一些错误(如果是,那么),或者这是算法中的错误?

如果需要其他信息,我可以提供。

0 个答案:

没有答案