检查边界框与视锥体的相交/碰撞

发布于 2024-10-22 19:00:29 字数 55 浏览 2 评论 0原文

我想根据某些对象的轴对齐边界框检查视锥体,以大致检查这些对象是否在视野中。速度并不是什么大问题。

I want to check a view frustum against the axis aligned bounding boxes of some objects, to check roughly whether those objects are in the field of view or not. Speed is not a big deal.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兔姬 2024-10-29 19:00:29

我发现构建视锥体的世界空间模型并检查 bbox 与它的碰撞是错误的方法。

A much simpler method is to go the opposite way and convert each vertex of a given bbox to screen-space, and if any vertex of the bbox is within the screen bounds then count that bbox as visible. I get the screen-space position by multiplying against the camera matrix and then accounting for perspective based on the field of view of the camera.

这是代码:

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

I figured out that building a world-space model of the view frustum and checking for bbox collisions with it was the wrong way to go about this.

A much simpler method is to go the opposite way and convert each vertex of a given bbox to screen-space, and if any vertex of the bbox is within the screen bounds then count that bbox as visible. I get the screen-space position by multiplying against the camera matrix and then accounting for perspective based on the field of view of the camera.

Here's the code:

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

key:

 camMatrix = camera inverse world-space matrix
 pVectSS = position vector screen-space
 hFOV = horizontal field of view
 vFOV = vertical field of view
嗼ふ静 2024-10-29 19:00:29

那会起作用的。然而,通常人们宁愿提取截锥体平面并计算到这些平面的距离。您说“速度不是什么大不了的事”,但最终您可能会发现事实并非如此。毕竟,进行视锥体剔除是为了让事情变得更快。

将顶点与矩阵相乘相当于 4 个点积,因此您需要相当于 32 个点积来检查所有 8 个角。计算点到平面的距离需要点积和加法,这在最坏的情况下效率更高,在平均情况下效率更高(因为您通常可以在一个或两个平面后剪切后丢弃对象,并且永远不会超过三个)。有许多利用临时一致性的剪裁平面优化,我不会深入讨论这些细节。

此外,您可以通过计算中心点到平面的距离来预先进行一些粗略剔除,并检查该距离是否大于边界框的半径。这将非常便宜地剔除明显“在”或“在外”的对象。或者,您可以将视图向量的点积与视场值的余弦值加上一些“填充”(或者,只是看看它是否为正)进行比较,作为第一个超粗略检查。您会记得,两个向量的点积告诉您它们指向同一方向的程度。与你的视图向量具有负点积的东西当然是你可以安全丢弃的东西,因为它在你身后。

That will work. However, usually one would rather extract the frustum planes and calculate the distances to these. You said "speed is not a big deal", but eventually you may find that it is. After all, one does frustum culling to make things faster.

Multiplying a vertex with a matrix takes the equivalent of 4 dot products, therefore you need the equivalent of 32 dot products to check all 8 corners. Calculating the distance of a point to a plane takes a dot product and an addition, which is somewhat more efficient in the worst case and much more efficient in the average case (since you can often discard an object after clipping after one or two planes, and never more than three). There are a number of optimizations for clip planes that exploit temporary coherence, which I will not go into deeper detail.

Additionally, you can do some coarse culling beforehand by calculating the distance of the center point to a plane and check whether that is greater than the bounding box's radius. This will cull objects that are clearly "in" or "out" very cheaply. Or, alternatively, you could compare the dot product of your view vector to the cosine of your field of view value plus some "padding" (or alternatively, just see if it is positive) as a first ultra-coarse check. As you will remember, the dot product of two vectors tells you how much they point into the same direction. Something that has a negative dot product with your view vector certainly is something you can safely discard, because it's behind you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文