fix: fix zsorting crash
This commit is contained in:
parent
b4f7cdb44b
commit
b1bd072f94
3 changed files with 83 additions and 80 deletions
|
@ -123,6 +123,10 @@ function Hitbox3D:getCenter()
|
||||||
return self.x + (self.w/2), self.y + (self.h/2), self.z + (self.d/2)
|
return self.x + (self.w/2), self.y + (self.h/2), self.z + (self.d/2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Hitbox3D:getCube()
|
||||||
|
return self.world.bodies:getCube(self)
|
||||||
|
end
|
||||||
|
|
||||||
-- COLLISION FUNCTIONS
|
-- COLLISION FUNCTIONS
|
||||||
-- Handle Hitbox position
|
-- Handle Hitbox position
|
||||||
|
|
||||||
|
|
74
sonic-radiance.love/birb/modules/world/utils/compare.lua
Normal file
74
sonic-radiance.love/birb/modules/world/utils/compare.lua
Normal file
|
@ -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
|
|
@ -31,6 +31,8 @@ local Bump3D = require(cwd .. "libs.bump-3dpd")
|
||||||
local Tsort = require(cwd .. "libs.tsort")
|
local Tsort = require(cwd .. "libs.tsort")
|
||||||
local CameraSystem = require(cwd .. "camera")
|
local CameraSystem = require(cwd .. "camera")
|
||||||
|
|
||||||
|
local comparisons = require(cwd .. "utils.compare")
|
||||||
|
|
||||||
local PADDING_VALUE = 10/100
|
local PADDING_VALUE = 10/100
|
||||||
|
|
||||||
function World3D:new(scene, actorlist, mapfile, maptype)
|
function World3D:new(scene, actorlist, mapfile, maptype)
|
||||||
|
@ -183,87 +185,10 @@ end
|
||||||
-- Functions to draw the world
|
-- Functions to draw the world
|
||||||
|
|
||||||
function World3D:zSortItems(items)
|
function World3D:zSortItems(items)
|
||||||
-- zSorting algorithm taken from bump3D example, adapted to gamecore.
|
-- TODO : take from a self.shapes:queryRect()
|
||||||
local graph = Tsort.new()
|
table.sort(items, comparisons.zsort)
|
||||||
local noOverlap = {}
|
|
||||||
|
|
||||||
-- Iterate through all visible items, and calculate ordering of all pairs
|
return items
|
||||||
-- 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
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue