0

我正在尝试将本页所示的 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 条件,将进行更多测试。

4

1 回答 1

0

似乎已经修好了。

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
于 2012-02-28T03:35:17.097 回答