2

我有一个项目来查看两个对象(每个对象由大约 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;

我也不知道究竟应该在哪里调用上面的这个函数。在我的渲染函数中,以便它在渲染时连续运行或只运行一次,因为我只需要检查非移动对象碰撞的事实?

我将不胜感激,如果您太忙或太无聊而无法查看我的代码,请帮助我更多地理解整个概念。

4

2 回答 2

1

正如已经建议的那样,您可以使用包围体。为了充分利用这些,您可以将包围体安排在八叉树中,在这种情况下,体积是盒子。

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

八叉树将索引哪些属于边界体积的哪些细分。所以有些面孔当然会属于不止一卷,可能会被多次测试。

这样做的好处是,您可以剪掉许多由于只有少数子卷实际上会相交而保证失败的蛮力测试。实际的相交测试仍然是蛮力的,但只针对一小部分人脸。

于 2013-01-14T22:46:57.167 回答
0

正如您所注意到的,蛮力碰撞检测通常无法扩展。:) 通常的方法是定义一个包含您的模型/形状的包围体并简化相交计算。边界体有各种形状和大小,具体取决于您的模型。它们可以是球体、盒子等。

除了定义边界体之外,您还需要检测update代码段中的碰撞,您很可能会在一段delta时间内经过。通常需要该delta时间来确定对象需要移动多远以及在该时间范围内是否发生碰撞。

于 2013-01-14T22:21:37.400 回答