2011-07-04 92 views
1

我正在跟踪需要测试的对象,如果它们位于立方体/边界框的内部或外部。如果它们在外面,我做一个射线平面相交来计算立方体的一个平面上的一个点。射线从盒子的中心开始,指向物体。飞机是组成立方体的6个飞机之一。在射线平面交叉点之前选择边界框的相关平面

我想避免的是我一直在6个平面的每一个平面上测试射线平面相交。所以我认为我会很聪明,首先计算每个平面法线和射线之间的点积。然后选择角度最小的一个(最接近1)。

这只能工作一半。有物体与其中一个平面对齐时的位置,我的功能选择了错误的平面。大多数情况下,虽然它工作,我想知道这是为什么。我认为我的方法肯定有一些根本性的错误。

这里是我定义的平面,每个平面都有一个标签。坐标系的0,0,0是立方体的一个角。

planes = { 
    xnear = { normal = {1, 0, 0}, d = 0 }, 
    xfar = { normal = {-1, 0, 0}, d = cubeSize.x }, 
    ynear = { normal = {0, 1, 0}, d = 0 }, 
    yfar = { normal = {0, -1, 0}, d = cubeSize.y }, 
    znear = { normal = {0, 0, 1}, d = 0 }, 
    zfar = { normal = {0, 0, -1}, d = cubeSize.z }, 
} 

然后我用下面的功能:

-- Determine what plane to use for collision testing. The angle is calculated 
-- between the plane normal and the direction of the ray 
function whatPlane(pos) 
local direction = vec3.sub(cubeCenter, pos) 
local result 
local max = -1 
for label, plane in pairs(planes) do 
    local dotproduct = vec3.dot(plane.normal, direction) 
    if dotproduct > max then 
     max = dotproduct 
     result = label 
    end 
end 
return result 
end 

什么,我在这里丢失?

我想我可以在每架飞机上做碰撞测试,然后选择最接近立方体中心的点,但这看起来很浪费。

回答

1

如果立方体确实是一个立方体,即所有维度都相同(并且只在正常多面体的中心的情况下),那么您的论点会很好。但是看起来你对每个轴有不同的尺寸。

如果一个长度相当小(想象一个非常薄的盒子),无论你看到什么方向,几乎在任何情况下你都会碰到那些大飞机,而且几乎从不会出现薄边。

如果您通过盒子的确切长度缩放方向,则可以对此进行补偿。即而不是direction您使用direction/(cubeSize.x,cubeSize.y,cubeSize.z)其中divison按坐标完成。

另一个说法:请注意,比较工作正常,也与非标准化的方向,但如果你保持你的点积未标准化,你可能会遇到其他问题。

+0

这很有道理。它现在有效!干杯 –