两个物体的强力碰撞检测太慢

时间:2013-01-14 22:13:37

标签: c++ opengl graphics collision-detection brute-force

我有一个项目,看看是否有两个对象(每个大约有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;

另外,我不确切地知道上面这个函数的确切位置。在我的渲染功能中,它在渲染时连续运行或仅运行一次,因为我只需要检查非移动物体的碰撞?

我很感激一些解释,如果你太忙或无聊看到我的代码,那就帮助我理解一下这整个概念。

2 个答案:

答案 0 :(得分:1)

正如已建议的那样,您可以使用边界卷。为了充分利用这些,您可以在八叉树中排列边界卷,在这种情况下,卷是框。

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

八叉树将索引哪些属于边界体积的哪些细分。因此,一些面孔当然属于多个卷,可能会多次测试。

好处是你可以通过只有少数子体积实际相交的事实来修剪许多保证失败的蛮力测试。实际的交叉点测试仍然是暴力,但是在一小部分面上。

答案 1 :(得分:0)

正如您所注意到的,蛮力碰撞检测通常无法扩展。 :)通常的方法是定义包含模型/形状的bounding volume并简化交集计算。根据您的型号,边界体积有各种形状和尺寸。它们可以是球形,盒子等。

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