Compare commits

..

2 Commits

Author SHA1 Message Date
29d86556ca Again, reduce the level of useless work 2022-12-17 13:45:46 -08:00
13e6c382be My fat bresenham implementation is really slow 2022-12-17 13:30:48 -08:00

View File

@ -679,10 +679,15 @@ function rope:drag(
for x,y in self:_rast( for x,y in self:_rast(
anc.x,anc.y,x,y anc.x,anc.y,x,y
) do ) do
self:_drag1(i(),x,y) local a=self:_anc(i())
if not (_point_eq(a, {x=x,y=y})) then
a.x=x
a.y=y
a.dirty=true
self:_tidy_up_gen() self:_tidy_up_gen()
end end
end end
end
function rope:_tidy_up_gen() function rope:_tidy_up_gen()
if (self:busy()) return if (self:busy()) return
@ -748,17 +753,6 @@ function rope:_tidy_up_gen()
end end
end end
function rope:_drag1(
i,x,y
)
local a=self:_anc(i)
if (_point_eq(a, {x=x,y=y})) return
a.x=x
a.y=y
a.dirty=true
end
function rope:_find_needed_anchors(i) function rope:_find_needed_anchors(i)
if (i<=0) return false if (i<=0) return false
if (#self.ancs+1<i) return false if (#self.ancs+1<i) return false
@ -799,6 +793,9 @@ function rope:_find_touched_anchors(i)
local a0=self:_anc(i-1) local a0=self:_anc(i-1)
local a2=self:_anc(i) local a2=self:_anc(i)
if (level:pcoll(a0.x,a0.y)) return false
if (level:pcoll(a2.x,a2.y)) return false
for bx,by in self:_rast(a0.x,a0.y,a2.x,a2.y) do for bx,by in self:_rast(a0.x,a0.y,a2.x,a2.y) do
local a1=level:point_anchor(bx,by) local a1=level:point_anchor(bx,by)
if a1!=nil and not _point_eq(a0,a1) and not _point_eq(a1,a2) if a1!=nil and not _point_eq(a0,a1) and not _point_eq(a1,a2)
@ -850,6 +847,11 @@ function rope:_elide_point(i)
end end
function rope:_can_move_midpoint(a0,a1_0,a1_1,a2) function rope:_can_move_midpoint(a0,a1_0,a1_1,a2)
if (level:pcoll(a0.x,a0.y)) return false
if (level:pcoll(a2.x,a2.y)) return false
if (level:pcoll(a1_0.x,a1_0.y)) return false
if (level:pcoll(a1_1.x,a1_1.y)) return false
if not self:_can_stretch(a1_0, a1_1) then if not self:_can_stretch(a1_0, a1_1) then
return false return false
end end
@ -915,6 +917,21 @@ end
function rope:_can_stretch( function rope:_can_stretch(
p1,p2 p1,p2
) )
-- faster implementation for straight lines
if p1.y\8==p2.y\8 then
local my=p2.y\8
for mx=p1.x\8,p2.x\8 do
if (level:mcoll(mx,my)) return false
end
end
if p1.x\8==p2.x\8 then
local mx=p2.x\8
for my=p1.y\8,p2.y\8 do
if (level:mcoll(mx,my)) return false
end
end
if (level:pcoll(p1.x,p1.y)) return false if (level:pcoll(p1.x,p1.y)) return false
if (level:pcoll(p2.x,p2.y)) return false if (level:pcoll(p2.x,p2.y)) return false
@ -967,34 +984,27 @@ function rope:_rast(
if (y0<y1) sy=1 if (y0<y1) sy=1
local done=false,err local done=false,err
local queue={}
if dx>dy then if dx>dy then
err=dx/2.0 err=dx/2.0
return function() return function()
if (queue==nil) return if (done) return
if (x==x1) queue=nil return x1,y1 if (x==x1) done=true return x1,y1
if #queue==0 then local oldx,oldy=x,y
add(queue,{x,y})
err-=dy err-=dy
if (err<0) y+=sy add(queue,{x,y}) err+=dx if (err<0) y+=sy err+=dx
x+=sx x+=sx
end return oldx,oldy
return unpack(deli(queue,1))
end end
else else
err=dy/2.0 err=dy/2.0
return function() return function()
if (queue==nil) return if (done) return
if (y==y1) queue=nil return x1,y1 if (y==y1) done=true return x1,y1
if #queue==0 then
add(queue,{x,y})
local oldx,oldy=x,y local oldx,oldy=x,y
err-=dx err-=dx
if (err<0) x+=sx add(queue,{x,y}) err+=dy if (err<0) x+=sx err+=dy
y+=sy y+=sy
end return oldx,oldy
return unpack(deli(queue,1))
end end
end end
end end