Implemented new function in layergen to combat the issue of different sources for material, when these neighbor on different edges. A fade in each direction for the non-precedence material is now implemented, hopefully solving this issue. To be tested by MarStr.

This commit is contained in:
Marcus Str 2024-09-28 21:06:40 +02:00
parent 1fba4590c3
commit d5c3c5ecad
6 changed files with 170 additions and 1 deletions

View File

@ -84,3 +84,5 @@ def findAirportTiles(av, ah):
def in_circle(center_x, center_y, radius, x, y): def in_circle(center_x, center_y, radius, x, y):
square_dist = (center_x - x) ** 2 + (center_y - y) ** 2 square_dist = (center_x - x) ** 2 + (center_y - y) ** 2
return square_dist <= radius ** 2 return square_dist <= radius ** 2

View File

@ -441,6 +441,29 @@ class mstr_layergen:
layer_border = self.genborder(osm_edge, "landuse", "meadow") layer_border = self.genborder(osm_edge, "landuse", "meadow")
layer_comp.alpha_composite(layer_border) layer_comp.alpha_composite(layer_border)
# Here we want to make sure that the generated image fits well with others, so
# let's do that.
mstr_msg("layergen", "Generating adjacent fades")
self.generate_adjacent_fades()
# Determine if there are any fades, and if so, fade those in first before we save the layer
fade_fn = mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value
if os.path.isfile(fade_fn + "_fade_top.png") == True:
fade = Image.open(fade_fn + "_fade_top.png")
layer_comp.alpha_composite(fade)
if os.path.isfile(fade_fn + "_fade_right.png") == True:
fade = Image.open(fade_fn + "_fade_right.png")
layer_comp.alpha_composite(fade)
if os.path.isfile(fade_fn + "_fade_bottom.png") == True:
fade = Image.open(fade_fn + "_fade_bottom.png")
layer_comp.alpha_composite(fade)
if os.path.isfile(fade_fn + "_fade_left.png") == True:
fade = Image.open(fade_fn + "_fade_left.png")
layer_comp.alpha_composite(fade)
mstr_msg("layergen", "Adjacent fading completed")
# Store layer # Store layer
if self._is_completion == False: if self._is_completion == False:
layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" ) layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" )
@ -805,6 +828,7 @@ class mstr_layergen:
if self._tag == "waterway" and (self._value == "river" or self._value == "stream"): if self._tag == "waterway" and (self._value == "river" or self._value == "stream"):
layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=4)) layer_comp = layer_comp.filter(ImageFilter.GaussianBlur(radius=4))
# Store layer # Store layer
layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" ) layer_comp.save( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_layer.png" )
mstr_msg("layergen", "Layer image finalized and saved.") mstr_msg("layergen", "Layer image finalized and saved.")
@ -823,3 +847,146 @@ class mstr_layergen:
nrm = mstr_xp_normalmap(self._latitude, self._longitude, self._tag, self._value, self._lat_number, self._lng_number, self._latlngfld) nrm = mstr_xp_normalmap(self._latitude, self._longitude, self._tag, self._value, self._lat_number, self._lng_number, self._latlngfld)
nrm.build_normalmap() nrm.build_normalmap()
# Should we find more than one source, the first one found will take precedence.
# For the others, we will need to generate fading images, so that the final layer
# image works with other tiles
def generate_adjacent_fades(self):
adj_sources = self.find_all_adjacent_sources()
precedence = -1
# Be prepared for every border
brd_t = Image.open(mstr_datafolder + "textures/multi_source/brd_t.png")
brd_r = Image.open(mstr_datafolder + "textures/multi_source/brd_r.png")
brd_b = Image.open(mstr_datafolder + "textures/multi_source/brd_b.png")
brd_l = Image.open(mstr_datafolder + "textures/multi_source/brd_l.png")
brd_t_pix = brd_t.load()
brd_r_pix = brd_r.load()
brd_b_pix = brd_b.load()
brd_l_pix = brd_l.load()
for s in range(0, 4):
if adj_sources[s] != -1:
precedence = adj_sources[s]
break
# Generate required images
# Basically a shortened version of the main layergen call
for s in range(0, 4):
if adj_sources[s] != precedence and adj_sources[s] != -1:
src = adj_sources[s]
adj_image = Image.new("RGBA", (self._imgsize, self._imgsize))
adj_pix = adj_image.load()
# Root folder
root_folder = mstr_datafolder + "textures/" + self._tag + "/" + self._value
# Load in the sources to work with
ptc = glob.glob(root_folder + "/ptc/b" + str(src) + "_p*.png")
brd_src = Image.open(root_folder + "/brd/b" + str(src) + ".png")
ptc_src = []
for p in ptc:
ptc_src.append(Image.open(p))
osm_mask = Image.open( mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + ".png" )
for i in mstr_mask_blur:
if i[0] == self._tag and i[1] == self._value:
if self._tag != "place" and (self._value != "sea" or self._value != "ocean"):
osm_mask = osm_mask.filter(ImageFilter.BoxBlur(radius=i[2]))
break
mask_pix = osm_mask.load()
# Begin producing a largely random image
samples = 250 # <- We need this in a moment
for i in range(samples):
imgid = 0
if len(ptc_src) == 1: imgid = 0
if len(ptc_src) >= 2:
imgid = randrange(1, len(ptc_src)+1) - 1
l = 0 - int(ptc_src[imgid].width / 2)
r = adj_image.width - int(ptc_src[imgid].width / 2)
t = 0 - int(ptc_src[imgid].height / 2)
b = adj_image.height - int(ptc_src[imgid].height / 2)
adj_image.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) )
adj_image.alpha_composite( brd_src )
for y in range(self._imgsize):
for x in range(self._imgsize):
if mask_pix[x, y][3] > 0:
rgb=adj_pix[x,y]
a=mask_pix[x,y]
adj_pix[x, y] = ( rgb[0], rgb[1], rgb[2], a[3])
# Up until here we mimiced the exact same behavior as layergen. However, now
# we need to adjust the alpha to make this layer fade.
# Then, we save the image
if s == 0:
for y in range(self._imgsize):
for x in range(self._imgsize):
fade_a = brd_t_pix[0, y]
if mask_pix[x, y][3] > 0:
c = adj_pix[x,y]
adj_pix[x,y] = (c[0], c[1], c[2], fade_a[3])
else:
adj_pix[x,y] = (0,0,0,0)
adj_image.save(mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_fade_top.png")
if s == 1:
for y in range(self._imgsize):
for x in range(self._imgsize):
fade_a = brd_r_pix[x, 0]
if mask_pix[x, y][3] > 0:
c = adj_pix[x,y]
adj_pix[x,y] = (c[0], c[1], c[2], fade_a[3])
else:
adj_pix[x,y] = (0,0,0,0)
adj_image.save(mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_fade_right.png")
if s == 2:
for y in range(self._imgsize):
for x in range(self._imgsize):
fade_a = brd_b_pix[0, y]
if mask_pix[x, y][3] > 0:
c = adj_pix[x,y]
adj_pix[x,y] = (c[0], c[1], c[2], fade_a[3])
else:
adj_pix[x,y] = (0,0,0,0)
adj_image.save(mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_fade_bottom.png")
if s == 3:
for y in range(self._imgsize):
for x in range(self._imgsize):
fade_a = brd_l_pix[x, 0]
if mask_pix[x, y][3] > 0:
c = adj_pix[x,y]
adj_pix[x,y] = (c[0], c[1], c[2], fade_a[3])
else:
adj_pix[x,y] = (0,0,0,0)
adj_image.save(mstr_datafolder + "_cache/" + str(self._latitude) + "-" + str(self._lat_number) + "_" + str(self._longitude) + "-" + str(self._lng_number) + "_" + self._tag + "-" + self._value + "_fade_left.png")
def find_all_adjacent_sources(self):
# Sources for this tag and value - top, right, bottom, left
sources = [-1,-1,-1,-1]
# Perform query for each neighboring tile
src_top = self._tileinfo.get_adjacency_for_tag_and_value(self._lat_number+1, self._lng_number, self._tag, self._value)
src_rgt = self._tileinfo.get_adjacency_for_tag_and_value(self._lat_number, self._lng_number+1, self._tag, self._value)
src_btm = self._tileinfo.get_adjacency_for_tag_and_value(self._lat_number-1, self._lng_number, self._tag, self._value)
src_lft = self._tileinfo.get_adjacency_for_tag_and_value(self._lat_number, self._lng_number-1, self._tag, self._value)
if len(src_top) == 2:
if "b" in src_top[1]: sources[0] = src_top[0]
if len(src_rgt) == 2:
if "l" in src_rgt[1]: sources[1] = src_rgt[0]
if len(src_btm) == 2:
if "t" in src_btm[1]: sources[2] = src_btm[0]
if len(src_lft) == 2:
if "r" in src_lft[1]: sources[3] = src_lft[0]
# Report our findings
return sources

Binary file not shown.

After

Width:  |  Height:  |  Size: 1001 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B