end
function VoxelArea:getExtent()
+ local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
return {
- x = self.MaxEdge.x - self.MinEdge.x + 1,
- y = self.MaxEdge.y - self.MinEdge.y + 1,
- z = self.MaxEdge.z - self.MinEdge.z + 1,
+ x = MaxEdge.x - MinEdge.x + 1,
+ y = MaxEdge.y - MinEdge.y + 1,
+ z = MaxEdge.z - MinEdge.z + 1,
}
end
end
function VoxelArea:index(x, y, z)
- local i = (z - self.MinEdge.z) * self.zstride +
- (y - self.MinEdge.y) * self.ystride +
- (x - self.MinEdge.x) + 1
+ local MinEdge = self.MinEdge
+ local i = (z - MinEdge.z) * self.zstride +
+ (y - MinEdge.y) * self.ystride +
+ (x - MinEdge.x) + 1
return math.floor(i)
end
function VoxelArea:indexp(p)
- local i = (p.z - self.MinEdge.z) * self.zstride +
- (p.y - self.MinEdge.y) * self.ystride +
- (p.x - self.MinEdge.x) + 1
+ local MinEdge = self.MinEdge
+ local i = (p.z - MinEdge.z) * self.zstride +
+ (p.y - MinEdge.y) * self.ystride +
+ (p.x - MinEdge.x) + 1
return math.floor(i)
end
function VoxelArea:position(i)
local p = {}
-
+ local MinEdge = self.MinEdge
+
i = i - 1
- p.z = math.floor(i / self.zstride) + self.MinEdge.z
+ p.z = math.floor(i / self.zstride) + MinEdge.z
i = i % self.zstride
- p.y = math.floor(i / self.ystride) + self.MinEdge.y
+ p.y = math.floor(i / self.ystride) + MinEdge.y
i = i % self.ystride
- p.x = math.floor(i) + self.MinEdge.x
+ p.x = math.floor(i) + MinEdge.x
return p
end
function VoxelArea:contains(x, y, z)
- return (x >= self.MinEdge.x) and (x <= self.MaxEdge.x) and
- (y >= self.MinEdge.y) and (y <= self.MaxEdge.y) and
- (z >= self.MinEdge.z) and (z <= self.MaxEdge.z)
+ local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
+ return (x >= MinEdge.x) and (x <= MaxEdge.x) and
+ (y >= MinEdge.y) and (y <= MaxEdge.y) and
+ (z >= MinEdge.z) and (z <= MaxEdge.z)
end
function VoxelArea:containsp(p)
- return (p.x >= self.MinEdge.x) and (p.x <= self.MaxEdge.x) and
- (p.y >= self.MinEdge.y) and (p.y <= self.MaxEdge.y) and
- (p.z >= self.MinEdge.z) and (p.z <= self.MaxEdge.z)
+ local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
+ return (p.x >= MinEdge.x) and (p.x <= MaxEdge.x) and
+ (p.y >= MinEdge.y) and (p.y <= MaxEdge.y) and
+ (p.z >= MinEdge.z) and (p.z <= MaxEdge.z)
end
function VoxelArea:containsi(i)
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