Question

I'm trying to port Gomez's Swept-AABB vs AABB collision detection algorithm as shown on this page to Lua, and I can't get it to work. It will detect "collisions" with the output time equal to zero pretty much everywhere, among other inaccuracies. Am I doing something wrong?

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

EDIT: It seems that for all 3 axis that none of the if conditions that assign a value to u0d are triggered, will do some more testing.

Was it helpful?

Solution

Seemed to have fixed it.

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top