检查边界框与视锥体的交集/碰撞
我想要检查一个视锥体和一些物体的轴对齐包围盒,看看这些物体大致上是否在视野范围内。速度不是特别重要。
2 个回答
2
这个方法是可行的。不过,通常人们更倾向于提取视锥体的平面,然后计算到这些平面的距离。你提到“速度不是大问题”,但最终你可能会发现这其实很重要。毕竟,做视锥剔除的目的就是为了提高速度。
把一个顶点和一个矩阵相乘,相当于要进行4次点积运算,所以要检查所有8个角落,你需要进行32次点积运算。计算一个点到一个平面的距离只需要一次点积和一次加法,这在最坏的情况下效率稍高,在平均情况下效率则高得多(因为你通常可以在裁剪后只用一两个平面就能排除一个物体,最多也就用到三个平面)。对于裁剪平面,还有一些优化方法可以利用临时的一致性,我就不详细讲了。
另外,你可以先进行一些粗略的剔除,方法是计算中心点到一个平面的距离,看看这个距离是否大于包围盒的半径。这种方法可以很便宜地剔除那些明显“在里面”或“在外面”的物体。或者,你也可以把你的视线向量的点积和视野值的余弦加上一些“缓冲”进行比较(或者简单地看一下是否为正),作为第一次超粗略的检查。你可能还记得,两个向量的点积可以告诉你它们指向同一方向的程度。与视线向量的点积为负的东西,肯定可以安全地丢掉,因为它在你身后。
4
我发现,构建一个世界空间的视锥体模型并检查与它的边界框碰撞,这种方法并不对。
其实有个更简单的方法,就是反过来,把给定边界框的每个顶点转换到屏幕空间。如果边界框的任何一个顶点在屏幕范围内,那就可以认为这个边界框是可见的。我通过把顶点与相机矩阵相乘来得到屏幕空间的位置,然后根据相机的视野角度来调整透视效果。下面是代码:
vertexMatrix = matrix([vertex.x,vertex.y,vertex.z,1])
productMatrix = (vertexMatrix * camMatrix)
pVectSS = vector(prodMatrix[0][0],prodMatrix[0][1],prodMatrix[0][2])
pointX = ((pVectSS.x/(-pVectSS.z))/tan(radians(hFOV/2)))/2.0+.5
pointY = ((pVectSS.y/(-pVectSS.z))/tan(radians(vFOV/2)))/2.0+.5
关键:
camMatrix = camera inverse world-space matrix
pVectSS = position vector screen-space
hFOV = horizontal field of view
vFOV = vertical field of view