From 7fd3ccd4ade72b0cbd72773dfc533438c669be9a Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 9 Oct 2021 13:33:59 +0200 Subject: [PATCH] Generic image rendering / property connection api for mat_maker_gd. --- game/addons/mat_maker_gd/nodes/mm_material.gd | 29 +++++++++- game/addons/mat_maker_gd/nodes/mm_node.gd | 53 +++++++++++++++++-- .../nodes/mm_node_universal_property.gd | 21 ++++++++ .../addons/mat_maker_gd/nodes/noise/perlin.gd | 4 +- .../addons/mat_maker_gd/nodes/simple/shape.gd | 8 ++- 5 files changed, 106 insertions(+), 9 deletions(-) diff --git a/game/addons/mat_maker_gd/nodes/mm_material.gd b/game/addons/mat_maker_gd/nodes/mm_material.gd index 1150bdaa..10806c59 100644 --- a/game/addons/mat_maker_gd/nodes/mm_material.gd +++ b/game/addons/mat_maker_gd/nodes/mm_material.gd @@ -2,11 +2,36 @@ tool class_name MMMateial extends Resource -var MMMNode = preload("res://addons/mat_maker_gd/nodes/mm_node.gd") - export(Vector2) var image_size : Vector2 = Vector2(128, 128) export(Array) var nodes : Array +func _init(): + for n in nodes: + n.connect("changed", self, "on_node_changed") + func add_node(node : MMNode) -> void: nodes.append(node) + + node.connect("changed", self, "on_node_changed") + emit_changed() + +func remove_node(node : MMNode) -> void: + nodes.erase(node) + + node.disconnect("changed", self, "on_node_changed") + + emit_changed() + +func render() -> void: + var did_render : bool = true + + while did_render: + did_render = false + + for n in nodes: + if n && n.render(self): + did_render = true + +func on_node_changed() -> void: + call_deferred("render") diff --git a/game/addons/mat_maker_gd/nodes/mm_node.gd b/game/addons/mat_maker_gd/nodes/mm_node.gd index 18420fbf..916b36ef 100644 --- a/game/addons/mat_maker_gd/nodes/mm_node.gd +++ b/game/addons/mat_maker_gd/nodes/mm_node.gd @@ -4,9 +4,30 @@ extends Resource export(Vector2) var graph_position : Vector2 = Vector2() +var input_properties : Array + var properties_initialized : bool = false -func recalculate_image(material, slot_idx : int) -> ImageTexture: +var dirty : bool = true + +#MMMateial +func render(material) -> bool: + if !dirty: + return false + + for p in input_properties: + if p.input_property && p.input_property.owner.dirty: + return false + + _render(material) + + return true + +#MMMateial +func _render(material) -> void: + pass + +func render_image(material) -> ImageTexture: var image : Image = Image.new() image.create(material.image_size.x, material.image_size.y, false, Image.FORMAT_RGBA8) @@ -23,7 +44,7 @@ func recalculate_image(material, slot_idx : int) -> ImageTexture: for y in range(image.get_height()): var v : Vector2 = Vector2(x / w, y / h) - var col : Color = get_value_for(v, slot_idx, pseed) + var col : Color = get_value_for(v, pseed) image.set_pixel(x, y, col) @@ -33,7 +54,7 @@ func recalculate_image(material, slot_idx : int) -> ImageTexture: return tex -func get_value_for(uv : Vector2, slot_idx : int, pseed : int) -> Color: +func get_value_for(uv : Vector2, pseed : int) -> Color: return Color() func init_properties() -> void: @@ -59,3 +80,29 @@ func set_graph_position(pos : Vector2) -> void: graph_position = pos emit_changed() + +func register_input_property(prop : MMNodeUniversalProperty) -> void: + prop.owner = self + + prop.connect("changed", self, "on_input_property_changed") + + input_properties.append(prop) + +func unregister_input_property(prop : MMNodeUniversalProperty) -> void: + if prop.owner == self: + prop.owner = null + + prop.disconnect("changed", self, "on_input_property_changed") + + input_properties.erase(prop) + +func set_dirty(val : bool) -> void: + var changed : bool = val != dirty + + dirty = val + + if changed: + emit_changed() + +func on_input_property_changed() -> void: + set_dirty(true) diff --git a/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd b/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd index 97713459..eb2787a1 100644 --- a/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd +++ b/game/addons/mat_maker_gd/nodes/mm_node_universal_property.gd @@ -42,6 +42,13 @@ var slot_name : String var value_step : float = 0.1 var value_range : Vector2 = Vector2(-1000, 1000) +#MMNode +var owner + +func _init(): + if input_property: + input_property.connect("changed", self, "on_input_property_cahnged") + func get_value(uv : Vector2): if !input_property: return get_default_value(uv) @@ -107,3 +114,17 @@ func get_active_image() -> Image: return override_image return default_image + +func set_input_property(val : MMNodeUniversalProperty) -> void: + if input_property == val: + return + + if input_property: + input_property.disconnect("changed", self, "on_input_property_cahnged") + + input_property = val + + input_property.connect("changed", self, "on_input_property_cahnged") + +func on_input_property_cahnged() -> void: + emit_changed() diff --git a/game/addons/mat_maker_gd/nodes/noise/perlin.gd b/game/addons/mat_maker_gd/nodes/noise/perlin.gd index a3fc7687..9bb7030e 100644 --- a/game/addons/mat_maker_gd/nodes/noise/perlin.gd +++ b/game/addons/mat_maker_gd/nodes/noise/perlin.gd @@ -10,11 +10,11 @@ export(Vector2) var scale : Vector2 = Vector2(4, 4) export(int) var iterations : int = 3 export(float) var persistence : float = 0.5 -func get_value_for(uv : Vector2, slot_idx : int, pseed : int) -> Color: +func get_value_for(uv : Vector2, pseed : int) -> Color: return NoisePerlin.perlinc(uv, scale, iterations, persistence, pseed) func _register_methods(mm_graph_node) -> void: - mm_graph_node.add_slot_texture(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_IMAGE, "recalculate_image", "") + mm_graph_node.add_slot_texture(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_IMAGE, "render_image", "") mm_graph_node.add_slot_int(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, "get_iterations", "set_iterations", "iterations")#, Vector2(1, 10)) mm_graph_node.add_slot_float(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, "get_persistence", "set_persistence", "persistence", 0.05)#, Vector2(0, 1)) mm_graph_node.add_slot_vector2(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, "get_scale", "set_scale", "scale", 1)#, Vector2(1, 32)) diff --git a/game/addons/mat_maker_gd/nodes/simple/shape.gd b/game/addons/mat_maker_gd/nodes/simple/shape.gd index c486e848..3eab639b 100644 --- a/game/addons/mat_maker_gd/nodes/simple/shape.gd +++ b/game/addons/mat_maker_gd/nodes/simple/shape.gd @@ -40,15 +40,19 @@ func _init_properties(): edge.input_slot_type = MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_UNIVERSAL edge.slot_name = "edge" edge.value_step = 0.05 + + #this will end up generating the image + #maybe whis should be automaticly done whenn added into material + #emit_changed() func _register_methods(mm_graph_node) -> void: - mm_graph_node.add_slot_texture(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_IMAGE, "recalculate_image", "") + mm_graph_node.add_slot_texture(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_IMAGE, "render_image", "") mm_graph_node.add_slot_enum(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, "get_shape_typoe", "set_shape_typoe", "shape_type", [ "Circle", "Polygon", "Star", "Curved Star", "Rays" ]) mm_graph_node.add_slot_int(MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, MMNodeUniversalProperty.SlotTypes.SLOT_TYPE_NONE, "get_sides", "set_sides", "sides")#, Vector2(1, 10)) mm_graph_node.add_slot_float_universal(radius) mm_graph_node.add_slot_float_universal(edge) -func get_value_for(uv : Vector2, slot_idx : int, pseed : int) -> Color: +func get_value_for(uv : Vector2, pseed : int) -> Color: var c : float = 0 if shape_type == ShapeType.SHAPE_TYPE_CIRCLE: