mirror of
https://gitlab.com/gaelysam/mapgen_rivers.git
synced 2024-12-28 20:00:41 +01:00
More robust and faster code for grid twisting on the Lua side.
At chunkgen init, build a list of the polygons instead of calculating them for every node.
This commit is contained in:
parent
b7c6f71635
commit
56cebecb13
10
geometry.lua
10
geometry.lua
@ -18,13 +18,13 @@ local function transform_quadri(X, Y, x, y)
|
||||
local x1, x2, x3, x4 = unpack(X)
|
||||
local y1, y2, y3, y4 = unpack(Y)
|
||||
|
||||
local d12 = distance_to_segment(x1,y1,x2,y2,x,y)
|
||||
local d34 = distance_to_segment(x3,y3,x4,y4,x,y)
|
||||
local xc = d12 / (d12+d34)
|
||||
|
||||
local d23 = distance_to_segment(x2,y2,x3,y3,x,y)
|
||||
local d41 = distance_to_segment(x4,y4,x1,y1,x,y)
|
||||
local yc = d41 / (d23+d41)
|
||||
local xc = d41 / (d23+d41)
|
||||
|
||||
local d12 = distance_to_segment(x1,y1,x2,y2,x,y)
|
||||
local d34 = distance_to_segment(x3,y3,x4,y4,x,y)
|
||||
local yc = d12 / (d12+d34)
|
||||
return xc, yc
|
||||
end
|
||||
|
||||
|
126
init.lua
126
init.lua
@ -62,7 +62,7 @@ end
|
||||
|
||||
local data = {}
|
||||
|
||||
local blocksize = 20
|
||||
local blocksize = 12
|
||||
local sea_level = 1
|
||||
local min_catchment = 25
|
||||
|
||||
@ -96,72 +96,77 @@ local function generate(minp, maxp, seed)
|
||||
|
||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local ystride = a.ystride -- Tip : the ystride of a VoxelArea is the number to add to the array index to get the index of the position above. It's faster because it avoids to completely recalculate the index.
|
||||
local chulens = maxp.z - minp.z + 1
|
||||
|
||||
for x = minp.x, maxp.x do
|
||||
for z = minp.z, maxp.z do
|
||||
local xb = x/blocksize
|
||||
local zb = z/blocksize
|
||||
local xc = math.floor(xb+0.5)
|
||||
local zc = math.floor(zb+0.5)
|
||||
local polygon_number = {}
|
||||
local polygons = {}
|
||||
local xpmin, xpmax = math.max(math.floor(minp.x/blocksize - 0.5), 0), math.min(math.ceil(maxp.x/blocksize), X-2)
|
||||
local zpmin, zpmax = math.max(math.floor(minp.z/blocksize - 0.5), 0), math.min(math.ceil(maxp.z/blocksize), Z-2)
|
||||
local n = 1
|
||||
local n_filled = 0
|
||||
for xp = xpmin, xpmax do
|
||||
for zp=zpmin, zpmax do
|
||||
local iA = index(xp, zp)
|
||||
local iB = index(xp+1, zp)
|
||||
local iC = index(xp+1, zp+1)
|
||||
local iD = index(xp, zp+1)
|
||||
local poly_x = {offset_x[iA]+xp, offset_x[iB]+xp+1, offset_x[iC]+xp+1, offset_x[iD]+xp}
|
||||
local poly_z = {offset_z[iA]+zp, offset_z[iB]+zp, offset_z[iC]+zp+1, offset_z[iD]+zp+1}
|
||||
|
||||
local x0, z0
|
||||
if xc >= 0 and zc >= 0 and xc < X and zc < Z then
|
||||
local xoff, zoff = get_point_location(xc, zc)
|
||||
local north, east, south, west
|
||||
if xc > 0 then
|
||||
local x1off, z1off = get_point_location(xc-1, zc)
|
||||
west = geometry.area({xoff, x1off, xb}, {zoff, z1off, zb}) <= 0
|
||||
else
|
||||
west = zb > zoff
|
||||
end
|
||||
if zc > 0 then
|
||||
local x2off, z2off = get_point_location(xc, zc-1)
|
||||
north = geometry.area({xoff, x2off, xb}, {zoff, z2off, zb}) <= 0
|
||||
else
|
||||
north = xb > xoff
|
||||
end
|
||||
if xc < X-1 then
|
||||
local x3off, z3off = get_point_location(xc+1, zc)
|
||||
east = geometry.area({xoff, x3off, xb}, {zoff, z3off, zb}) <= 0
|
||||
else
|
||||
east = zb < zoff
|
||||
end
|
||||
if zc < Z-1 then
|
||||
local x4off, z4off = get_point_location(xc, zc+1)
|
||||
south = geometry.area({xoff, x4off, xb}, {zoff, z4off, zb}) <= 0
|
||||
else
|
||||
south = xb < xoff
|
||||
end
|
||||
local bounds = {}
|
||||
local xmin = math.max(math.floor(blocksize*math.min(unpack(poly_x)))+1, minp.x)
|
||||
local xmax = math.min(math.floor(blocksize*math.max(unpack(poly_x))), maxp.x)
|
||||
for x=xmin, xmax do
|
||||
bounds[x] = {}
|
||||
end
|
||||
|
||||
if west and not north then
|
||||
x0, z0 = xc-1, zc-1
|
||||
elseif north and not east then
|
||||
x0, z0 = xc, zc-1
|
||||
elseif east and not south then
|
||||
x0, z0 = xc, zc
|
||||
elseif south and not west then
|
||||
x0, z0 = xc-1, zc
|
||||
else
|
||||
x0, z0 = xc, zc
|
||||
local i1 = 4
|
||||
for i2=1, 4 do -- Loop on 4 edges
|
||||
local x1, x2 = poly_x[i1], poly_x[i2]
|
||||
local lxmin = math.floor(blocksize*math.min(x1, x2))+1
|
||||
local lxmax = math.floor(blocksize*math.max(x1, x2))
|
||||
if lxmin <= lxmax then
|
||||
local z1, z2 = poly_z[i1], poly_z[i2]
|
||||
local a = (z1-z2) / (x1-x2)
|
||||
local b = blocksize*(z1 - a*x1)
|
||||
for x=math.max(lxmin, minp.x), math.min(lxmax, maxp.x) do
|
||||
table.insert(bounds[x], a*x+b)
|
||||
end
|
||||
end
|
||||
i1 = i2
|
||||
end
|
||||
for x=xmin, xmax do
|
||||
local xlist = bounds[x]
|
||||
table.sort(xlist)
|
||||
local c = math.floor(#xlist/2)
|
||||
for l=1, c do
|
||||
local zmin = math.max(math.floor(xlist[l*2-1])+1, minp.z)
|
||||
local zmax = math.min(math.floor(xlist[l*2]), maxp.z)
|
||||
local i = (x-minp.x) * chulens + (zmin-minp.z) + 1
|
||||
for z=zmin, zmax do
|
||||
polygon_number[i] = n
|
||||
i = i + 1
|
||||
n_filled = n_filled + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if x0 and z0 and x0 >= 0 and x0 < X-1 and z0 >= 0 and z0 < Z-1 then
|
||||
local x1 = x0+1
|
||||
local z1 = z0+1
|
||||
local xf, zf
|
||||
do
|
||||
local xA, zA = get_point_location(x0, z0)
|
||||
local xB, zB = get_point_location(x0, z1)
|
||||
local xC, zC = get_point_location(x1, z1)
|
||||
local xD, zD = get_point_location(x1, z0)
|
||||
xf, zf = geometry.transform_quadri({xA, xB, xC, xD}, {zA, zB, zC, zD}, xb, zb)
|
||||
end
|
||||
polygons[n] = {x=poly_x, z=poly_z, i={iA, iB, iC, iD}}
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
|
||||
local i00 = index(x0,z0)
|
||||
local i01 = index(x1,z0)
|
||||
local i10 = index(x0,z1)
|
||||
local i11 = index(x1,z1)
|
||||
local i = 1
|
||||
for x = minp.x, maxp.x do
|
||||
for z = minp.z, maxp.z do
|
||||
local npoly = polygon_number[i]
|
||||
if npoly then
|
||||
local poly = polygons[npoly]
|
||||
local xf, zf = geometry.transform_quadri(poly.x, poly.z, x/blocksize, z/blocksize)
|
||||
if xf < 0 or xf > 1 or zf < 0 or zf > 1 then
|
||||
print(xf, zf, x, z)
|
||||
end
|
||||
local i00, i01, i11, i10 = unpack(poly.i)
|
||||
|
||||
local terrain_height = math.floor(interp(
|
||||
dem[i00],
|
||||
@ -230,6 +235,7 @@ local function generate(minp, maxp, seed)
|
||||
end
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user