我想根据某些对象的轴对齐边界框检查视锥,以大致检查这些对象是否在视野中。速度不是什么大问题。
问问题
3703 次
2 回答
3
我发现构建视锥体的世界空间模型并检查与它的 bbox 碰撞是错误的方法。
一个更简单的方法是采用相反的方式并将给定 bbox 的每个顶点转换为屏幕空间,如果 bbox 的任何顶点在屏幕边界内,则将该 bbox 视为可见。我通过与相机矩阵相乘然后根据相机的视野考虑透视来获得屏幕空间位置。这是代码:
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
于 2011-03-21T04:52:00.953 回答
2
那可行。然而,通常人们宁愿提取平截头体平面并计算到这些平面的距离。你说“速度不是什么大问题”,但最终你可能会发现它是。毕竟,人们会进行截锥剔除以使事情变得更快。
将一个顶点与一个矩阵相乘相当于 4 个点积,因此您需要相当于 32 个点积来检查所有 8 个角。计算一个点到一个平面的距离需要一个点积和一个加法,这在最坏的情况下效率更高,在一般情况下效率更高(因为您通常可以在一两个平面后裁剪后丢弃一个对象,并且不超过三个)。剪裁平面有许多利用临时连贯性的优化,我不会深入讨论。
此外,您可以通过计算中心点到平面的距离预先进行一些粗略剔除,并检查该距离是否大于边界框的半径。这将非常便宜地剔除明显“进”或“出”的对象。或者,或者,您可以将您的视图向量的点积与您的视野值的余弦加上一些“填充”(或者,只是看看它是否为正)作为第一次超粗略检查。您会记得,两个向量的点积告诉您它们指向同一方向的程度。与您的视图矢量具有负点积的东西当然是您可以安全丢弃的东西,因为它在您身后。
于 2011-03-21T18:32:04.617 回答