summaryrefslogtreecommitdiff
path: root/liquid.lua
blob: cdddb020b32bbbdfbea51ef9c0f4221311c04c7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
local Liquid = {}
Liquid.__index = Liquid

local function buildWorldPolygonPoints(entity)
    local points = {}

    if not entity.polygon then
        return points
    end

    for i, point in ipairs(entity.polygon) do
        points[#points+1] = {
            x = entity.x + point.x,
            y = entity.y + point.y
        }
    end

    return points
end

function Liquid:new(source)
    local self = setmetatable({}, Liquid)
    self.entity = source
    self.x = source.x or 0
    self.y = source.y or 0
    self.width = source.width or 0
    self.height = source.height or 0
    self.shape = source.shape
    self.polygon = source.polygon or {}
    self.worldPolygon = buildWorldPolygonPoints(source)
    self.properties = source.properties or {}
    self.type = "liquid"
    self.triangles = {}

    local flat = {}
    for _, p in ipairs(self.worldPolygon) do
        table.insert(flat, p.x)
        table.insert(flat, p.y)
    end

    if #flat >= 6 then
        self.triangles = love.math.triangulate(flat)
    end
    return self
end

function Liquid:getWorldPolygon()
    return self.worldPolygon
end

function Liquid:containsEntityFully(entity)
    local corners = getEntityCorners(entity)

    for _, c in ipairs(corners) do
        if not self:containsPoint(c.x, c.y) then
            return false
        end
    end

    return true
end

function Liquid:containsPoint(px, py)
    local points = self.worldPolygon
    local count = #points
    if count < 3 then return false end

    local inside = false
    local j = count
    for i = 1, count do
        local xi, yi = points[i].x, points[i].y
        local xj, yj = points[j].x, points[j].y
        local intersects = ((yi > py) ~= (yj > py))
            and (px < (xj - xi) * (py - yi) / ((yj - yi) + 1e-9) + xi)
        if intersects then
            inside = not inside
        end
        j = i
    end
    return inside
end

function Liquid:containsEntity(entity)
    if not entity then return false end
    local ex = entity.x or 0
    local ey = entity.y or 0
    local ew = entity.width or 0
    local eh = entity.height or 0

    local sampleX = ex + ew * 0.5
    local sampleY = ey + eh
    return self:containsPoint(sampleX, sampleY)
end

function Liquid:update(dt)
end

return Liquid