2021-06-03 23:30:04 +02:00
local EvolutionModel = dofile ( mapgen_rivers.modpath .. ' /terrainlib_lua/erosion.lua ' )
local twist = dofile ( mapgen_rivers.modpath .. ' /terrainlib_lua/twist.lua ' )
2021-06-03 20:08:57 +02:00
2021-06-06 13:25:43 +02:00
local blocksize = mapgen_rivers.settings . blocksize
local tectonic_speed = mapgen_rivers.settings . tectonic_speed
2021-06-03 20:08:57 +02:00
2021-06-06 13:25:43 +02:00
local np_base = table.copy ( mapgen_rivers.noise_params . base )
2022-01-18 14:25:37 +01:00
np_base.spread = vector.divide ( np_base.spread , blocksize )
2021-06-03 20:08:57 +02:00
2021-06-06 13:25:43 +02:00
local evol_params = mapgen_rivers.settings . evol_params
local time = mapgen_rivers.settings . evol_time
local time_step = mapgen_rivers.settings . evol_time_step
2021-06-03 20:08:57 +02:00
local niter = math.ceil ( time / time_step )
time_step = time / niter
2022-01-03 15:45:27 +01:00
local use_margin = mapgen_rivers.settings . margin
local margin_width = mapgen_rivers.settings . margin_width / blocksize
local margin_elev = mapgen_rivers.settings . margin_elev
2022-01-02 15:13:12 +01:00
local function margin ( dem , width , elev )
local X , Y = dem.X , dem.Y
for i = 1 , width do
local c1 = ( ( i - 1 ) / width ) ^ 0.5
local c2 = ( 1 - c1 ) * elev
local index = ( i - 1 ) * X + 1
for x = 1 , X do
dem [ index ] = dem [ index ] * c1 + c2
index = index + 1
end
index = i
for y = 1 , Y do
dem [ index ] = dem [ index ] * c1 + c2
index = index + X
end
index = X * ( Y - i ) + 1
for x = 1 , X do
dem [ index ] = dem [ index ] * c1 + c2
index = index + 1
end
index = X - i + 1
for y = 1 , Y do
dem [ index ] = dem [ index ] * c1 + c2
index = index + X
end
end
end
2021-06-26 13:13:41 +02:00
local function pregenerate ( keep_loaded )
2021-06-05 11:24:28 +02:00
local grid = mapgen_rivers.grid
local size = grid.size
2022-01-18 17:58:51 +01:00
if size.x * size.y > 4e6 then
minetest.log ( " warning " , " [mapgen_rivers] You are going to generate a very large grid (>4M nodes). If you experience problems, you should increase blocksize or reduce map size. " )
end
2021-06-03 23:30:04 +02:00
local seed = tonumber ( minetest.get_mapgen_setting ( " seed " ) )
np_base.seed = ( np_base.seed or 0 ) + seed
2021-06-03 20:08:57 +02:00
2021-06-03 23:30:04 +02:00
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 } )
2021-06-03 20:08:57 +02:00
dem.X = size.x
dem.Y = size.y
2022-01-02 15:13:12 +01:00
if use_margin then
margin ( dem , margin_width , margin_elev )
end
2021-06-06 13:25:43 +02:00
local model = EvolutionModel ( evol_params )
2021-06-03 20:08:57 +02:00
model.dem = dem
local ref_dem = model : define_isostasy ( dem )
2021-06-06 13:25:43 +02:00
local tectonic_step = tectonic_speed * time_step
2021-07-26 22:28:45 +02:00
collectgarbage ( )
2021-06-03 20:08:57 +02:00
for i = 1 , niter do
2022-01-03 16:22:55 +01:00
minetest.log ( " info " , " [mapgen_rivers] Iteration " .. i .. " of " .. niter )
2021-06-03 20:08:57 +02:00
model : diffuse ( time_step )
model : flow ( )
model : erode ( time_step )
2021-06-06 13:25:43 +02:00
if i < niter then
2021-07-24 18:55:13 +02:00
if tectonic_step ~= 0 then
nobj_base : get_3d_map_flat ( { x = 0 , y = tectonic_step * i , z = 0 } , ref_dem )
2022-01-02 15:13:12 +01:00
if use_margin then
margin ( ref_dem , margin_width , margin_elev )
end
2021-07-24 18:55:13 +02:00
end
2021-06-06 13:25:43 +02:00
model : isostasy ( )
end
2021-07-26 22:28:45 +02:00
collectgarbage ( )
2021-06-03 20:08:57 +02:00
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 )
2021-06-03 23:30:04 +02:00
for i = 1 , size.x * size.y do
2021-06-03 20:08:57 +02:00
offset_x [ i ] = mmin ( mmax ( offset_x [ i ] * 256 , - 128 ) , 127 )
offset_y [ i ] = mmin ( mmax ( offset_y [ i ] * 256 , - 128 ) , 127 )
end
mapgen_rivers.write_map ( ' dem ' , model.dem , 2 )
mapgen_rivers.write_map ( ' lakes ' , model.lakes , 2 )
mapgen_rivers.write_map ( ' dirs ' , model.dirs , 1 )
mapgen_rivers.write_map ( ' rivers ' , model.rivers , 4 )
mapgen_rivers.write_map ( ' offset_x ' , offset_x , 1 )
mapgen_rivers.write_map ( ' offset_y ' , offset_y , 1 )
local sfile = io.open ( mapgen_rivers.world_data_path .. ' size ' , " w " )
2021-06-03 23:30:04 +02:00
sfile : write ( size.x .. ' \n ' .. size.y )
2021-06-03 20:08:57 +02:00
sfile : close ( )
2021-06-05 11:24:28 +02:00
2021-06-26 13:13:41 +02:00
if keep_loaded then
2021-07-24 18:55:13 +02:00
grid.dem = model.dem
grid.lakes = model.lakes
grid.dirs = model.dirs
grid.rivers = model.rivers
grid.offset_x = offset_x
grid.offset_y = offset_y
2021-06-26 13:13:41 +02:00
end
2021-07-26 22:28:45 +02:00
collectgarbage ( )
2021-06-03 20:08:57 +02:00
end
2021-06-23 19:53:56 +02:00
return pregenerate