fix: rework sorting

This commit is contained in:
Kazhnuz 2024-11-08 09:47:47 +01:00
parent 3bd966953d
commit f5e32a77a2
3 changed files with 94 additions and 65 deletions

View file

@ -32,13 +32,12 @@ local Sti = require("framework.scenes.world.maps.tiled")
local Camera = require("framework.scenes.world.camera")
local Terrain = require("framework.scenes.world.terrain")
local Sorter = require("framework.scenes.world.sorter")
local Vector3D = require "framework.libs.brinevector3D"
local GFX = require "framework.scenes.world.actors.gfx"
local comparisons = require "framework.scenes.world.zsort"
local function _tryFunction(toUpdate, dt, func)
if (toUpdate ~= nil) then
func(dt)
@ -65,21 +64,15 @@ function World:new(datas)
self.type = self.def.type or "2D"
self.drawShadow = (self.def.drawShadow == true)
self.sorter = Sorter(self)
self.currentCreationID = 0
World.super.new(self)
self:_setSorting()
self:_load()
end
function World:_setSorting()
self.sort = comparisons.depthSort
if self.type == "3D" then
self.sort = comparisons.zSort
end
end
function World:onLoad()
end
@ -359,9 +352,10 @@ end
function World:drawShapes()
local position, dimensions = self.camera:getViewCoordinate()
local shapes = self:getShapeInRect(position, dimensions)
table.sort(shapes, self.sort)
self.sorter:sort(shapes)
for _, shape in ipairs(shapes) do
shape:draw()
shape.zSorted = false
end
end

View file

@ -0,0 +1,89 @@
local Sorter = Object:extend()
local function _depthSort(itemA, itemB)
local aDepth, aID = itemA.depth, itemA.creationID
local bDepth, bID = itemB.depth, itemB.creationID
local comparison = 0
if aDepth > bDepth then
comparison = 1
elseif aDepth < bDepth then
comparison = -1
else
if aID > bID then
comparison = 1
elseif aID < bID then
comparison = -1
end
end
return comparison == -1
end
local function _zSort(itemA, itemB)
local positionA, positionB = utils.vector.floor(itemA.position), utils.vector.floor(itemB.position)
local aY, aZ, aH, aD = positionA.y, itemA.zGround or positionA.z, itemA.dimensions.h, itemA.dimensions.d
local bY, bZ, bH, bD = positionB.y, itemB.zGround or positionB.z, itemB.dimensions.h, itemB.dimensions.d
local comparison = 0
local compareString = ""
if aZ >= bZ + bD then
-- item A is completely above item B
compareString = "est complètement au dessus"
comparison = 1
elseif bZ >= aZ + aD then
-- item B is completely above item A
compareString = "est complètement en dessous"
comparison = -1
elseif aY + aH <= bY then
-- item A is completely behind item B
compareString = "est complètement derrière"
comparison = -1
elseif bY + bH <= aY then
-- item B is completely behind item A
compareString = "est complètement devant"
comparison = 1
elseif aY + aZ + aH + aD >= bY + bZ + bH + bD then --(aY - aZ) + aH > (bY - bZ) + bH then
-- item A's forward-most point is in front of item B's forward-most point
compareString = "à son point le plus en avant (y+h) devant celui"
comparison = 1
elseif aY + aZ + aH + aD <= bY + bZ + bH + bD then --aY < (bY - bZ) + bH then
-- item B's forward-most point is in front of item A's forward-most point
compareString = "à son point le plus en avant (y+h) derrière celui"
comparison = -1
else
-- item A's forward-most point is the same than item B's forward-most point
compareString = "est au même niveau global"
return _depthSort(itemA, itemB)
end
if (love.keyboard.isDown("d")) then
print((itemA.type or "nil") ..
itemA.creationID .. " " .. (compareString .. (" de " .. (itemB.type or "nil"))) .. itemB.creationID)
end
return comparison == -1
end
function Sorter:new(world)
self.world = world
self.mode = world.type or "2D"
end
function Sorter:sort(items)
if (self.mode == "2D") then
self:sort2D(items)
else
self:sort3D(items)
end
end
function Sorter:sort2D(items)
table.sort(items, _depthSort)
end
function Sorter:sort3D(items)
table.sort(items, _zSort)
end
return Sorter

View file

@ -1,54 +0,0 @@
local comparisons = {}
function comparisons.depthSort(itemA, itemB)
local aDepth, aID = itemA.depth, itemA.creationID
local bDepth, bID = itemB.depth, itemB.creationID
local comparison = 0
if aDepth > bDepth then
comparison = 1
elseif aDepth < bDepth then
comparison = -1
else
if aID > bID then
comparison = 1
elseif aID < bID then
comparison = -1
end
end
return comparison == -1
end
function comparisons.zSort(itemA, itemB)
local aY, aZ, aH, aD = itemA.position.y, itemA.position.z, itemA.dimensions.h, itemA.dimensions.d
local bY, bZ,bH, bD = itemB.position.y, itemB.position.z, itemB.dimensions.h, itemB.dimensions.d
local comparison = 0
if aY + aH <= bY then
-- item A is completely behind item B
comparison = -1
elseif bY + bH <= aY then
-- item B is completely behind item A
comparison = 1
elseif aZ >= bZ + bD then
-- item A is completely above item B
comparison = 1
elseif bZ >= aZ + aD then
-- item B is completely above item A
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
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
comparison = -1
else
-- item A's forward-most point is the same than item B's forward-most point
return comparisons.depthSort(itemA, itemB)
end
return comparison == -1
end
return comparisons