VoxelArea

Notice

This site is a work in progress under active development! Content and URLs may change quickly without notice. Refer to the About page for information on the mission statement, roadmap, and how to contribute.

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 to vector.new(1, 1, 1) if nil.
  • MaxEdge: Maximum position of the area, inclusive. Defaults to vector.new(0, 0, 0) if nil.

Both positions should be vectors 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 = core.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