我试图让AABB和三角形之间的交叉点起作用。我正在按照这个答案:AABB/triangle intersection in C#(在那里提到的修复)
我将代码移植到C ++,它几乎可以正常工作。然而,一些三角形似乎得到误报,它看起来像这样:
我试图尽可能接近问题中给出的代码:
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;
}
我在移植代码时是否引入了一些错误(如果是,那么),或者这是算法中的错误?
如果需要其他信息,我可以提供。