mirror of
https://gitlab.com/gaelysam/mapgen_rivers.git
synced 2024-11-14 14:50:22 +01:00
e5b8f2b3b8
Also remove globally stored path for modpath and data. Basically use less global variables for better adaptation to multithreading.
130 lines
3.5 KiB
Lua
130 lines
3.5 KiB
Lua
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
|
|
|
local EvolutionModel = dofile(modpath .. '/terrainlib_lua/erosion.lua')
|
|
local twist = dofile(modpath .. '/terrainlib_lua/twist.lua')
|
|
|
|
local blocksize = tonumber(mapgen_rivers.settings:get("blocksize"))
|
|
local tectonic_speed = tonumber(mapgen_rivers.settings:get("tectonic_speed"))
|
|
|
|
local np_base = mapgen_rivers.settings:get_np_group("np_base")
|
|
np_base.spread.x = np_base.spread.x / blocksize
|
|
np_base.spread.y = np_base.spread.y / blocksize
|
|
np_base.spread.z = np_base.spread.z / blocksize
|
|
|
|
local evol_params = {
|
|
K = tonumber(mapgen_rivers.settings:get("river_erosion_coef")),
|
|
m = tonumber(mapgen_rivers.settings:get("river_erosion_power")),
|
|
d = tonumber(mapgen_rivers.settings:get("difusive_erosion")),
|
|
}
|
|
|
|
local time = tonumber(mapgen_rivers.settings:get("evol_time"))
|
|
local time_step = tonumber(mapgen_rivers.settings:get("evol_time_step"))
|
|
local niter = math.ceil(time/time_step)
|
|
time_step = time / niter
|
|
|
|
-- Setup the model
|
|
local grid = mapgen_rivers.grid
|
|
local size = grid.size
|
|
|
|
local seed = tonumber(minetest.get_mapgen_setting("seed"))
|
|
np_base.seed = (np_base.seed or 0) + seed
|
|
|
|
local nobj_base = PerlinNoiseMap(np_base, {x=size.x, y=1, z=size.y})
|
|
|
|
local dem = nobj_base:get_3d_map_flat({x=0, y=0, z=0})
|
|
dem.X = size.x
|
|
dem.Y = size.y
|
|
|
|
local model = EvolutionModel(evol_params)
|
|
model.dem = dem
|
|
local ref_dem = model:define_isostasy(dem)
|
|
|
|
local tectonic_step = tectonic_speed * time_step
|
|
collectgarbage()
|
|
|
|
-- Run the model
|
|
for i=1, niter do
|
|
minetest.log("info", "[mapgen_rivers] Iteration " .. i .. " of " .. niter)
|
|
|
|
model:diffuse(time_step)
|
|
model:flow()
|
|
model:erode(time_step)
|
|
if i < niter then
|
|
if tectonic_step ~= 0 then
|
|
nobj_base:get_3d_map_flat({x=0, y=tectonic_step*i, z=0}, ref_dem)
|
|
end
|
|
model:isostasy()
|
|
end
|
|
|
|
collectgarbage()
|
|
end
|
|
model:flow()
|
|
|
|
local mfloor = math.floor
|
|
local mmin, mmax = math.min, math.max
|
|
local offset_x, offset_y = twist(model.dirs, model.rivers, 5)
|
|
for i=1, size.x*size.y do
|
|
offset_x[i] = mmin(mmax(offset_x[i]*256, -128), 127)
|
|
offset_y[i] = mmin(mmax(offset_y[i]*256, -128), 127)
|
|
end
|
|
|
|
-- Write the results in the world directory
|
|
local datapath = minetest.get_worldpath .. "/river_data/"
|
|
minetest.mkdir(datapath)
|
|
|
|
local function write_map(filename, data, bytes)
|
|
local size = #data
|
|
local file = io.open(datapath .. filename, 'wb')
|
|
|
|
local bytelist = {}
|
|
for j=1, bytes do
|
|
bytelist[j] = 0
|
|
end
|
|
|
|
local unpk = unpack
|
|
local schar = string.char
|
|
local floor = math.floor
|
|
for i=1, size do
|
|
local n = floor(data[i])
|
|
data[i] = n
|
|
for j=bytes, 2, -1 do
|
|
bytelist[j] = n % 256
|
|
n = floor(n / 256)
|
|
end
|
|
bytelist[1] = n % 256
|
|
|
|
file:write(schar(unpk(bytelist)))
|
|
end
|
|
|
|
file:close()
|
|
end
|
|
|
|
write_map('dem', model.dem, 2)
|
|
write_map('lakes', model.lakes, 2)
|
|
write_map('dirs', model.dirs, 1)
|
|
write_map('rivers', model.rivers, 4)
|
|
write_map('offset_x', offset_x, 1)
|
|
write_map('offset_y', offset_y, 1)
|
|
local sfile = io.open(datapath .. 'size', "w")
|
|
sfile:write(size.x..'\n'..size.y)
|
|
sfile:close()
|
|
|
|
local use_interactive_loader
|
|
if minetest.settings:has("mapgen_rivers_use_interactive_loader") then
|
|
use_interactive_loader = minetest.settings:get_bool("mapgen_rivers_use_interactive_loader")
|
|
else
|
|
use_interactive_loader = not minetest.settings:get_bool("mapgen_rivers_load_all")
|
|
end
|
|
|
|
if not use_interactive_loader then
|
|
mapgen_rivers.grid = {
|
|
size = {x=size_x, y=size_y},
|
|
dem = model.dem,
|
|
lakes = model.lakes,
|
|
dirs = model.dirs,
|
|
rivers = model.rivers,
|
|
offset_x = offset_x,
|
|
offset_y = offset_y,
|
|
}
|
|
end
|