initial commit

This commit is contained in:
FaceDeer 2018-11-14 23:40:23 -07:00
parent 2b46951bcc
commit 5e8156c929
4 changed files with 249 additions and 0 deletions

0
depends.txt Normal file
View File

129
init.lua Normal file
View File

@ -0,0 +1,129 @@
mapgen_helper = {}
mapgen_helper.mapgen_seed = tonumber(minetest.get_mapgen_setting("seed"))
local MP = minetest.get_modpath(minetest.get_current_modname())
dofile(MP.."/voxelarea_iterator.lua")
dofile(MP.."/voxeldata.lua")
-- Returns a consistent list of random points within a volume.
-- Each call to this method will give the same set of points if the same parameters are provided
mapgen_helper.get_random_points = function(minp, maxp, min_output_size, max_output_size)
local next_seed = math.random(1, 1000000000)
math.randomseed(minp.x + minp.y*2^4 + minp.z*2^8 + mapgen_helper.mapgen_seed)
local count = math.random(min_output_size, max_output_size)
local result = {}
while count > 0 do
local point = {}
point.x = math.random(minp.x, maxp.x)
point.x = math.random(minp.y, maxp.y)
point.z = math.random(minp.z, maxp.z)
table.insert(result, point)
count = count - 1
end
math.randomseed(next_seed)
return result
end
-- Given a position and a grid scale, returns the minp corners of the four grids that the player is closest to.
-- For example, if we have a grid scale of 6 and the parameter position is at "*", the four points marked "R" would be returned.
-- |-----|-----|-----| |-----|-----|-----| |-----|-----|-----|
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- |-----|-----|-----| |-----|-----|-----| |-----R-----R-----|
-- | | | | | | | | | | | |
-- | | | | | | | | | | *| |
-- | | | | | | | | | | | |
-- | | * | | | | *| | | | | |
-- | | | | | | | | | | | |
-- R-----R-----|-----| |-----R-----R-----| |-----R-----R-----|
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- | | | | | | | | | | | |
-- R-----R-----|-----| |-----R-----R-----| |-----|-----|-----|
-- In this way you can be sure you aren't near an area you haven't tested.
mapgen_helper.get_nearest_grids = function(pos_xz, gridscale)
local half_scale = gridscale / 2
local grid_cell = {x = math.floor(pos_xz.x / gridscale) * gridscale, z = math.floor(pos_xz.z / gridscale) * gridscale}
local pos_internal = {x = pos_xz.x % gridscale, z = pos_xz.z % gridscale}
local result = {grid_cell}
local shift_x = gridscale
local shift_z = gridscale
if (pos_internal.x < half_scale) then
shift_x = -gridscale
end
if (pos_internal.z < half_scale) then
shift_z = -gridscale
end
table.insert(result, {x = grid_cell.x + shift_x, z = grid_cell.z + shift_z})
table.insert(result, {x = grid_cell.x + shift_x, z = grid_cell.z})
table.insert(result, {x = grid_cell.x, z = grid_cell.z + shift_z})
return result
end
-- |---|---|---|
-- | | | |
-- | | | |
-- R---R---R---|
-- | | | |
-- | | *| |
-- R---R---R---|
-- | | | |
-- | | | |
-- R---R---R---|
mapgen_helper.get_adjacent_grids = function(pos_xz, gridscale)
local grid_cell = {x = math.floor(pos_xz.x / gridscale) * gridscale, z = math.floor(pos_xz.z / gridscale) * gridscale}
local result = {grid_cell}
table.insert(result, {x = grid_cell.x + gridscale, z = grid_cell.y + gridscale})
table.insert(result, {x = grid_cell.x + gridscale, z = grid_cell.y})
table.insert(result, {x = grid_cell.x, z = grid_cell.y + gridscale})
table.insert(result, {x = grid_cell.x - gridscale, z = grid_cell.y - gridscale})
table.insert(result, {x = grid_cell.x - gridscale, z = grid_cell.y})
table.insert(result, {x = grid_cell.x, z = grid_cell.y - gridscale})
return result
end
-- A cheap nearness test, using Manhattan distance.
mapgen_helper.is_within_distance = function(pos1, pos2, distance)
return math.abs(pos1.x-pos2.x) <= distance and
math.abs(pos1.y-pos2.y) <= distance and
math.abs(pos1.z-pos2.z) <= distance
end
-- Finds an intersection between two axis-aligned bounding boxes (AABB)s, or nil if there's no overlap
mapgen_helper.intersect = function(minpos1, maxpos1, minpos2, maxpos2)
--checking x and z first since they're more likely to fail to overlap
if minpos1.x <= maxpos2.x and maxpos1.x >= minpos2.x and
minpos1.z <= maxpos2.z and maxpos1.z >= minpos2.z and
minpos1.y <= maxpos2.y and maxpos1.y >= minpos2.y then
return {
x = math.max(minpos1.x, minpos2.x),
y = math.max(minpos1.y, minpos2.y),
z = math.max(minpos1.z, minpos2.z)
},
{
x = math.min(maxpos1.x, maxpos2.x),
y = math.min(maxpos1.y, maxpos2.y),
z = math.min(maxpos1.z, maxpos2.z)
}
end
return nil, nil
end

