VoxelArea: faster iter function (#4490)
authorHybridDog <ovvv@web.de>
Sat, 8 Oct 2016 12:42:17 +0000 (14:42 +0200)
committerZeno- <kde.psych@gmail.com>
Sat, 8 Oct 2016 12:42:17 +0000 (22:42 +1000)
builtin/game/voxelarea.lua

index 6d926c9407925e5d0baae27c872b3aa756ff504d..7247614147427debb379cf340b014770a202a14a 100644 (file)
@@ -50,7 +50,7 @@ end
 function VoxelArea:position(i)
        local p = {}
        local MinEdge = self.MinEdge
+
        i = i - 1
 
        p.z = math.floor(i / self.zstride) + MinEdge.z
@@ -84,23 +84,46 @@ end
 
 function VoxelArea:iter(minx, miny, minz, maxx, maxy, maxz)
        local i = self:index(minx, miny, minz) - 1
-       local last = self:index(maxx, maxy, maxz)
-       local ystride = self.ystride
-       local zstride = self.zstride
-       local yoff = (last+1) % ystride
-       local zoff = (last+1) % zstride
-       local ystridediff = (i - last) % ystride
-       local zstridediff = (i - last) % zstride
+       local xrange = maxx - minx + 1
+       local nextaction = i + 1 + xrange
+
+       local y = 0
+       local yrange = maxy - miny + 1
+       local yreqstride = self.ystride - xrange
+
+       local z = 0
+       local zrange = maxz - minz + 1
+       local multistride = self.zstride - ((yrange - 1) * self.ystride + xrange)
+
        return function()
+               -- continue i until it needs to jump
                i = i + 1
-               if i % zstride == zoff then
-                       i = i + zstridediff
-               elseif i % ystride == yoff then
-                       i = i + ystridediff
+               if i ~= nextaction then
+                       return i
                end
-               if i <= last then
+
+               -- continue y until maxy is exceeded
+               y = y + 1
+               if y ~= yrange then
+                       -- set i to index(minx, miny + y, minz + z) - 1
+                       i = i + yreqstride
+                       nextaction = i + xrange
                        return i
                end
+
+               -- continue z until maxz is exceeded
+               z = z + 1
+               if z == zrange then
+                       -- cuboid finished, return nil
+                       return
+               end
+
+               -- set i to index(minx, miny, minz + z) - 1
+               i = i + multistride
+
+               y = 0
+               nextaction = i + xrange
+               return i
        end
 end