Add smooth terrain
|
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 387 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
BIN
world_maker/data/heightmap_smooth.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 645 B |
|
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 809 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 454 B |
|
Before Width: | Height: | Size: 960 B After Width: | Height: | Size: 888 B |
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 268 B After Width: | Height: | Size: 748 B |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
world_maker/data/smooth_terrain_delta.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 119 B After Width: | Height: | Size: 658 B |
@@ -105,7 +105,7 @@ def filter_sobel(image: Union[str, Image]) -> Image:
|
||||
return image
|
||||
|
||||
|
||||
def filter_smooth(image: Union[str, Image], radius: int = 3):
|
||||
def filter_smooth_theshold(image: Union[str, Image], radius: int = 3):
|
||||
"""
|
||||
:param image: white and black image representing the derivative of the terrain (sobel), where black is flat and white is very steep.
|
||||
:param radius: Radius of the Gaussian blur.
|
||||
@@ -135,6 +135,14 @@ def filter_smooth(image: Union[str, Image], radius: int = 3):
|
||||
return Image.fromarray(bool_array)
|
||||
|
||||
|
||||
def filter_smooth(image: Union[str, Image], radius: int = 3):
|
||||
|
||||
image = handle_import_image(image)
|
||||
image = image.convert('L')
|
||||
image = image.filter(ImageFilter.GaussianBlur(radius))
|
||||
return image
|
||||
|
||||
|
||||
def subtract_map(image: Union[str, Image], substractImage: Union[str, Image]) -> Image:
|
||||
image = handle_import_image(image)
|
||||
substractImage = handle_import_image(substractImage).convert('L')
|
||||
@@ -163,7 +171,7 @@ def group_map(image1: Union[str, Image], image2: Union[str, Image]) -> Image:
|
||||
|
||||
def filter_smooth_array(array: np.ndarray, radius: int = 3) -> np.ndarray:
|
||||
image = Image.fromarray(array)
|
||||
smooth_image = filter_smooth(image, radius)
|
||||
smooth_image = filter_smooth_theshold(image, radius)
|
||||
array = np.array(smooth_image)
|
||||
return array
|
||||
|
||||
@@ -182,7 +190,7 @@ def filter_remove_details(image: Union[str, Image], n: int = 20) -> Image:
|
||||
|
||||
def highway_map() -> Image:
|
||||
print("[Data Analysis] Generating highway map...")
|
||||
smooth_sobel = filter_smooth("./world_maker/data/sobelmap.png", 1)
|
||||
smooth_sobel = filter_smooth_theshold("./world_maker/data/sobelmap.png", 1)
|
||||
negative_smooth_sobel = filter_negative(smooth_sobel)
|
||||
negative_smooth_sobel_water = subtract_map(
|
||||
negative_smooth_sobel, './world_maker/data/watermap.png')
|
||||
@@ -247,7 +255,7 @@ def smooth_sobel_water() -> Image:
|
||||
watermap = filter_negative(
|
||||
filter_remove_details(filter_negative(watermap), 5))
|
||||
sobel = handle_import_image("./world_maker/data/sobelmap.png")
|
||||
sobel = filter_remove_details(filter_smooth(sobel, 1), 2)
|
||||
sobel = filter_remove_details(filter_smooth_theshold(sobel, 1), 2)
|
||||
group = group_map(watermap, sobel)
|
||||
group = filter_negative(group)
|
||||
group.save('./world_maker/data/smooth_sobel_watermap.png')
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
from typing import Union
|
||||
|
||||
import numpy as np
|
||||
from gdpc import Editor, Block, geometry
|
||||
from gdpc import Editor, Block, geometry, lookup
|
||||
from PIL import Image
|
||||
from skimage import morphology
|
||||
|
||||
from world_maker.data_analysis import handle_import_image
|
||||
|
||||
|
||||
def remove_trees(heightmap: Union[str, Image], treesmap: Union[str, Image], mask: Union[str, Image], ):
|
||||
def remove_trees(heightmap: Union[str, Image], treesmap: Union[str, Image], mask: Union[str, Image]):
|
||||
|
||||
editor = Editor(buffering=True)
|
||||
build_area = editor.getBuildArea()
|
||||
@@ -29,7 +29,7 @@ def remove_trees(heightmap: Union[str, Image], treesmap: Union[str, Image], mask
|
||||
for x in range(0, distance[0]):
|
||||
for z in range(0, distance[1]):
|
||||
|
||||
if mask.getpixel((x, z)) == 255 and treesmap.getpixel((x, z)) > 0 and (x, z) not in removed:
|
||||
if mask.getpixel((x, z)) != 0 and treesmap.getpixel((x, z)) > 0 and (x, z) not in removed:
|
||||
|
||||
treeArea = morphology.flood(treesmap, (z, x), tolerance=1)
|
||||
blend = Image.blend(Image.fromarray(treeArea).convert(
|
||||
@@ -52,3 +52,48 @@ def remove_trees(heightmap: Union[str, Image], treesmap: Union[str, Image], mask
|
||||
y_top = removed_treesmap.getpixel((x, z))
|
||||
geometry.placeLine(
|
||||
editor, (start[0] + x, y+1, start[1] + z), (start[0] + x, y_top, start[1] + z), Block('air'))
|
||||
|
||||
|
||||
def smooth_terrain(heightmap: Union[str, Image], heightmap_smooth: Union[str, Image], mask: Union[str, Image]):
|
||||
|
||||
editor = Editor()
|
||||
build_area = editor.getBuildArea()
|
||||
build_rectangle = build_area.toRect()
|
||||
|
||||
start = build_rectangle.begin
|
||||
|
||||
distance = (max(build_rectangle.end[0], build_rectangle.begin[0]) - min(build_rectangle.end[0], build_rectangle.begin[0]), max(
|
||||
build_rectangle.end[1], build_rectangle.begin[1]) - min(build_rectangle.end[1], build_rectangle.begin[1]))
|
||||
|
||||
heightmap = handle_import_image(heightmap).convert('L')
|
||||
heightmap_smooth = handle_import_image(heightmap_smooth).convert('L')
|
||||
mask = handle_import_image(mask).convert('L')
|
||||
|
||||
smooth_terrain_delta = Image.new("RGB", distance, 0)
|
||||
|
||||
slice = editor.loadWorldSlice(build_rectangle)
|
||||
smoothable_blocks = lookup.OVERWORLD_SOILS | lookup.OVERWORLD_STONES | lookup.SNOWS
|
||||
|
||||
for x in range(0, distance[0]):
|
||||
for z in range(0, distance[1]):
|
||||
|
||||
if mask.getpixel((x, z)) != 0:
|
||||
y = heightmap.getpixel((x, z))
|
||||
y_smooth = heightmap_smooth.getpixel((x, z))
|
||||
delta = y - y_smooth
|
||||
smooth_terrain_delta.putpixel((x, z), delta)
|
||||
|
||||
if delta != 0:
|
||||
block = slice.getBlock((x, y, z))
|
||||
if block.id in smoothable_blocks:
|
||||
if delta > 0:
|
||||
geometry.placeLine(
|
||||
editor, (start[0] + x, y, start[1] + z), (start[0] + x, y_smooth, start[1] + z), Block('air'))
|
||||
editor.placeBlock(
|
||||
(start[0] + x, y_smooth, start[1] + z), block)
|
||||
|
||||
else:
|
||||
geometry.placeLine(
|
||||
editor, (start[0] + x, y, start[1] + z), (start[0] + x, y_smooth, start[1] + z), block)
|
||||
|
||||
smooth_terrain_delta.save('./world_maker/data/smooth_terrain_delta.png')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from world_maker.World import World
|
||||
from PIL import Image
|
||||
from world_maker.data_analysis import (get_data, filter_negative, rectangle_2D_to_3D, skeleton_mountain_map, highway_map, filter_sobel, skeleton_highway_map,
|
||||
smooth_sobel_water, subtract_map, detect_mountain)
|
||||
smooth_sobel_water, subtract_map, detect_mountain, filter_smooth)
|
||||
from world_maker.City import City
|
||||
from world_maker.Position import Position
|
||||
from random import randint
|
||||
@@ -11,8 +11,13 @@ from world_maker.pack_rectangle import generate_building
|
||||
def world_maker():
|
||||
world = World()
|
||||
heightmap, watermap, treemap = get_data(world)
|
||||
|
||||
filter_smooth(
|
||||
'./world_maker/data/heightmap.png', 4).save('./world_maker/data/heightmap_smooth.png')
|
||||
|
||||
filter_sobel(
|
||||
"./world_maker/data/heightmap.png").save('./world_maker/data/sobelmap.png')
|
||||
|
||||
smooth_sobel_water_map = smooth_sobel_water()
|
||||
skeleton_highway = skeleton_highway_map(highway_map())
|
||||
city = City()
|
||||
|
||||