我正试图将Gomez的Swept AABB与AABB碰撞检测算法(如本页所示)移植到Lua,但我无法使其工作。它将在几乎所有地方检测输出时间等于零的"碰撞",以及其他不准确之处。我做错什么了吗?
local axis = {"x","y","z"}
-- box1 is the moving box, disp is the box's displacement, box2 is stationary
function Collision.swept_aabb_vs_aabb(box1, disp, box2)
local a = box2
local b = box1
local amin = a:minCorner()
local amax = a:maxCorner()
local bmin = b:minCorner()
local bmax = b:maxCorner()
local u0d, u1d = vector(0,0,0), vector(1,1,1)
for i=1,3 do
local ax = axis[i]
if amax[ax] < bmin[ax] and disp[ax] < 0 then
u0d[ax] = (amax[ax] - bmin[ax]) / disp[ax]
elseif bmax[ax] < amin[ax] and disp[ax] > 0 then
u0d[ax] = (amin[ax] - bmax[ax]) / disp[ax]
end
if bmax[ax] > amin[ax] and disp[ax] < 0 then
u1d[ax] = (amin[ax] - bmax[ax]) / disp[ax]
elseif amax[ax] > bmin[ax] and disp[ax] > 0 then
u1d[ax] = (amax[ax] - bmin[ax]) / disp[ax]
end
end
local u0 = max(u0d.x,u0d.y,u0d.z)
local u1 = min(u1d.x,u1d.y,u1d.z)
if u0 <= u1 then return u0 else return nil end
end
编辑:对于所有3个轴,似乎没有一个为u0d赋值的if条件被触发,将进行更多的测试。
似乎已经修复了它。
local axis = {"x","y","z"}
function Collision.swept_aabb_vs_aabb(box1, disp, box2)
local amin = box2:minCorner()
local amax = box2:maxCorner()
local bmin = box1:minCorner()
local bmax = box1:maxCorner()
local u0, u1 = -math.huge, math.huge
for i=1,3 do
local ax = axis[i]
if amax[ax] < bmin[ax]then
if disp[ax] < 0 then
local u_0 = (amax[ax] - bmin[ax]) / disp[ax]
if u_0 > u0 then
u0 = u_0
end
else
return nil
end
elseif bmax[ax] < amin[ax] then
if disp[ax] > 0 then
local u_0 = (amin[ax] - bmax[ax]) / disp[ax]
if u_0 > u0 then
u0 = u_0
end
else
return nil
end
end
if bmax[ax] > amin[ax] and disp[ax] < 0 then
local u_1 = (amin[ax] - bmax[ax]) / disp[ax]
if u_1 < u1 then u1 = u_1 end
elseif amax[ax] > bmin[ax] and disp[ax] > 0 then
local u_1 = (amax[ax] - bmin[ax]) / disp[ax]
if u_1 < u1 then u1 = u_1 end
end
end
if u0 <= u1 and u0 >= 0 and u0 <= 1 then return u0 else return nil end
end