update to convert poly to mesh

This commit is contained in:
2021-12-23 15:05:00 +01:00
parent 7c62363827
commit 963b3ac174
4 changed files with 273 additions and 212 deletions

View File

@@ -28,11 +28,6 @@
]] ]]
-- require('mobdebug').start() -- require('mobdebug').start()
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
require("lldebugger").start()
end
require 'src/Dependencies' require 'src/Dependencies'
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then

View File

@@ -1,17 +1,23 @@
-- require('mobdebug').start() -- require('mobdebug').start()
Level = Class {}
Level = Class{}
function Level:init() function Level:init()
self.segments = self:createLevel() self.segments = self:createLevel()
self.polygon = self:createPolygon() self.polygon = self:createPolygon()
self.player = {} self.player = {}
self.mesh = {}
end end
function Level:update(dt) function Level:update(dt)
self:createPolygon()
if #self.polygonPoints < 3 then
self.mesh = {}
else
print_r(self.polygonPoints)
self.mesh = poly2mesh(self.polygonPoints)
end
end end
function Level:render() function Level:render()
@@ -20,21 +26,32 @@ function Level:render()
end end
function Level:renderOuterSegments() function Level:renderOuterSegments()
for k,segment in pairs(self.segments) do for k, segment in pairs(self.segments) do segment:render() end
segment:render()
end
end end
function Level:renderBackground() function Level:renderBackground()
love.graphics.draw(gImages["img1"],LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP) love.graphics.draw(gImages["img1"], LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP)
love.graphics.draw(self.mesh, 0, 0)
end end
function Level:createLevel() function Level:createLevel()
local level = { local level = {
[1] = Segment({LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},.5,'down'), [1] = Segment({LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP}, {
[2] = Segment({VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},.5,'left'), VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP
[3] = Segment({VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},{LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},.5,'up'), }, .5, 'down'),
[4] = Segment({LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET},{LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},.5,'right') [2] = Segment({
VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP
}, {
VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET,
VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET
}, .5, 'left'),
[3] = Segment({
VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET,
VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET
}, {LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET}, .5, 'up'),
[4] = Segment({
LEVEL_RENDER_OFFSET, VIRTUAL_HEIGHT - LEVEL_RENDER_OFFSET
}, {LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP}, .5, 'right')
} }
-- local level = { -- local level = {
-- [1] = Segment({LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},.5), -- [1] = Segment({LEVEL_RENDER_OFFSET,LEVEL_RENDER_OFFSET_TOP},{VIRTUAL_WIDTH - LEVEL_RENDER_OFFSET, LEVEL_RENDER_OFFSET_TOP},.5),
@@ -47,56 +64,58 @@ function Level:createLevel()
return level return level
end end
function Level:insideBounds2(x,y) function Level:insideBounds2(x, y)
local shape = love.physics.newPolygonShape(self.polygonPoints) local shape = love.physics.newPolygonShape(self.polygonPoints)
return shape:testPoint(x,y) return shape:testPoint(x, y)
end end
function Level:insideBounds(x,y, segments) function Level:insideBounds(x, y, segments)
if not segments then if not segments then segments = self.segments end
segments = self.segments
end
local up,down,left,right = false local up, down, left, right = false
local upSeg, downSeg, leftSeg, rightSeg = nil local upSeg, downSeg, leftSeg, rightSeg = nil
-- find closest segments -- find closest segments
for i, segment in pairs(segments) do for i, segment in pairs(segments) do
-- check raycast on y axis -- check raycast on y axis
if segment.vertical then if segment.vertical then
if y <= math.max(segment.firstPointY, segment.secondPointY) and if y <= math.max(segment.firstPointY, segment.secondPointY) and y >=
y >= math.min(segment.firstPointY, segment.secondPointY) then math.min(segment.firstPointY, segment.secondPointY) then
if x <= segment.firstPointX then if x <= segment.firstPointX then
if not rightSeg then if not rightSeg then
rightSeg = segment rightSeg = segment
elseif math.abs(segment.firstPointX - x) < math.abs(rightSeg.firstPointX - x) then elseif math.abs(segment.firstPointX - x) <
rightSeg = segment math.abs(rightSeg.firstPointX - x) then
end rightSeg = segment
else
if not leftSeg then
leftSeg = segment
elseif math.abs(segment.firstPointX - x) < math.abs(leftSeg.firstPointX - x) then
leftSeg = segment
end
end end
else
if not leftSeg then
leftSeg = segment
elseif math.abs(segment.firstPointX - x) <
math.abs(leftSeg.firstPointX - x) then
leftSeg = segment
end
end
end end
end end
if segment.horizontal then if segment.horizontal then
if x <= math.max(segment.firstPointX, segment.secondPointX) and if x <= math.max(segment.firstPointX, segment.secondPointX) and x >=
x >= math.min(segment.firstPointX, segment.secondPointX) then math.min(segment.firstPointX, segment.secondPointX) then
if y <= segment.firstPointY then if y <= segment.firstPointY then
if not downSeg then if not downSeg then
downSeg = segment downSeg = segment
elseif math.abs(segment.firstPointY - y) < math.abs(downSeg.firstPointY - y) then elseif math.abs(segment.firstPointY - y) <
downSeg = segment math.abs(downSeg.firstPointY - y) then
end downSeg = segment
else
if not upSeg then
upSeg = segment
elseif math.abs(segment.firstPointY - y) < math.abs(upSeg.firstPointY - y) then
upSeg = segment
end
end end
else
if not upSeg then
upSeg = segment
elseif math.abs(segment.firstPointY - y) <
math.abs(upSeg.firstPointY - y) then
upSeg = segment
end
end
end end
end end
end end
@@ -104,23 +123,23 @@ function Level:insideBounds(x,y, segments)
return false return false
end end
if rightSeg.face ~= 'left' or leftSeg.face ~= 'right' or upSeg.face ~= 'down' or downSeg.face ~= 'up' then if rightSeg.face ~= 'left' or leftSeg.face ~= 'right' or upSeg.face ~=
return false 'down' or downSeg.face ~= 'up' then return false end
end
return true return true
end end
function Level:insideBounds3(x,y) function Level:insideBounds3(x, y)
x = math.floor(x) x = math.floor(x)
y = math.floor(y) y = math.floor(y)
local oddNodes = false local oddNodes = false
local j = #self.polygon local j = #self.polygon
local polygon = self.polygon local polygon = self.polygon
for i = 1, #polygon do for i = 1, #polygon do
if (polygon[i].y < y and polygon[j].y >= y or polygon[j].y < y and polygon[i].y >= y) then if (polygon[i].y < y and polygon[j].y >= y or polygon[j].y < y and
if (polygon[i].x + ( y - polygon[i].y ) / (polygon[j].y - polygon[i].y) * (polygon[j].x - polygon[i].x) < x) then polygon[i].y >= y) then
oddNodes = not oddNodes if (polygon[i].x + (y - polygon[i].y) /
end (polygon[j].y - polygon[i].y) * (polygon[j].x - polygon[i].x) <
x) then oddNodes = not oddNodes end
end end
j = i j = i
end end
@@ -128,17 +147,18 @@ function Level:insideBounds3(x,y)
end end
function Level:createPolygon() function Level:createPolygon()
local polygon = {} local polygon = {}
local polygonPoints = {} local polygonPoints = {}
local j = 1 local j = 1
for i,segment in ipairs(self.segments) do for i, segment in ipairs(self.segments) do
polygon[i] = {} polygon[i] = {}
polygon[i+1] = {} polygon[i + 1] = {}
polygon[i].x, polygon[i].y, polygon[i+1].x, polygon[i+1].y = segment:segmentToPoints() polygon[i].x, polygon[i].y, polygon[i + 1].x, polygon[i + 1].y =
segment:segmentToPoints()
polygonPoints[j] = polygon[i].x polygonPoints[j] = polygon[i].x
polygonPoints[j+1] = polygon[i].y polygonPoints[j + 1] = polygon[i].y
polygonPoints[j+2] = polygon[i+1].x polygonPoints[j + 2] = polygon[i + 1].x
polygonPoints[j+3] = polygon[i+1].y polygonPoints[j + 3] = polygon[i + 1].y
j = j + 4 j = j + 4
i = i + 1 i = i + 1
end end
@@ -146,24 +166,22 @@ function Level:createPolygon()
return polygon return polygon
end end
function Level:pointOnEdge(x,y,segments) function Level:pointOnEdge(x, y, segments)
if not segments then if not segments then segments = self.segments end
segments = self.segments
end
local margin = 2 local margin = 2
for i,segment in pairs(segments) do for i, segment in pairs(segments) do
if segment.vertical then --vertical line if segment.vertical then -- vertical line
if x >= segment.firstPointX - margin and x <= segment.firstPointX + margin and if x >= segment.firstPointX - margin and x <= segment.firstPointX +
y <= math.max(segment.firstPointY, segment.secondPointY) and margin and y <=
y >= math.min(segment.firstPointY, segment.secondPointY) math.max(segment.firstPointY, segment.secondPointY) and y >=
then math.min(segment.firstPointY, segment.secondPointY) then
return true return true
end end
elseif segment.horizontal then --horizontal line elseif segment.horizontal then -- horizontal line
if y >= segment.firstPointY - margin and y <= segment.firstPointY + margin and if y >= segment.firstPointY - margin and y <= segment.firstPointY +
x <= math.max(segment.firstPointX, segment.secondPointX) and margin and x <=
x >= math.min(segment.firstPointX, segment.secondPointX) math.max(segment.firstPointX, segment.secondPointX) and x >=
then math.min(segment.firstPointX, segment.secondPointX) then
return true return true
end end
end end
@@ -171,21 +189,21 @@ function Level:pointOnEdge(x,y,segments)
return false return false
end end
function Level:getTouchingSegment(x,y) function Level:getTouchingSegment(x, y)
local margin = 2 local margin = 2
for i,segment in pairs(self.segments) do for i, segment in pairs(self.segments) do
if segment.vertical then --vertical line if segment.vertical then -- vertical line
if x >= segment.firstPointX - margin and x <= segment.firstPointX + margin and if x >= segment.firstPointX - margin and x <= segment.firstPointX +
y <= math.max(segment.firstPointY, segment.secondPointY) and margin and y <=
y >= math.min(segment.firstPointY, segment.secondPointY) math.max(segment.firstPointY, segment.secondPointY) and y >=
then math.min(segment.firstPointY, segment.secondPointY) then
return i, segment return i, segment
end end
elseif segment.horizontal then --horizontal line elseif segment.horizontal then -- horizontal line
if y >= segment.firstPointY - margin and y <= segment.firstPointY + margin and if y >= segment.firstPointY - margin and y <= segment.firstPointY +
x <= math.max(segment.firstPointX, segment.secondPointX) and margin and x <=
x >= math.min(segment.firstPointX, segment.secondPointX) math.max(segment.firstPointX, segment.secondPointX) and x >=
then math.min(segment.firstPointX, segment.secondPointX) then
return i, segment return i, segment
end end
end end
@@ -196,19 +214,21 @@ end
function Level:cutLevel() function Level:cutLevel()
local newSegs = self.player.trailSegments local newSegs = self.player.trailSegments
local startSegi, startSeg = self.player.trailStartSegment[1],self.player.trailStartSegment[2] local startSegi, startSeg = self.player.trailStartSegment[1],
local endSegi, endSeg = self.player.trailFinishSegment[1],self.player.trailFinishSegment[2] self.player.trailStartSegment[2]
local endSegi, endSeg = self.player.trailFinishSegment[1],
self.player.trailFinishSegment[2]
local first = 0 local first = 0
local last = 0 local last = 0
local firstFace = '' local firstFace = ''
--check if it is same start and finish segment -- check if it is same start and finish segment
if startSegi == endSegi then if startSegi == endSegi then
-- print("cutlevel same start and end segment: "..tostring(startSegi)..' - '..tostring(endSegi)) -- print("cutlevel same start and end segment: "..tostring(startSegi)..' - '..tostring(endSegi))
local s = {} local s = {}
-- split the start/end segment -- split the start/end segment
local new = {} local new = {}
local split = self.segments[startSegi]:copy() local split = self.segments[startSegi]:copy()
newSegs[1]:joinPerpendicular(split) newSegs[1]:joinPerpendicular(split)
newSegs[#newSegs]:joinPerpendicular(split) newSegs[#newSegs]:joinPerpendicular(split)
@@ -221,7 +241,7 @@ function Level:cutLevel()
end end
local part1, part2, temp = {} local part1, part2, temp = {}
local inOrder = false local inOrder = false
local j,k = 1,1 local j, k = 1, 1
local insertedNewSegs = false local insertedNewSegs = false
-- print("-- Create new segments table") -- print("-- Create new segments table")
-- create the new set of segments -- create the new set of segments
@@ -231,7 +251,8 @@ function Level:cutLevel()
-- print("Reached the segment being cut") -- print("Reached the segment being cut")
-- print_r(self.segments[k]) -- print_r(self.segments[k])
-- print("split the segment") -- print("split the segment")
part1, temp, part2 = self.segments[k]:splitInThreeWithSegments(newSegs[1],newSegs[#newSegs]) part1, temp, part2 = self.segments[k]:splitInThreeWithSegments(
newSegs[1], newSegs[#newSegs])
-- print("part1") -- print("part1")
part1:debug() part1:debug()
-- print("part2") -- print("part2")
@@ -245,7 +266,7 @@ function Level:cutLevel()
-- print("-- insert new segments into new set") -- print("-- insert new segments into new set")
for i, segment in pairs(newSegs) do for i, segment in pairs(newSegs) do
if i + 1 < #newSegs then if i + 1 < #newSegs then
newSegs[i+1]:joinPerpendicular(segment) newSegs[i + 1]:joinPerpendicular(segment)
end end
new[j] = segment:copy() new[j] = segment:copy()
j = j + 1 j = j + 1
@@ -266,7 +287,7 @@ function Level:cutLevel()
new = self:orderSegments(new) new = self:orderSegments(new)
-- print_r(new) -- print_r(new)
-- print("calculate faces") -- print("calculate faces")
self:calculateSegmentFaces(new,new[1].face) self:calculateSegmentFaces(new, new[1].face)
-- print_r(new) -- print_r(new)
self.segments = new self.segments = new
else else
@@ -279,8 +300,8 @@ function Level:cutLevel()
local j = 1 local j = 1
local last = #self.segments local last = #self.segments
local insertedNewSegments = false local insertedNewSegments = false
local savedStart,savedEnd = {} local savedStart, savedEnd = {}
local board2StartSegi,board2EndSegi = 0 local board2StartSegi, board2EndSegi = 0
-- create first board -- create first board
while k <= #self.segments do while k <= #self.segments do
-- print("-----start Loop for "..tostring(k).."-----") -- print("-----start Loop for "..tostring(k).."-----")
@@ -292,14 +313,15 @@ function Level:cutLevel()
newSegs[1]:joinPerpendicular(self.segments[k]) newSegs[1]:joinPerpendicular(self.segments[k])
newSegs[1]:debug() newSegs[1]:debug()
-- print("newSegs[1] is joined -- finished") -- print("newSegs[1] is joined -- finished")
local startPart1, startPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[1]) local startPart1, startPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[1])
-- print("-- Segment k split into 2 segments by newsegs[1]: ") -- print("-- Segment k split into 2 segments by newsegs[1]: ")
startPart1:debug() startPart1:debug()
startPart2:debug() startPart2:debug()
if self.segments[last]:endEqualsStartOf(self.segments[k]) or if self.segments[last]:endEqualsStartOf(self.segments[k]) or
self.segments[last]:startEqualsStartOf(self.segments[k]) then -- last one is linked to the start of this one self.segments[last]:startEqualsStartOf(self.segments[k]) then -- last one is linked to the start of this one
--keep first part of segment -- keep first part of segment
-- print("-- keep first part of the k segment") -- print("-- keep first part of the k segment")
self.segments[k] = startPart1 self.segments[k] = startPart1
savedStart = startPart2 savedStart = startPart2
@@ -327,10 +349,11 @@ function Level:cutLevel()
end end
-- print_r(board1) -- print_r(board1)
local endPart1, endPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs]) local endPart1, endPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs])
-- print("-- proceed to insert the second split segment") -- print("-- proceed to insert the second split segment")
if self.segments[last]:endEqualsEndOf(self.segments[k]) or if self.segments[last]:endEqualsEndOf(self.segments[k]) or
self.segments[last]:startEqualsEndOf(self.segments[k]) then -- next one is linked to the start of this one self.segments[last]:startEqualsEndOf(self.segments[k]) then -- next one is linked to the start of this one
self.segments[k] = endPart1 self.segments[k] = endPart1
savedEnd = endPart2 savedEnd = endPart2
-- print("-- keep first part of the k segment") -- print("-- keep first part of the k segment")
@@ -353,7 +376,8 @@ function Level:cutLevel()
newSegs[#newSegs]:joinPerpendicular(self.segments[k]) newSegs[#newSegs]:joinPerpendicular(self.segments[k])
newSegs[#newSegs]:debug() newSegs[#newSegs]:debug()
-- print("newSegs[#newSegs] is joined -- finished") -- print("newSegs[#newSegs] is joined -- finished")
local endPart1, endPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs]) local endPart1, endPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[#newSegs])
-- print("-- Segment k split into 2 segments by newsegs[#newSegs]: ") -- print("-- Segment k split into 2 segments by newsegs[#newSegs]: ")
endPart1:debug() endPart1:debug()
endPart2:debug() endPart2:debug()
@@ -387,7 +411,8 @@ function Level:cutLevel()
end end
-- print_r(board1) -- print_r(board1)
local startPart1, startPart2 = self.segments[k]:splitInTwoWithSegment(newSegs[1]) local startPart1, startPart2 =
self.segments[k]:splitInTwoWithSegment(newSegs[1])
-- print("-- Segment k split into 2 segments by newsegs[1]: ") -- print("-- Segment k split into 2 segments by newsegs[1]: ")
startPart1:debug() startPart1:debug()
startPart2:debug() startPart2:debug()
@@ -398,7 +423,7 @@ function Level:cutLevel()
savedstart = startPart2 savedstart = startPart2
else else
self.segments[k] = startPart2 self.segments[k] = startPart2
savedStart= startPart1 savedStart = startPart1
end end
board1[j] = self.segments[k]:copy() board1[j] = self.segments[k]:copy()
@@ -417,7 +442,7 @@ function Level:cutLevel()
end end
-- print("order segments in cutlevel board1") -- print("order segments in cutlevel board1")
board1 = self:orderSegments(board1) board1 = self:orderSegments(board1)
self:calculateSegmentFaces(board1,board1[1].face) self:calculateSegmentFaces(board1, board1[1].face)
-- print("PREPARE BOARD 1 -- FINAL") -- print("PREPARE BOARD 1 -- FINAL")
-- print_r(board1) -- print_r(board1)
@@ -485,7 +510,7 @@ function Level:cutLevel()
-- print("order segments in cutlevel board2") -- print("order segments in cutlevel board2")
board2 = self:orderSegments(board2) board2 = self:orderSegments(board2)
self:calculateSegmentFaces(board2,board2[1].face) self:calculateSegmentFaces(board2, board2[1].face)
-- print("PREPARE BOARD 2 -- FINAL") -- print("PREPARE BOARD 2 -- FINAL")
-- print_r(board2) -- print_r(board2)
@@ -494,20 +519,21 @@ function Level:cutLevel()
elseif self:containsBalls(board2) == 0 then elseif self:containsBalls(board2) == 0 then
self.segments = board1 self.segments = board1
else else
self.segments = self:getPerimeter(board1) > self:getPerimeter(board2) and board1 or board2 self.segments = self:getPerimeter(board1) >
self:getPerimeter(board2) and board1 or board2
end end
end end
end end
function Level:orderSegments(segs) function Level:orderSegments(segs)
--returns the list of segments in the level linked to each other in order and perpendicular to each other -- returns the list of segments in the level linked to each other in order and perpendicular to each other
local new = {} local new = {}
-- -- print('----- order Segments : ') -- -- print('----- order Segments : ')
-- print_s(segs) -- print_s(segs)
new[1] = segs[1] new[1] = segs[1]
table.remove(segs,1) table.remove(segs, 1)
local found = false local found = false
local k = #segs local k = #segs
@@ -524,18 +550,19 @@ function Level:orderSegments(segs)
-- -- print("new[i] end equals start of ") -- -- print("new[i] end equals start of ")
-- s:debug() -- s:debug()
if new[i].vertical == s.vertical and new[i].horizontal == s.horizontal then if new[i].vertical == s.vertical and new[i].horizontal ==
s.horizontal then
-- -- print("join contiguous "..tostring(i).. 'with'..tostring(j)) -- -- print("join contiguous "..tostring(i).. 'with'..tostring(j))
new[i]:joinContiguous(s) new[i]:joinContiguous(s)
table.remove(segs,j) table.remove(segs, j)
i = i - 1 i = i - 1
k = k - 1 k = k - 1
break break
else else
-- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j)) -- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j))
s:joinPerpendicular(new[i]) s:joinPerpendicular(new[i])
new[i+1] = s new[i + 1] = s
table.remove(segs,j) table.remove(segs, j)
break break
end end
elseif new[i]:endEqualsEndOf(s) then elseif new[i]:endEqualsEndOf(s) then
@@ -544,33 +571,38 @@ function Level:orderSegments(segs)
-- -- print("new[i] end equals end of ") -- -- print("new[i] end equals end of ")
-- s:debug() -- s:debug()
s:switchDirection() s:switchDirection()
if new[i].vertical == s.vertical and new[i].horizontal == s.horizontal then if new[i].vertical == s.vertical and new[i].horizontal ==
s.horizontal then
-- -- print("join contiguous "..tostring(i).. 'with'..tostring(j)) -- -- print("join contiguous "..tostring(i).. 'with'..tostring(j))
new[i]:joinContiguous(s) new[i]:joinContiguous(s)
table.remove(segs,j) table.remove(segs, j)
i = i - 1 i = i - 1
k = k - 1 k = k - 1
break break
else else
-- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j)) -- -- print("join perpendicular "..tostring(i).. 'with'..tostring(j))
s:joinPerpendicular(new[i]) s:joinPerpendicular(new[i])
new[i+1] = s new[i + 1] = s
table.remove(segs,j) table.remove(segs, j)
break break
end end
end end
end end
local fi, fs = 0,{} local fi, fs = 0, {}
if not found then if not found then
-- -- print("search didnt yield any segment") -- -- print("search didnt yield any segment")
local margin = 2 local margin = 2
while not found and margin < 5 do while not found and margin < 5 do
fi, fs = self:findNearestSegment(new[i].secondPointX,new[i].secondPointY,segs,margin) fi, fs = self:findNearestSegment(new[i].secondPointX,
new[i].secondPointY, segs,
margin)
if not fs then if not fs then
fi, fs = self:findNearestSegment(new[i].firstPointX,new[i].firstPointY,segs,margin) fi, fs = self:findNearestSegment(new[i].firstPointX,
new[i].firstPointY, segs,
margin)
if not fs then if not fs then
margin = margin + 1 margin = margin + 1
@@ -586,20 +618,20 @@ function Level:orderSegments(segs)
if new[i].vertical == fs.vertical then if new[i].vertical == fs.vertical then
-- -- print("join contiguous "..tostring(i).. 'with'..tostring(fi)) -- -- print("join contiguous "..tostring(i).. 'with'..tostring(fi))
new[i]:joinContiguous(fs) new[i]:joinContiguous(fs)
table.remove(segs,fi) table.remove(segs, fi)
i = i - 1 i = i - 1
k = k - 1 k = k - 1
else else
-- -- print("join perpendicular "..tostring(i).. 'with'..tostring(fi)) -- -- print("join perpendicular "..tostring(i).. 'with'..tostring(fi))
fs:joinPerpendicular(new[i]) fs:joinPerpendicular(new[i])
new[i+1] = fs new[i + 1] = fs
table.remove(segs,fi) table.remove(segs, fi)
end end
end end
end end
if not found then if not found then
-- print("ERROR -- order segments does not find next segment to ") -- print("ERROR -- order segments does not find next segment to ")
new[i]:debug("number: " ..tostring(i)) new[i]:debug("number: " .. tostring(i))
break break
else else
found = false found = false
@@ -619,13 +651,13 @@ function Level:calculateSegmentFaces(segments, firstFace)
if k + 1 <= #segments then if k + 1 <= #segments then
if face == 'up' then if face == 'up' then
if s.direction == 'right' then if s.direction == 'right' then
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'left' face = 'left'
else else
face = 'right' face = 'right'
end end
else else
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'right' face = 'right'
else else
face = 'left' face = 'left'
@@ -633,13 +665,13 @@ function Level:calculateSegmentFaces(segments, firstFace)
end end
elseif face == 'down' then elseif face == 'down' then
if s.direction == 'right' then if s.direction == 'right' then
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'right' face = 'right'
else else
face = 'left' face = 'left'
end end
else else
if segments[k+1].direction == 'up' then if segments[k + 1].direction == 'up' then
face = 'left' face = 'left'
else else
face = 'right' face = 'right'
@@ -647,13 +679,13 @@ function Level:calculateSegmentFaces(segments, firstFace)
end end
elseif face == 'right' then elseif face == 'right' then
if s.direction == 'up' then if s.direction == 'up' then
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'down' face = 'down'
else else
face = 'up' face = 'up'
end end
else else
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'up' face = 'up'
else else
face = 'down' face = 'down'
@@ -661,13 +693,13 @@ function Level:calculateSegmentFaces(segments, firstFace)
end end
elseif face == 'left' then elseif face == 'left' then
if s.direction == 'up' then if s.direction == 'up' then
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'up' face = 'up'
else else
face = 'down' face = 'down'
end end
else else
if segments[k+1].direction == 'right' then if segments[k + 1].direction == 'right' then
face = 'down' face = 'down'
else else
face = 'up' face = 'up'
@@ -680,36 +712,28 @@ end
function Level:getPerimeter(segments) function Level:getPerimeter(segments)
local p = 0 local p = 0
if not segments then if not segments then segments = self.segments end
segments = self.segments for k, s in pairs(segments) do p = p + s:length() end
end
for k, s in pairs(segments) do
p = p + s:length()
end
return p return p
end end
function Level:findNearestSegment(x,y,segments,margin) function Level:findNearestSegment(x, y, segments, margin)
if not segments then if not segments then segments = self.segments end
segments = self.segments if not margin then margin = 2 end
end
if not margin then
margin = 2
end
-- find a touching segment within margins -- find a touching segment within margins
for i,segment in pairs(segments) do for i, segment in pairs(segments) do
if segment.vertical then --vertical line if segment.vertical then -- vertical line
if x >= segment.firstPointX - margin and x <= segment.firstPointX + margin and if x >= segment.firstPointX - margin and x <= segment.firstPointX +
y <= math.max(segment.firstPointY, segment.secondPointY) and margin and y <=
y >= math.min(segment.firstPointY, segment.secondPointY) math.max(segment.firstPointY, segment.secondPointY) and y >=
then math.min(segment.firstPointY, segment.secondPointY) then
return i, segment return i, segment
end end
elseif segment.horizontal then --horizontal line elseif segment.horizontal then -- horizontal line
if y >= segment.firstPointY - margin and y <= segment.firstPointY + margin and if y >= segment.firstPointY - margin and y <= segment.firstPointY +
x <= math.max(segment.firstPointX, segment.secondPointX) and margin and x <=
x >= math.min(segment.firstPointX, segment.secondPointX) math.max(segment.firstPointX, segment.secondPointX) and x >=
then math.min(segment.firstPointX, segment.secondPointX) then
return i, segment return i, segment
end end
end end
@@ -719,13 +743,12 @@ end
function Level:containsBalls(segments) function Level:containsBalls(segments)
-- returns numbere of balls inside the bounds passed in or self.segments -- returns numbere of balls inside the bounds passed in or self.segments
if not segments then if not segments then segments = self.segments end
segments = self.segments
end
local counter = 0 local counter = 0
for k,b in pairs(self.balls) do for k, b in pairs(self.balls) do
if self:insideBounds(b.x + 4, b.y + 4,segments) or self:pointOnEdge(b.x+4, b.y+4, seegments) then if self:insideBounds(b.x + 4, b.y + 4, segments) or
self:pointOnEdge(b.x + 4, b.y + 4, seegments) then
counter = counter + 1 counter = counter + 1
end end
end end

