暴力碰撞检测两个对象太慢

Brute force collision detection for two objects too slow

本文关键字:两个 对象 碰撞检测      更新时间:2023-10-16

我有一个项目,看看两个对象(每个大约由10,000个三角形组成)是否使用蛮力碰撞算法碰撞,在OpenGL中渲染。这两个物体不动。我必须将它们转换到一些位置,并找到例如100个三角形碰撞等。

到目前为止,我已经编写了一个代码,实际检查这两个模型之间的线平面相交。如果我把所有的东西都弄直了,我需要检查第一个模型中每个三角形的每条边和另一个模型中每个三角形的每一个平面。这实际上意味着3个for循环需要几个小时才能结束。我想我一定是弄错了,或者整个概念被误解了。
     for (int i=0; i<model1_faces.num; i++) {
    for (int j=0; j<3; j++) {
        x1[j] = model1_vertices[model1_faces[i].v[j]-1].x;
        y1[j] = model1_vertices[model1_faces[i].v[j]-1].y;
        z1[j] = model1_vertices[model1_faces[i].v[j]-1].z;
    }
    A.x = x1[0]; 
    A.y = y1[0]; 
    A.z = z1[0];
    B.x = x1[1];
    B.y = y1[1];
    B.z = z1[1];
    C.x = x1[2];
    C.y = y1[2];
    C.z = z1[2];
    TriangleNormal = findNormalVector((B-A)*(C-A));
    RayDirection = B-A;
    for (int j=0; j<model2_faces.num; j++) {
        PointOnPlane = model2_vertices[model2_faces[j].v[0]-1]; // Any point of the triangle
        system("PAUSE");
        float D1 = (A-PointOnPlane)^(TriangleNormal);   // Distance from A to the plane of j triangle
        float D2 = (B-PointOnPlane)^(TriangleNormal);
        if ((D1*D2) >= 0) continue; // Line AB doesn't cross the triangle
        if (D1==D2) continue;       // Line parallel to the plane
        CollisionVect = A + (RayDirection) * (-D1/(D2-D1));
        Vector temp;
        temp = TriangleNormal*(RayDirection);
        if (temp^(CollisionVect-A) < 0) continue; 
        temp = TriangleNormal*(C-B);
        if (temp^(CollisionVect-B) < 0) continue; 
        temp = TriangleNormal*(A-C);
        if (temp^(CollisionVect-A) < 0) continue;
        // If I reach this point I had a collision //
        cout << "Had collision!!" << endl;

我也不知道到底应该在哪里调用这个函数。在我的渲染函数中,它在渲染时连续运行,或者只是一次,因为我只需要检查非移动对象碰撞?

我希望你能解释一下,如果你太忙或太无聊了,不能看我的代码,只要帮助我理解更多的整个概念。

正如已经建议的那样,您可以使用边界卷。为了更好地利用这些,你可以在一个八叉树中安排你的边界卷,在这种情况下,卷是盒子。

在最外层,每个边界卷包含整个对象。因此,您可以通过比较两个对象的零级边界体积来测试它们是否可能相交。测试两个盒子的交集,其中所有的面都是轴对齐的,这是微不足道的。

八叉树将索引属于边界卷的哪些细分。因此,有些人脸当然会属于不止一个卷,可能会被测试多次。

这样做的好处是,您可以减少许多强行测试,因为只有少数子卷实际上会相交,所以这些测试肯定会失败。实际的交叉测试仍然是蛮力的,但是是在一小部分面孔上。

暴力冲突检测通常不能扩展,正如您所注意到的。通常的方法是定义一个包含模型/形状的边界体,并简化交叉计算。根据你的模型,边界体积有各种形状和大小。它们可以是球体、盒子等。

除了定义边界卷之外,您还需要在update部分代码中检测碰撞,因为您最有可能在某些delta时间内传递。通常需要delta时间来确定物体需要移动多远以及在该时间范围内是否发生碰撞。