立方体/バウンディングボックスの内側または外側にあるかどうかをテストする必要があるオブジェクトを追跡しています。それらが外側にある場合は、光線平面の交差を実行して、立方体の平面の1つ上の点を計算します。光線はボックスの中央から始まり、オブジェクトに向かっています。平面は、立方体を構成する6つの平面の1つです。
私が避けたいのは、6つの平面すべてで光線平面の交差を常にテストしているということです。だから私は賢くて、最初に各平面法線と光線の間の内積を計算すると思いました。次に、角度が最も小さいもの(1に最も近いもの)を選択します。
これは中途半端にしか機能しません。オブジェクトが平面の1つと位置合わせされている場所があり、関数が間違った平面を選択します。ほとんどの場合それは機能します、そして私はそれがなぜであるか疑問に思います。私のアプローチには根本的に何か問題があるに違いないと思います。
これが私の定義した平面で、それぞれにラベルが付いています。座標系の0,0,0は、立方体の1つの角です。
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
私はここで何が欠けていますか?
すべての平面で衝突テストを実行してから、立方体の中心に最も近い点を選択することもできると思いますが、それは無駄のようです。