mirror of
https://github.com/Relintai/wfc_module_samples.git
synced 2025-04-22 20:21:18 +02:00
Added support for the Tiling WFC demos (they still need some engine side fixes to actually not hang though.). Also improvements to the code.
This commit is contained in:
parent
f556b5e1dc
commit
289e320311
@ -9,7 +9,7 @@ anchor_bottom = 1.0
|
||||
script = ExtResource( 1 )
|
||||
source_image_rect_path = NodePath("VBoxContainer2/VBoxContainer/HBoxContainer/TextureRect")
|
||||
result_image_rect_path = NodePath("VBoxContainer2/VBoxContainer/HBoxContainer2/TextureRect")
|
||||
settings_label_path = NodePath("VBoxContainer2/VBoxContainer/HBoxContainer3/Label2")
|
||||
settings_label_path = NodePath("VBoxContainer2/VBoxContainer/HBoxContainer3/ScrollContainer/Label2")
|
||||
|
||||
[node name="VBoxContainer2" type="VBoxContainer" parent="."]
|
||||
margin_left = 7.0
|
||||
@ -58,18 +58,29 @@ expand = true
|
||||
|
||||
[node name="HBoxContainer3" type="VBoxContainer" parent="VBoxContainer2/VBoxContainer"]
|
||||
margin_left = 608.0
|
||||
margin_right = 659.0
|
||||
margin_right = 1010.0
|
||||
margin_bottom = 562.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer2/VBoxContainer/HBoxContainer3"]
|
||||
margin_right = 51.0
|
||||
margin_right = 402.0
|
||||
margin_bottom = 14.0
|
||||
text = "Settings"
|
||||
|
||||
[node name="Label2" type="Label" parent="VBoxContainer2/VBoxContainer/HBoxContainer3"]
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer2/VBoxContainer/HBoxContainer3"]
|
||||
margin_top = 18.0
|
||||
margin_right = 51.0
|
||||
margin_bottom = 32.0
|
||||
margin_right = 402.0
|
||||
margin_bottom = 562.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Label2" type="Label" parent="VBoxContainer2/VBoxContainer/HBoxContainer3/ScrollContainer"]
|
||||
margin_right = 402.0
|
||||
margin_bottom = 544.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 7
|
||||
autowrap = true
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"]
|
||||
margin_top = 566.0
|
||||
|
@ -13,6 +13,46 @@ enum SampleDataType {
|
||||
SAMPLE_DATA_TYPE_TILED = 1,
|
||||
};
|
||||
|
||||
class TileEntry:
|
||||
var tile_name : String = ""
|
||||
var symmetry : int = 0
|
||||
var weight : float = 1
|
||||
var image : Image
|
||||
var images : Array
|
||||
|
||||
func _to_string():
|
||||
var t : String = ""
|
||||
|
||||
if image:
|
||||
t = "simple"
|
||||
else:
|
||||
t = "complex (" + str(images.size()) + ")"
|
||||
|
||||
return "[ TileEntry " + t + " tile_name: " + tile_name + ", symmetry: " + str(symmetry) + " weight: " + str(weight) + " ]\n"
|
||||
|
||||
class NeighbourEntry:
|
||||
var left : String = ""
|
||||
var left_orientation : int = 0
|
||||
var right : String = ""
|
||||
var right_orientation : int = 0
|
||||
|
||||
func setup(l : String, r : String):
|
||||
left = l.get_slice(" ", 0)
|
||||
var s : String = l.get_slice(" ", 1)
|
||||
|
||||
if (s != ""):
|
||||
left_orientation = int(s)
|
||||
|
||||
right = r.get_slice(" ", 0)
|
||||
|
||||
s = l.get_slice(" ", 1)
|
||||
|
||||
if (s != ""):
|
||||
right_orientation = int(s)
|
||||
|
||||
func _to_string():
|
||||
return "[ NeighbourEntry left: " + left + "(" + str(left_orientation) + "), right: " + right + "(" + str(right_orientation) + ") ]\n"
|
||||
|
||||
class SampleData:
|
||||
var type : int = 0
|
||||
var image_name : String = ""
|
||||
@ -25,6 +65,9 @@ class SampleData:
|
||||
var limit : int = 0
|
||||
var screenshots : int = 0
|
||||
var periodic_input : int = true
|
||||
var tiles : Array
|
||||
var neighbours : Array
|
||||
var image : Image
|
||||
|
||||
func _to_string():
|
||||
return "SampleData\ntype: " + str(type) + \
|
||||
@ -37,8 +80,9 @@ class SampleData:
|
||||
"\nground: " + str(ground) + \
|
||||
"\nlimit: " + str(limit) + \
|
||||
"\nscreenshots: " + str(screenshots) + \
|
||||
"\nperiodic_input: " + str(periodic_input)
|
||||
|
||||
"\nperiodic_input: " + str(periodic_input) + \
|
||||
"\ntiles: " + str(tiles) + \
|
||||
"\nneighbours: " + str(neighbours)
|
||||
|
||||
var data : Array
|
||||
|
||||
@ -88,9 +132,80 @@ func load_data():
|
||||
entry.screenshots = int(attrib_value)
|
||||
elif attrib_name == "periodic_input":
|
||||
entry.periodic_input = int(attrib_value)
|
||||
|
||||
|
||||
if entry.type == SampleDataType.SAMPLE_DATA_TYPE_TILED:
|
||||
var e : Array = load_tile_entry(entry)
|
||||
entry.tiles = e[0]
|
||||
entry.neighbours = e[1]
|
||||
else:
|
||||
entry.image = ResourceLoader.load("res://samples/" + entry.image_name + ".png")
|
||||
|
||||
data.push_back(entry)
|
||||
|
||||
func load_tile_entry(entry : SampleData) -> Array:
|
||||
var xmlp : XMLParser = XMLParser.new()
|
||||
xmlp.open("res://samples/" + entry.image_name + "/data.xml")
|
||||
|
||||
var tiles : Array
|
||||
var neighbours : Array
|
||||
|
||||
while xmlp.read() == OK:
|
||||
if xmlp.get_node_type() == XMLParser.NODE_ELEMENT:
|
||||
if xmlp.get_node_name() == "tile":
|
||||
var e : TileEntry = TileEntry.new()
|
||||
|
||||
for i in range(xmlp.get_attribute_count()):
|
||||
var attrib_name : String = xmlp.get_attribute_name(i)
|
||||
var attrib_value : String = xmlp.get_attribute_value(i)
|
||||
|
||||
if attrib_name == "name":
|
||||
e.tile_name = attrib_value
|
||||
elif attrib_name == "symmetry":
|
||||
e.symmetry = int(attrib_value)
|
||||
elif attrib_name == "weight":
|
||||
e.weight = float(attrib_value)
|
||||
|
||||
var simple_image_path : String = "res://samples/" + entry.image_name + "/" + e.tile_name + ".png"
|
||||
|
||||
var file : File = File.new()
|
||||
if !file.file_exists(simple_image_path):
|
||||
var indx : int = 0
|
||||
while true:
|
||||
var image_path : String = "res://samples/" + entry.image_name + "/" + e.tile_name + " " + str(indx) + ".png"
|
||||
|
||||
if !file.file_exists(image_path):
|
||||
break
|
||||
|
||||
e.images.push_back(ResourceLoader.load(image_path))
|
||||
indx += 1
|
||||
else:
|
||||
e.image = ResourceLoader.load(simple_image_path)
|
||||
|
||||
|
||||
|
||||
tiles.push_back(e)
|
||||
elif xmlp.get_node_name() == "neighbor":
|
||||
var e : NeighbourEntry = NeighbourEntry.new()
|
||||
|
||||
var left : String
|
||||
var right : String
|
||||
|
||||
for i in range(xmlp.get_attribute_count()):
|
||||
var attrib_name : String = xmlp.get_attribute_name(i)
|
||||
var attrib_value : String = xmlp.get_attribute_value(i)
|
||||
|
||||
if attrib_name == "left":
|
||||
left = attrib_value
|
||||
elif attrib_name == "right":
|
||||
right = attrib_value
|
||||
|
||||
e.setup(left, right)
|
||||
neighbours.push_back(e)
|
||||
|
||||
|
||||
return [ tiles, neighbours ]
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
_on_next_pressed()
|
||||
|
||||
@ -110,13 +225,11 @@ func generate_image_overlapping():
|
||||
|
||||
var indexer : ImageIndexer = ImageIndexer.new()
|
||||
|
||||
var img : Image = ResourceLoader.load("res://samples/" + sd.image_name + ".png")
|
||||
var source_tex : ImageTexture = ImageTexture.new();
|
||||
source_tex.create_from_image(img, 0)
|
||||
source_tex.create_from_image(sd.image, 0)
|
||||
get_node(source_image_rect_path).texture = source_tex
|
||||
|
||||
indexer.index_image(img)
|
||||
var indices : PoolIntArray = indexer.get_color_indices()
|
||||
var indices : PoolIntArray = indexer.index_image(sd.image)
|
||||
|
||||
var wfc : OverlappingWaveFormCollapse = OverlappingWaveFormCollapse.new()
|
||||
wfc.pattern_size = sd.pattern_size
|
||||
@ -126,10 +239,10 @@ func generate_image_overlapping():
|
||||
|
||||
wfc.periodic_input = sd.periodic_input
|
||||
|
||||
wfc.out_height = img.get_height()
|
||||
wfc.out_width = img.get_width()
|
||||
wfc.out_height = sd.image.get_height()
|
||||
wfc.out_width = sd.image.get_width()
|
||||
|
||||
wfc.set_input(indices, img.get_width(), img.get_height())
|
||||
wfc.set_input(indices, sd.image.get_width(), sd.image.get_height())
|
||||
|
||||
#todo
|
||||
#if sd.width > 0 && sd.height > 0:
|
||||
@ -151,7 +264,7 @@ func generate_image_overlapping():
|
||||
var data : PoolByteArray = indexer.indices_to_argb8_data(res)
|
||||
|
||||
var res_img : Image = Image.new()
|
||||
res_img.create_from_data(img.get_width(), img.get_height(), false, Image.FORMAT_RGBA8, data)
|
||||
res_img.create_from_data(sd.image.get_width(), sd.image.get_height(), false, Image.FORMAT_RGBA8, data)
|
||||
|
||||
var res_tex : ImageTexture = ImageTexture.new();
|
||||
res_tex.create_from_image(res_img, 0)
|
||||
@ -159,12 +272,69 @@ func generate_image_overlapping():
|
||||
get_node(result_image_rect_path).texture = res_tex
|
||||
|
||||
func generate_image_tiled():
|
||||
#load data xml
|
||||
#process
|
||||
#index all images -> need new api to the indexer
|
||||
#add_neighbour set binding names -> {left_tile, left_orientation, right_tile, right_orientation}
|
||||
#left_orientation -> might need constants
|
||||
pass
|
||||
get_node(source_image_rect_path).texture = null
|
||||
get_node(result_image_rect_path).texture = null
|
||||
|
||||
var sd : SampleData = data[_current_data_index]
|
||||
|
||||
get_node(settings_label_path).text = str(_current_data_index) + "\n" + sd.to_string()
|
||||
|
||||
var indexer : ImageIndexer = ImageIndexer.new()
|
||||
var wfc : TilingWaveFormCollapse = TilingWaveFormCollapse.new()
|
||||
|
||||
for i in range(sd.tiles.size()):
|
||||
var te : TileEntry = sd.tiles[i]
|
||||
|
||||
if !te.image:
|
||||
var tile_index : int = wfc.tile_add(te.symmetry, te.weight)
|
||||
wfc.tile_name_set(tile_index, te.tile_name)
|
||||
|
||||
for img in te.images:
|
||||
var indices : PoolIntArray = indexer.index_image(img)
|
||||
wfc.tile_data_add(tile_index, indices, img.get_width(), img.get_height())
|
||||
else:
|
||||
var indices : PoolIntArray = indexer.index_image(te.image)
|
||||
var tile_index : int = wfc.tile_add_generated(indices, te.image.get_width(), te.image.get_height(), te.symmetry, te.weight)
|
||||
wfc.tile_name_set(tile_index, te.tile_name)
|
||||
|
||||
|
||||
for i in range(sd.neighbours.size()):
|
||||
var ne : NeighbourEntry = sd.neighbours[i]
|
||||
|
||||
wfc.neighbour_data_add_str(ne.left, ne.left_orientation, ne.right, ne.right_orientation)
|
||||
|
||||
wfc.periodic_output = sd.periodic
|
||||
|
||||
wfc.wave_width = sd.width
|
||||
wfc.wave_height = sd.height
|
||||
|
||||
#todo
|
||||
#if sd.width > 0 && sd.height > 0:
|
||||
# wfc.set_input(indices, sd.width, sd.height)
|
||||
#else:
|
||||
# wfc.set_input(indices, img.get_width(), img.get_height())
|
||||
|
||||
randomize()
|
||||
wfc.set_seed(randi())
|
||||
|
||||
wfc.initialize()
|
||||
|
||||
var res : PoolIntArray = wfc.generate_image_index_data()
|
||||
|
||||
if (res.size() == 0):
|
||||
print("(res.size() == 0)")
|
||||
return
|
||||
|
||||
var data : PoolByteArray = indexer.indices_to_argb8_data(res)
|
||||
|
||||
var res_img : Image = Image.new()
|
||||
res_img.create_from_data(sd.width, sd.height, false, Image.FORMAT_RGBA8, data)
|
||||
|
||||
var res_tex : ImageTexture = ImageTexture.new();
|
||||
res_tex.create_from_image(res_img, 0)
|
||||
|
||||
get_node(result_image_rect_path).texture = res_tex
|
||||
|
||||
|
||||
func _on_prev_pressed():
|
||||
while true:
|
||||
|
Loading…
Reference in New Issue
Block a user