initial commit
This commit is contained in:
parent
2b46951bcc
commit
5e8156c929
0
depends.txt
Normal file
0
depends.txt
Normal file
129
init.lua
Normal file
129
init.lua
Normal 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
75
voxelarea_iterator.lua
Normal 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
45
voxeldata.lua
Normal 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
|
Loading…
x
Reference in New Issue
Block a user