Rewrite rope #11

Merged
pyrex merged 12 commits from rewrite_rope into main 2022-12-21 05:44:16 +00:00
Showing only changes of commit 60f1c2e112 - Show all commits

View File

@ -7,6 +7,10 @@ real_modules={}
frame=0 frame=0
function _init() function _init()
-- cls(0)
-- for i in _stepfrom(0.5,-2.5) do print(i) end
-- assert(false)
_doall("init") end _doall("init") end
function _update() function _update()
frame+=1 frame+=1
@ -1096,59 +1100,99 @@ end
-- TODO: Upon adding a point, start from there to see if we need another -- TODO: Upon adding a point, start from there to see if we need another
-- rather than adding at most one -- rather than adding at most one
function rope:_drag1(n1,ax1_new,ay1_new) function rope:_drag1(n1,ax1_new,ay1_new)
local ax1_old,ay1_old=n1.ax,n1.ay local function _sweep_radar(ax_pivot,ay_pivot,ax_far0,ay_far0,ax_far1,ay_far1)
local n0=n1.prev if ax_far0==ax_far1 then
local ax_far=ax_far0
local ax0,ax1=_mnmx(ax_pivot,ax_far)
if n0!=nil then ay_far_old=ay_far0
local ax0,ay0=n0.ax,n0.ay for ay_far_new in _stepfrom(ay_far0,ay_far1) do
for _,anchor in level:anchor_points() do for _,anchor in level:anchor_points() do
if if
-- NOTE: Do we need to look at the new path too? Something (ax0<=anchor.ax and anchor.ax<=ax1) and
-- just feels wrong about this check. _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_old)!=
-- Really our goal is to figure out if moving the end of the _which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far,ay_far_new)
-- path crosses over the anchor, which feels like a point/triangle then
-- collision return anchor
-- We also want to pick the anchor that the ray sweeps over first, not end
-- the closest one. end
-- Maybe we should ay_far_old=ay_far_new
-- (1) sort by angle difference from the original line
-- (2) ignore cases where the angle is not between the two lines
-- (3) ignore cases where the created point is further from the original point
-- than the _intended_ one would be
-- Note that if x or y is held constant, this can be implemented
-- with a sort on x or y. For our game this is true.
--
_in_box(anchor.ax,anchor.ay,ax0,ay0,ax1_old,ay1_old) and
_which_side(anchor.ax,anchor.ay,ax0,ay0,ax1_old,ay1_old) !=
_which_side(anchor.ax,anchor.ay,ax0,ay0,ax1_new,ay1_new)
then
local n05={ax=anchor.ax,ay=anchor.ay,prev=n0,next=n1}
n0.next = n05
n1.prev = n05
end end
elseif ay_far0==ay_far1 then
local ay_far=ay_far0
local ay0,ay1=_mnmx(ay_pivot,ay_far)
ax_far_old=ax_far0
for ax_far_new in _stepfrom(ax_far0,ax_far1) do
for _,anchor in level:anchor_points() do
if
(ay0<=anchor.ay and anchor.ay<=ay1) and
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_old,ay_far)!=
_which_side(anchor.ax,anchor.ay,ax_pivot,ay_pivot,ax_far_new,ay_far)
then
return anchor
end
end
ax_far_old=ax_far_new
end
else
assert(false, "wtf?")
end end
end end
local ax1_old,ay1_old=n1.ax,n1.ay
local n0=n1.prev
while true do
if (n0==nil) break
local anch=_sweep_radar(n0.ax,n0.ay,ax1_old,ay1_old,ax1_new,ay1_new)
if (anch==nil) break
local n05={ax=anch.ax,ay=anch.ay,prev=n0,next=n1}
n0.next=n05
n1.prev=n05
n0=n05
end
local n2=n1.next local n2=n1.next
if n2!=nil then while true do
local ax2,ay2=n2.ax,n2.ay if (n2==nil) break
for _,anchor in level:anchor_points() do local anch=_sweep_radar(n2.ax,n2.ay,ax1_old,ay1_old,ax1_new,ay1_new)
if if (anch==nil) break
_in_box(anchor.ax,anchor.ay,ax1_old,ay1_old,ax2,ay2) and local n15={ax=anch.ax,ay=anch.ay,prev=n1,next=n2}
_which_side(anchor.ax,anchor.ay,ax1_old,ay1_old,ax2,ay2) != n1.next=n15
_which_side(anchor.ax,anchor.ay,ax1_new,ay1_new,ax2,ay2) n2.prev=n15
then n2=n15
local n15={ax=anchor.ax,ay=anchor.ay,prev=n1,next=n2}
n1.next = n15
n2.prev = n15
end
end
end end
n1.ax=ax1_new n1.ax=ax1_new
n1.ay=ay1_new n1.ay=ay1_new
end end
function _stepfrom(x0,x1)
local done=false
if x0==x1 then
return function()
if (done) return nil
done=true return x0
end
end
local mul=1
if (x0>x1) x0,x1,mul=-x0,-x1,-mul
local i=flr(x0)
local top=flr(x1)
return function()
if (done) return nil
i+=1
if i>top then
done = true
if (x1!=flr(x1)) return mul*x1
return nil
end
return mul*i
end
end
function _in_box(x,y,x0,y0,x1,y1) function _in_box(x,y,x0,y0,x1,y1)
x0,x1=_mnmx(x0,x1) x0,x1=_mnmx(x0,x1)
y0,y1=_mnmx(y0,y1) y0,y1=_mnmx(y0,y1)