From f5e32a77a2c951afc59fbf095b2fd04e37ee8031 Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Fri, 8 Nov 2024 09:47:47 +0100 Subject: [PATCH] fix: rework sorting --- framework/scenes/world/init.lua | 16 ++---- framework/scenes/world/sorter.lua | 89 +++++++++++++++++++++++++++++++ framework/scenes/world/zsort.lua | 54 ------------------- 3 files changed, 94 insertions(+), 65 deletions(-) create mode 100644 framework/scenes/world/sorter.lua delete mode 100644 framework/scenes/world/zsort.lua diff --git a/framework/scenes/world/init.lua b/framework/scenes/world/init.lua index 1868782..49fcfa1 100644 --- a/framework/scenes/world/init.lua +++ b/framework/scenes/world/init.lua @@ -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 diff --git a/framework/scenes/world/sorter.lua b/framework/scenes/world/sorter.lua new file mode 100644 index 0000000..1be0db2 --- /dev/null +++ b/framework/scenes/world/sorter.lua @@ -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 diff --git a/framework/scenes/world/zsort.lua b/framework/scenes/world/zsort.lua deleted file mode 100644 index b141543..0000000 --- a/framework/scenes/world/zsort.lua +++ /dev/null @@ -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 \ No newline at end of file