75
voxelarea_iterator.lua Normal file
View File

@ -0,0 +1,75 @@
-- These functions are a minor modification of the voxel area iterator defined in the built in voxelarea.lua lua code.
-- As such, this file is separately licened under the LGPL as follows:
-- License of Minetest source code
-------------------------------
--Minetest
--Copyright (C) 2010-2018 celeron55, Perttu Ahola <celeron55@gmail.com>
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--GNU Lesser General Public License for more details.
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
function VoxelArea:iter_xyz(minx, miny, minz, maxx, maxy, maxz)
local i = self:index(minx, miny, minz) - 1
local x = minx - 1 -- subtracting one because x gets incremented before it gets returned the first time.
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
x = x + 1
if i ~= nextaction then
return i, x, y+miny, z+minz
end
-- continue y until maxy is exceeded
y = y + 1
x = minx -- new line
if y ~= yrange then
-- set i to index(minx, miny + y, minz + z) - 1
i = i + yreqstride
nextaction = i + xrange
return i, x, y+miny, z+minz
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, x, y+miny, z+minz
end
end
function VoxelArea:iterp_xyz(minp, maxp)
return self:iter_xyz(minp.x, minp.y, minp.z, maxp.x, maxp.y, maxp.z)
end

45
voxeldata.lua Normal file
View File

@ -0,0 +1,45 @@
local map_data = {}
local perlin_buffers = {}
mapgen_helper.mapgen_voxelmanip = function()
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
vm:get_data(map_data)
return vm, map_data, VoxelArea:new{MinEdge=emin, MaxEdge=emax}
end
mapgen_helper.perlin3d = function(name, minp, maxp, perlin_params)
local minx = minp.x
local minz = minp.z
local sidelen = maxp.x - minp.x + 1 --length of a mapblock
local chunk_lengths = {x = sidelen, y = sidelen, z = sidelen} --table of chunk edges
perlin_buffers[name] = perlin_buffers[name] or {}
perlin_buffers[name].nvals_perlin_buffer = perlin_buffers[name].nvals_perlin_buffer or {}
perlin_buffers[name].nobj_perlin = perlin_buffers[name].nobj_perlin or minetest.get_perlin_map(perlin_params, chunk_lengths)
local nvals_perlin = perlin_buffers[name].nobj_perlin:get_3d_map_flat(minp, perlin_buffers[name].nvals_perlin_buffer)
return nvals_perlin, VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
end
mapgen_helper.perlin2d = function(name, minp, maxp, perlin_params)
local minx = minp.x
local minz = minp.z
local sidelen = maxp.x - minp.x + 1 --length of a mapblock
local chunk_lengths = {x = sidelen, y = sidelen, z = sidelen} --table of chunk edges
perlin_buffers[name] = perlin_buffers[name] or {}
perlin_buffers[name].nvals_perlin_buffer = perlin_buffers[name].nvals_perlin_buffer or {}
perlin_buffers[name].nobj_perlin = perlin_buffers[name].nobj_perlin or minetest.get_perlin_map(perlin_params, chunk_lengths)
local nvals_perlin = perlin_buffers[name].nobj_perlin:get_2d_map_flat({x=minp.x, y=minp.z}, perlin_buffers[name].nvals_perlin_buffer)
return nvals_perlin
end
-- TODO: need a nice iterator for this kind of thing, check whether VoxelArea's can do this or if something custom will be needed
mapgen_helper.index2d = function(minp, maxp, x, z)
return x - minp.x +
(maxp.x - minp.x + 1) -- sidelen
*(z - minp.z)
+ 1
end