diff --git a/sonic-radiance.love/birb/modules/world/actors/utils/hitbox3D.lua b/sonic-radiance.love/birb/modules/world/actors/utils/hitbox3D.lua index 261e104..64ec5e0 100644 --- a/sonic-radiance.love/birb/modules/world/actors/utils/hitbox3D.lua +++ b/sonic-radiance.love/birb/modules/world/actors/utils/hitbox3D.lua @@ -123,6 +123,10 @@ function Hitbox3D:getCenter() return self.x + (self.w/2), self.y + (self.h/2), self.z + (self.d/2) end +function Hitbox3D:getCube() + return self.world.bodies:getCube(self) +end + -- COLLISION FUNCTIONS -- Handle Hitbox position diff --git a/sonic-radiance.love/birb/modules/world/utils/compare.lua b/sonic-radiance.love/birb/modules/world/utils/compare.lua new file mode 100644 index 0000000..adfd13e --- /dev/null +++ b/sonic-radiance.love/birb/modules/world/utils/compare.lua @@ -0,0 +1,74 @@ +local comparisons = {} + +function comparisons.zsort(itemA, itemB) + local _, aY, aZ, _, aH, aD = itemA.mainHitbox:getCube() + local aDepth, aID, aType + aDepth = itemA.depth + aID = itemA.creationID + aType = itemA.type + aZ = math.ceil(aZ) + aY = math.ceil(aY) + + local _, bY, bZ, _, bH, bD = itemB.mainHitbox:getCube() + local bDepth, bID, bType + bDepth = itemB.depth + bID = itemB.creationID + bType = itemB.type + bZ = math.ceil(bZ) + bY = math.ceil(bY) + + + --print("comparing " .. aID .. " to " .. bID) + + --print("a", aY, aZ, aH, aD, aDepth, aID, itemA.type) + --print("b", bY, bZ, bH, bD, bDepth, bID, itemB.type) + + local comparison = 0 + + if aZ >= bZ + bD then + -- item A is completely above item B + --graph:add(itemB, itemA) + comparison = 1 + elseif bZ >= aZ + aD then + -- item B is completely above item A + --graph:add(itemA, itemB) + comparison = -1 + elseif aY + aH <= bY then + -- item A is completely behind item B + --graph:add(itemA, itemB) + comparison = -1 + elseif bY + bH <= aY then + -- item B is completely behind item A + --graph:add(itemB, itemA) + comparison = 1 + elseif aY + aH > bY + bH then --(aY - aZ) + aH > (bY - bZ) + bH then + -- item A's forward-most point is in front of item B's forward-most point + --graph:add(itemB, itemA) + comparison = 1 + elseif aY + aH < bY + bH then --aY < (bY - bZ) + bH then + -- item B's forward-most point is in front of item A's forward-most point + --graph:add(itemA, itemB) + comparison = -1 + else + -- item A's forward-most point is the same than item B's forward-most point + if aDepth > bDepth then + --graph:add(itemB, itemA) + comparison = 1 + elseif aDepth < bDepth then + --graph:add(itemA, itemB) + comparison = -1 + else + if aID > bID then + --graph:add(itemA, itemB) + comparison = 1 + elseif aID < bID then + --graph:add(itemB, itemA) + comparison = -1 + end + end + end + + return comparison == -1 +end + +return comparisons diff --git a/sonic-radiance.love/birb/modules/world/world3D.lua b/sonic-radiance.love/birb/modules/world/world3D.lua index 42ee40b..622f53b 100644 --- a/sonic-radiance.love/birb/modules/world/world3D.lua +++ b/sonic-radiance.love/birb/modules/world/world3D.lua @@ -31,6 +31,8 @@ local Bump3D = require(cwd .. "libs.bump-3dpd") local Tsort = require(cwd .. "libs.tsort") local CameraSystem = require(cwd .. "camera") +local comparisons = require(cwd .. "utils.compare") + local PADDING_VALUE = 10/100 function World3D:new(scene, actorlist, mapfile, maptype) @@ -183,87 +185,10 @@ end -- Functions to draw the world function World3D:zSortItems(items) - -- zSorting algorithm taken from bump3D example, adapted to gamecore. - local graph = Tsort.new() - local noOverlap = {} + -- TODO : take from a self.shapes:queryRect() + table.sort(items, comparisons.zsort) - -- Iterate through all visible items, and calculate ordering of all pairs - -- of overlapping items. - -- TODO: Each pair is calculated twice currently. Maybe this is slow? - for _, itemA in ipairs(items) do repeat - local x, y, w, h = self.shapes:getRect(itemA) - local otherItemsFilter = function(other) return other ~= itemA end - local overlapping, len = self.shapes:queryRect(x, y, w, h, otherItemsFilter) - - if len == 0 then - table.insert(noOverlap, itemA) - - break - end - - local _, aY, aZ, _, aH, aD = self.bodies:getCube(itemA.mainHitbox) - local aDepth, aID, aType - aDepth = itemA.depth - aID = itemA.creationID - aType = itemA.type - aZ = math.ceil(aZ) - aY = math.ceil(aY) - - for _, itemB in ipairs(overlapping) do - local _, bY, bZ, _, bH, bD = self.bodies:getCube(itemB.mainHitbox) - local bDepth, bID, bType - bDepth = itemB.depth - bID = itemB.creationID - bType = itemB.type - bZ = math.ceil(bZ) - bY = math.ceil(bY) - - if aZ >= bZ + bD then - -- item A is completely above item B - graph:add(itemB, itemA) - elseif bZ >= aZ + aD then - -- item B is completely above item A - graph:add(itemA, itemB) - elseif aY + aH <= bY then - -- item A is completely behind item B - graph:add(itemA, itemB) - elseif bY + bH <= aY then - -- item B is completely behind item A - graph:add(itemB, itemA) - elseif (aY - aZ) + aH > (bY - bZ) + bH then - -- item A's forward-most point is in front of item B's forward-most point - graph:add(itemB, itemA) - elseif (aY - aZ) + aH < (bY - bZ) + bH then - -- item B's forward-most point is in front of item A's forward-most point - graph:add(itemA, itemB) - else - -- item A's forward-most point is the same than item B's forward-most point - if aDepth > bDepth then - graph:add(itemB, itemA) - elseif aDepth < bDepth then - graph:add(itemA, itemB) - else - if aID > bID then - graph:add(itemA, itemB) - elseif aID < bID then - graph:add(itemB, itemA) - else - error("two object can't have the same ID") - end - end - end - end - until true end - - local sorted, err = graph:sort() - if err then - error(err) - end - for _, item in ipairs(noOverlap) do - table.insert(sorted, item) - end - - return sorted + return items end