VoxelArea
The VoxelArea
metatable provides an OOP-like utility for dealing with LuaVoxelManip (specifically, for doing the index math).
VoxelArea.new(self, o)
Sets self.__index
to self
and self
as the metatable of o
, which can have the following fields:
MinEdge
: Minimum position of the area, inclusive. Defaults tovector.new(1, 1, 1)
ifnil
.MaxEdge
: Maximum position of the area, inclusive. Defaults tovector.new(0, 0, 0)
ifnil
.
Both positions should be vector
s of integer numbers; each component of MinEdge
should be smaller than the respective component of MaxEdge
if the VoxelArea
is to be non-empty. You can use minp, maxp = vector.sort(minp, maxp)
to achieve this.
Calculates ystride
and zstride
and stores both in o
.
Common usage:
local voxelmanip = minetest.get_voxel_manip(pos_min, pos_max)
local emin, emax = voxelmanip:read_from_map(pos_min, pos_max)
local voxelarea = VoxelArea:new{ MinEdge = emin, MaxEdge = emax }
WARNING: Always pass the actual emerged min & max positions. Do not pass the desired min & max positions.
WARNING: Never pass fractional values as min- or max edge.
TIP: You can use vector.floor
, vector.round
or vector.apply(vec, math.ceil)
to guarantee integer values.
The following methods can both be called in an imperative manner (VoxelArea.<method>(self, ...)
) or an OOP manner (recommended): self:<method>(...)
. The below examples are documented using the latter style, where area
is a valid table with VoxelArea
as the metatable.
area:getExtent()
Returns the dimensions of area
as integer vector
.
area:getVolume()
Returns the volume of area
as integer.
area:index(x, y, z)
x
, y
, z
are absolute coordinates of a node within the area. Returns an integer index to be used for data tables returned by VoxelManip objects.
WARNING: This will silently floor
the returned index instead of throwing an error. Make sure that the coordinates you pass are (1) not fractional and (2) within the area.
area:indexp(p)
Shorthand for area:index(p.x, p.y, p.z)
.
area:position(index)
Inverse to area:indexp
. Returns the absolute node position corresponding to the index
as a table with x
, y
and z
fields.
TIP: The returned table is missing the vector
metatable. If it is not performance-critical, use p = vector.new(area:position(index))
to create a copied vector with metatable.
area:contains(x, y, z)
Returns true
if all x
, y
, z
coordinates are between the respective MinEdge
and MaxEdge
coordinates, both inclusive.
area:containsp(p)
Shorthand for area:contains(p.x, p.y, p.z)
area:containsi(i)
Returns true
if i
is between 1
and the area
volume, both inclusive.
WARNING: area:containsi(area:indexp(p))
is not equivalent to area:containsp(p)
, as area:indexp
will happily produce valid indices for some out-of-area positions.
area:iter(minx, miny, minz, maxx, maxy, maxz)
Returns an iterator (a function that returns the index of the current position and advances to the next one) that iterates in XYZ order (first incrementing X until the line has been finished, then Y until the plane has been finished, then Z until the cuboid has been finished).
area:iterp(minp, maxp)
Shorthand for area:iter(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z)
.
Example:
for index in area:iterp(pos_min, pos_max) do
content_id_data[index] = ...
end
which is equivalent to (but shorter & faster than):
for z = pos_min.z, pos_max.z do
for y = pos_min.y, pos_max.y do
for x = pos_min.x, pos_max.x do
local index = area:index(x, y, z)
content_id_data[index] = ...
end
end
end
This article is originally based on an article from the minetest_docs project: VoxelArea.adoc by Lars Müller, licensed under CC-BY 4.0