diff options
author | HybridDog <ovvv@web.de> | 2016-10-08 14:42:17 +0200 |
---|---|---|
committer | Zeno- <kde.psych@gmail.com> | 2016-10-08 22:42:17 +1000 |
commit | 9978d0796fa61eabb235d715a56ad6e5396d2e1e (patch) | |
tree | ea8e3b6ae107a83d21f0f071b9edc8c98fa56607 | |
parent | 09cefc3dfd76ac629bfc0777635fc5ac47b25ab0 (diff) | |
download | minetest-9978d0796fa61eabb235d715a56ad6e5396d2e1e.tar.gz minetest-9978d0796fa61eabb235d715a56ad6e5396d2e1e.tar.bz2 minetest-9978d0796fa61eabb235d715a56ad6e5396d2e1e.zip |
VoxelArea: faster iter function (#4490)
-rw-r--r-- | builtin/game/voxelarea.lua | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/builtin/game/voxelarea.lua b/builtin/game/voxelarea.lua index 6d926c940..724761414 100644 --- a/builtin/game/voxelarea.lua +++ b/builtin/game/voxelarea.lua @@ -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 |