Rewritten part of code to calculate river depth

Fixes bathymetry problems on turns or confluences, as well as abrupt riverbanks.
This commit is contained in:
Gaël de Sailly 2020-04-26 22:19:05 +02:00
parent cd4b517585
commit b429b302e1
2 changed files with 52 additions and 55 deletions

View File

@ -45,55 +45,63 @@ local function generate(minp, maxp, seed)
local xf, zf = transform_quadri(poly.x, poly.z, x/blocksize, z/blocksize) local xf, zf = transform_quadri(poly.x, poly.z, x/blocksize, z/blocksize)
local i00, i01, i11, i10 = unpack(poly.i) local i00, i01, i11, i10 = unpack(poly.i)
-- Test the 4 edges to see whether we are in a river or not -- Load river width on 4 edges and corners
local is_river = false
local depth_factor = 0
local r_west, r_north, r_east, r_south = unpack(poly.rivers) local r_west, r_north, r_east, r_south = unpack(poly.rivers)
if xf > r_east then local c_NW, c_NE, c_SE, c_SW = unpack(poly.river_corners)
is_river = true
depth_factor = xf-r_east
xf = 1
elseif xf < r_west then
is_river = true
depth_factor = r_west-xf
xf = 0
end
if zf > r_south then
is_river = true
depth_factor = zf-r_south
zf = 1
elseif zf < r_north then
is_river = true
depth_factor = r_north-zf
zf = 0
end
if not is_river then -- Test corners also -- Calculate the depth factor for each edge and corner.
local c_NW, c_NE, c_SE, c_SW = unpack(poly.river_corners) -- Depth factor:
if xf+zf < c_NW then -- < 0: outside river
is_river = true -- = 0: on riverbank
depth_factor = c_NW-xf-zf -- > 0: inside river
xf, zf = 0, 0 local depth_factors = {
elseif 1-xf+zf < c_NE then r_west - xf,
is_river = true r_north - zf,
depth_factor = c_NE-1+xf-zf xf - r_east,
xf, zf = 1, 0 zf - r_south,
elseif 2-xf-zf < c_SE then c_NW-xf-zf,
is_river = true c_NE+xf-zf-1,
depth_factor = c_SE-2+xf+zf c_SE+xf+zf-2,
xf, zf = 1, 1 c_SW-xf+zf-1,
elseif xf+1-zf < c_SW then }
is_river = true
depth_factor = c_SW-xf-1+zf -- Find the maximal depth factor and determine to which river it belongs
xf, zf = 0, 1 local depth_factor_max = 0
local imax = 0
for i=1, 8 do
if depth_factors[i] >= depth_factor_max then
depth_factor_max = depth_factors[i]
imax = i
end end
end end
if not is_river then -- Redefine indicesto have 0/1 on the riverbanks (avoids ugly edge cuts, at least for small rivers) -- Transform the coordinates to have xf and zf = 0 or 1 in rivers (to avoid rivers having lateral slope and to accomodate the surrounding smoothly)
xf = (xf-r_west) / (r_east-r_west) if imax == 0 then
zf = (zf-r_north) / (r_south-r_north) local x0 = math.max(r_west, c_NW-zf, c_SW+zf-1)
local x1 = math.min(r_east, 1-c_NE+zf, 2-c_SE-zf)
local z0 = math.max(r_north, c_NW-xf, c_NE+xf-1)
local z1 = math.min(r_south, 1-c_SW+xf, 2-c_SE-xf)
xf = (xf-x0) / (x1-x0)
zf = (zf-z0) / (z1-z0)
elseif imax == 1 then
xf = 0
elseif imax == 2 then
zf = 0
elseif imax == 3 then
xf = 1
elseif imax == 4 then
zf = 1
elseif imax == 5 then
xf, zf = 0, 0
elseif imax == 6 then
xf, zf = 1, 0
elseif imax == 7 then
xf, zf = 1, 1
elseif imax == 8 then
xf, zf = 0, 1
end end
-- Determine elevation by interpolation
local vdem = poly.dem local vdem = poly.dem
local terrain_height = math.floor(0.5+interp( local terrain_height = math.floor(0.5+interp(
vdem[1], vdem[1],
@ -104,8 +112,8 @@ local function generate(minp, maxp, seed)
)) ))
local lake_height = math.max(math.floor(poly.lake), terrain_height) local lake_height = math.max(math.floor(poly.lake), terrain_height)
if is_river then if imax > 0 and depth_factor_max > 0 then
terrain_height = math.min(math.max(lake_height, sea_level) - math.floor(1+depth_factor*riverbed_slope), terrain_height) terrain_height = math.min(math.max(lake_height, sea_level) - math.floor(1+depth_factor_max*riverbed_slope), terrain_height)
end end
local is_lake = lake_height > terrain_height local is_lake = lake_height > terrain_height
local ivm = a:index(x, minp.y-1, z) local ivm = a:index(x, minp.y-1, z)

View File

@ -153,17 +153,6 @@ local function make_polygons(minp, maxp)
local river_east = 1 - (dirB==1 and riverB or 0) - (dirC==3 and riverC or 0) local river_east = 1 - (dirB==1 and riverB or 0) - (dirC==3 and riverC or 0)
local river_south = 1 - (dirD==2 and riverD or 0) - (dirC==4 and riverC or 0) local river_south = 1 - (dirD==2 and riverD or 0) - (dirC==4 and riverC or 0)
-- Only if opposite rivers overlap (should be rare)
if river_west > river_east then
local mean = (river_west + river_east) / 2
river_west = mean
river_east = mean
end
if river_north > river_south then
local mean = (river_north + river_south) / 2
river_north = mean
river_south = mean
end
polygon.rivers = {river_west, river_north, river_east, river_south} polygon.rivers = {river_west, river_north, river_east, river_south}
end end
end end