暴力碰撞检测两个对象太慢
Brute force collision detection for two objects too slow
我有一个项目,看看两个对象(每个大约由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
时间来确定物体需要移动多远以及在该时间范围内是否发生碰撞。
相关文章:
- 如何返回一个类的两个对象相加的结果
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 如何在Qt中连接来自不同窗口的两个对象?
- C++两个对象,其中包含指向同一数组不同部分的指针
- 为什么将两个对象分配给另一个对象后,两个对象不一样?
- C++:在另外两个对象之间共享一个对象
- 在单元测试中,如何在不使用 operator== 的情况下比较两个对象,这可能会错过新成员?
- 同一类的两个对象相互引用
- 将类对象传递给两个对象
- 如何调用运算符函数添加两个对象?
- 让一个名为A的类.传递以下两个对象有什么区别:(a)obj1和(b)obj1()
- 比较矢量迭代中的两个对象C
- 当我有两个对象时<<如何重载运算符?(有关系)
- 声明一个模板函数,将模板类友元的两个对象(仅)带到这两个专用化
- 使用指针将两个对象(每个都与一个类)相关联
- 比较类的两个对象之间的数据