View File

@@ -71,3 +71,46 @@ function print_s(segments)
s:debug(tostring(k)) s:debug(tostring(k))
end end
end end
-- convert a list of points forming a polygon {x1, y1, x2, y2, ...} into a mesh
function poly2mesh(points)
-- remove duplicates???
local polypts = love.math.triangulate(points)
local tlist
local vnums = {}
local vcoords = {}
do
local verthash = {}
local n = 0
local v
-- use unique vertices by using a coordinate hash table
for i = 1, #polypts do
for j = 1, 3 do
local px = polypts[i][j * 2 - 1]
local py = polypts[i][j * 2]
if not verthash[px] then verthash[px] = {} end
if not verthash[px][py] then
n = n + 1
verthash[px][py] = n
vcoords[n * 2 - 1] = px
vcoords[n * 2] = py
v = n
else
v = verthash[px][py]
end
vnums[(i - 1) * 3 + j] = v
end
end
end
local mesh = love.graphics.newMesh(#vcoords, "triangles", "static")
for i = 1, #vcoords / 2 do
local x, y = vcoords[i * 2 - 1], vcoords[i * 2]
-- Here's where the UVs are assigned
mesh:setVertex(i, x, y, x / 50, y / 50, .5, .5, .9, 1)
end
mesh:setVertexMap(vnums)
return mesh
end

View File

@@ -21,7 +21,7 @@ function PlayState:enter()
end end
function PlayState:update(dt) function PlayState:update(dt)
-- self.level:update(dt) self.level:update(dt)
self.player:update(dt) self.player:update(dt)
self:updateBalls(dt, self.level) self:updateBalls(dt, self.level)
end end