]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/game/voxelarea.lua
minetest.dig_node: Remove node
[dragonfireclient.git] / builtin / game / voxelarea.lua
1 VoxelArea = {
2         MinEdge = vector.new(1, 1, 1),
3         MaxEdge = vector.new(0, 0, 0),
4         ystride = 0,
5         zstride = 0,
6 }
7
8 function VoxelArea:new(o)
9         o = o or {}
10         setmetatable(o, self)
11         self.__index = self
12
13         local e = o:getExtent()
14         o.ystride = e.x
15         o.zstride = e.x * e.y
16
17         return o
18 end
19
20 function VoxelArea:getExtent()
21         local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
22         return vector.new(
23                 MaxEdge.x - MinEdge.x + 1,
24                 MaxEdge.y - MinEdge.y + 1,
25                 MaxEdge.z - MinEdge.z + 1
26         )
27 end
28
29 function VoxelArea:getVolume()
30         local e = self:getExtent()
31         return e.x * e.y * e.z
32 end
33
34 function VoxelArea:index(x, y, z)
35         local MinEdge = self.MinEdge
36         local i = (z - MinEdge.z) * self.zstride +
37                           (y - MinEdge.y) * self.ystride +
38                           (x - MinEdge.x) + 1
39         return math.floor(i)
40 end
41
42 function VoxelArea:indexp(p)
43         local MinEdge = self.MinEdge
44         local i = (p.z - MinEdge.z) * self.zstride +
45                           (p.y - MinEdge.y) * self.ystride +
46                           (p.x - MinEdge.x) + 1
47         return math.floor(i)
48 end
49
50 function VoxelArea:position(i)
51         local p = {}
52         local MinEdge = self.MinEdge
53
54         i = i - 1
55
56         p.z = math.floor(i / self.zstride) + MinEdge.z
57         i = i % self.zstride
58
59         p.y = math.floor(i / self.ystride) + MinEdge.y
60         i = i % self.ystride
61
62         p.x = math.floor(i) + MinEdge.x
63
64         return p
65 end
66
67 function VoxelArea:contains(x, y, z)
68         local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
69         return (x >= MinEdge.x) and (x <= MaxEdge.x) and
70                    (y >= MinEdge.y) and (y <= MaxEdge.y) and
71                    (z >= MinEdge.z) and (z <= MaxEdge.z)
72 end
73
74 function VoxelArea:containsp(p)
75         local MaxEdge, MinEdge = self.MaxEdge, self.MinEdge
76         return (p.x >= MinEdge.x) and (p.x <= MaxEdge.x) and
77                    (p.y >= MinEdge.y) and (p.y <= MaxEdge.y) and
78                    (p.z >= MinEdge.z) and (p.z <= MaxEdge.z)
79 end
80
81 function VoxelArea:containsi(i)
82         return (i >= 1) and (i <= self:getVolume())
83 end
84
85 function VoxelArea:iter(minx, miny, minz, maxx, maxy, maxz)
86         local i = self:index(minx, miny, minz) - 1
87         local xrange = maxx - minx + 1
88         local nextaction = i + 1 + xrange
89
90         local y = 0
91         local yrange = maxy - miny + 1
92         local yreqstride = self.ystride - xrange
93
94         local z = 0
95         local zrange = maxz - minz + 1
96         local multistride = self.zstride - ((yrange - 1) * self.ystride + xrange)
97
98         return function()
99                 -- continue i until it needs to jump
100                 i = i + 1
101                 if i ~= nextaction then
102                         return i
103                 end
104
105                 -- continue y until maxy is exceeded
106                 y = y + 1
107                 if y ~= yrange then
108                         -- set i to index(minx, miny + y, minz + z) - 1
109                         i = i + yreqstride
110                         nextaction = i + xrange
111                         return i
112                 end
113
114                 -- continue z until maxz is exceeded
115                 z = z + 1
116                 if z == zrange then
117                         -- cuboid finished, return nil
118                         return
119                 end
120
121                 -- set i to index(minx, miny, minz + z) - 1
122                 i = i + multistride
123
124                 y = 0
125                 nextaction = i + xrange
126                 return i
127         end
128 end
129
130 function VoxelArea:iterp(minp, maxp)
131         return self:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z)
132 end