From e41c509e9f400329f3bdbac3722dd030eec427cd Mon Sep 17 00:00:00 2001 From: RodZill4 Date: Sun, 27 Oct 2019 10:12:03 +0100 Subject: [PATCH] Updated normal map generator and fixed bugs --- addons/material_maker/engine/gen_graph.gd | 76 ++++++++++++++++++---- addons/material_maker/engine/gen_shader.gd | 19 ++++-- addons/material_maker/graph_edit.gd | 27 +++++--- addons/material_maker/library.gd | 13 ++-- addons/material_maker/nodes/normal_map.mmg | 2 +- 5 files changed, 103 insertions(+), 34 deletions(-) diff --git a/addons/material_maker/engine/gen_graph.gd b/addons/material_maker/engine/gen_graph.gd index a0f4637..76209b7 100644 --- a/addons/material_maker/engine/gen_graph.gd +++ b/addons/material_maker/engine/gen_graph.gd @@ -7,6 +7,8 @@ var connections = [] var editable = false +signal connections_changed(removed_connections, added_connections) + func fix_remotes() -> void: for c in get_children(): if c is MMGenRemote: @@ -79,7 +81,7 @@ func get_port_targets(gen_name: String, output_index: int) -> Array: rv.push_back(InputPort.new(tgt_gen, c.to_port)) return rv -func add_generator(generator : MMGenBase) -> void: +func add_generator(generator : MMGenBase) -> bool: var name = generator.name var index = 1 while has_node(name): @@ -87,8 +89,11 @@ func add_generator(generator : MMGenBase) -> void: name = generator.name + "_" + str(index) generator.name = name add_child(generator) + return true -func remove_generator(generator : MMGenBase) -> void: +func remove_generator(generator : MMGenBase) -> bool: + if !generator.can_be_deleted(): + return false var new_connections = [] for c in connections: if c.from != generator.name and c.to != generator.name: @@ -96,8 +101,8 @@ func remove_generator(generator : MMGenBase) -> void: connections = new_connections remove_child(generator) fix_remotes() - add_child(generator) generator.queue_free() + return true func replace_generator(old : MMGenBase, new : MMGenBase) -> void: new.name = old.name @@ -106,6 +111,20 @@ func replace_generator(old : MMGenBase, new : MMGenBase) -> void: old.free() add_child(new) +func get_connected_inputs(generator) -> Array: + var rv : Array = [] + for c in connections: + if c.to == generator.name: + rv.push_back(c.to_port) + return rv + +func get_connected_outputs(generator) -> Array: + var rv : Array = [] + for c in connections: + if c.from == generator.name: + rv.push_back(c.from_port) + return rv + func connect_children(from, from_port : int, to, to_port : int) -> bool: # check the new connection does not create a loop var spreadlist = [ InputPort.new(to, to_port) ] @@ -128,18 +147,51 @@ func connect_children(from, from_port : int, to, to_port : int) -> bool: connections.remove(remove) # create new connection connections.append({from=from.name, from_port=from_port, to=to.name, to_port=to_port}) + to.source_changed(to_port) return true func disconnect_children(from, from_port : int, to, to_port : int) -> bool: - while true: - var remove = -1 - for i in connections.size(): - if connections[i].from == from.name and connections[i].from_port == from_port and connections[i].to == to.name and connections[i].to_port == to_port: - remove = i - break - if remove == -1: - break - connections.remove(remove) + var new_connections : Array = [] + for c in connections: + if c.from != from.name or c.from_port != from_port or c.to != to.name or c.to_port != to_port: + new_connections.push_back(c) + else: + to.source_changed(to_port) + connections = new_connections + return true + +func reconnect_inputs(generator, reconnects : Dictionary) -> bool: + var new_connections : Array = [] + var added_connections : Array = [] + var removed_connections : Array = [] + for c in connections: + if c.to == generator.name and reconnects.has(c.to_port): + removed_connections.push_back(c.duplicate(true)) + if reconnects[c.to_port] < 0: + continue + c.to_port = reconnects[c.to_port] + added_connections.push_back(c.duplicate(true)) + new_connections.push_back(c) + connections = new_connections + if !removed_connections.empty(): + emit_signal("connections_changed", removed_connections, added_connections) + return true + +func reconnect_outputs(generator, reconnects : Dictionary) -> bool: + var new_connections : Array = [] + var added_connections : Array = [] + var removed_connections : Array = [] + for c in connections: + if c.from == generator.name and reconnects.has(c.from_port): + removed_connections.push_back(c.duplicate(true)) + if reconnects[c.from_port] < 0: + continue + c.from_port = reconnects[c.from_port] + added_connections.push_back(c.duplicate(true)) + new_connections.push_back(c) + connections = new_connections + if !removed_connections.empty(): + emit_signal("connections_changed", removed_connections, added_connections) return true func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary: diff --git a/addons/material_maker/engine/gen_shader.gd b/addons/material_maker/engine/gen_shader.gd index a910401..ca87782 100644 --- a/addons/material_maker/engine/gen_shader.gd +++ b/addons/material_maker/engine/gen_shader.gd @@ -106,14 +106,19 @@ func replace_input(string, context, input, type, src, default) -> Dictionary: src_code = yield(src_code, "completed") src_code.string = src_code[type] # Add global definitions - for d in src_code.globals: - if required_globals.find(d) == -1: - required_globals.push_back(d) + if src_code.has("globals"): + for d in src_code.globals: + if required_globals.find(d) == -1: + required_globals.push_back(d) # Add generated definitions - required_defs += src_code.defs + if src_code.has("defs"): + required_defs += src_code.defs # Add generated code - required_code += src_code.code - required_textures = src_code.textures + if src_code.has("code"): + required_code += src_code.code + # Add textures + if src_code.has("textures"): + required_textures = src_code.textures string = string.replace("$%s(%s)" % [ input, uv ], src_code.string) return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures, new_pass_required=new_pass_required } @@ -165,6 +170,8 @@ func subst(string, context, uv = "") -> Dictionary: elif p.type == "size": value_string = "%.9f" % pow(2, value) elif p.type == "enum": + if value >= p.values.size(): + value = 0 value_string = p.values[value].value elif p.type == "color": value_string = "vec4(%.9f, %.9f, %.9f, %.9f)" % [ value.r, value.g, value.b, value.a ] diff --git a/addons/material_maker/graph_edit.gd b/addons/material_maker/graph_edit.gd index 2740496..cc4b4dc 100644 --- a/addons/material_maker/graph_edit.gd +++ b/addons/material_maker/graph_edit.gd @@ -54,16 +54,23 @@ func connect_node(from, from_slot, to, to_slot): func disconnect_node(from, from_slot, to, to_slot) -> void: if generator.disconnect_children(get_node(from).generator, from_slot, get_node(to).generator, to_slot): .disconnect_node(from, from_slot, to, to_slot) - send_changed_signal(); + send_changed_signal() + +func on_connections_changed(removed_connections : Array, added_connections : Array) -> void: + print("connections_changed") + for c in removed_connections: + .disconnect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port) + for c in added_connections: + .connect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port) func remove_node(node) -> void: - generator.remove_generator(node.generator) - var node_name = node.name - for c in get_connection_list(): - if c.from == node_name or c.to == node_name: - disconnect_node(c.from, c.from_port, c.to, c.to_port) - node.queue_free() - send_changed_signal() + if generator.remove_generator(node.generator): + var node_name = node.name + for c in get_connection_list(): + if c.from == node_name or c.to == node_name: + disconnect_node(c.from, c.from_port, c.to, c.to_port) + node.queue_free() + send_changed_signal() # Global operations on graph @@ -111,8 +118,12 @@ func center_view() -> void: scroll_offset = center - 0.5*rect_size func update_view(g) -> void: + if generator != null: + generator.disconnect("connections_changed", self, "on_connections_changed") clear_view() generator = g + if generator != null: + generator.connect("connections_changed", self, "on_connections_changed") update_graph(generator.get_children(), generator.connections) subgraph_ui.visible = generator != top_generator subgraph_ui.get_node("Label").text = generator.label diff --git a/addons/material_maker/library.gd b/addons/material_maker/library.gd index 5ce69dd..d3c5f18 100644 --- a/addons/material_maker/library.gd +++ b/addons/material_maker/library.gd @@ -59,13 +59,12 @@ func get_preview_texture(data : Dictionary) -> ImageTexture: if data.has("icon") and data.has("library"): var image_path = data.library.left(data.library.rfind("."))+"/"+data.icon+".png" var t : ImageTexture - if false && image_path.left(6) == "res://": - t = load(image_path) as ImageTexture - else: - t = ImageTexture.new() - var image : Image = Image.new() - image.load(image_path) - t.create_from_image(image) + if image_path.left(6) == "res://": + image_path = ProjectSettings.globalize_path(image_path) + t = ImageTexture.new() + var image : Image = Image.new() + image.load(image_path) + t.create_from_image(image) return t return null diff --git a/addons/material_maker/nodes/normal_map.mmg b/addons/material_maker/nodes/normal_map.mmg index 0543376..529071d 100644 --- a/addons/material_maker/nodes/normal_map.mmg +++ b/addons/material_maker/nodes/normal_map.mmg @@ -1 +1 @@ -{"connections":[{"from":"nm_convolution","from_port":0,"to":"nm_postprocess","to_port":0},{"from":"nm_postprocess","from_port":0,"to":"gen_outputs","to_port":0},{"from":"gen_inputs","from_port":0,"to":"buffer","to_port":0},{"from":"buffer","from_port":0,"to":"nm_convolution","to_port":0}],"label":"Normal Map","name":"normal_map","node_position":{"x":0,"y":0},"nodes":[{"name":"buffer","node_position":{"x":-687.663818,"y":125.60614},"parameters":{"size":10},"type":"buffer"},{"convolution_params":{"input_type":"f","matrix":[[[-1,-1,0],[0,-2,0],[1,-1,0]],[[-2,0,0],0,[2,0,0]],[[-1,1,0],[0,2,0],[1,1,0]]],"output_type":"rgb","x":1,"y":1},"name":"nm_convolution","node_position":{"x":-690.25,"y":174.25},"parameters":{"size":10},"type":"convolution"},{"name":"nm_postprocess","node_position":{"x":-690.25,"y":222.25},"parameters":{"amount":0.995,"size":10},"shader_model":{"code":"","global":"","inputs":[{"default":"vec3(0.0)","label":"","name":"in","type":"rgb"}],"instance":"","name":"NormalMapPostProcess","outputs":[{"rgb":"0.5*normalize($in($uv)*$amount*vec3(-1.0, 1.0, 1.0)*$size/128.0-vec3(0.0, 0.0, 1.0))+vec3(0.5)","type":"rgb"}],"parameters":[{"default":9,"first":4,"label":"","last":11,"name":"size","type":"size"},{"default":1,"label":"","max":2,"min":0,"name":"amount","step":0.005,"type":"float"}]},"type":"shader"},{"name":"gen_parameters","node_position":{"x":-718.910156,"y":26.083313},"parameters":{"param0":10,"param1":0.995},"type":"remote","widgets":[{"label":"Size","linked_widgets":[{"node":"buffer","widget":"size"},{"node":"nm_convolution","widget":"size"},{"node":"nm_postprocess","widget":"size"}],"type":"linked_control"},{"label":"Amount","linked_widgets":[{"node":"nm_postprocess","widget":"amount"}],"type":"linked_control"}]},{"name":"gen_outputs","node_position":{"x":-407.663818,"y":151.047363},"parameters":{},"ports":[{"name":"port0","type":"rgba"}],"type":"ios"},{"name":"gen_inputs","node_position":{"x":-870.910156,"y":157.047363},"parameters":{},"ports":[{"name":"port0","type":"rgba"}],"type":"ios"}],"parameters":{"param0":10,"param1":0.995},"type":"graph"} \ No newline at end of file +{"connections":[{"from":"nm_convolution","from_port":0,"to":"nm_postprocess","to_port":0},{"from":"nm_postprocess","from_port":0,"to":"gen_outputs","to_port":0},{"from":"gen_inputs","from_port":0,"to":"buffer","to_port":0},{"from":"buffer","from_port":0,"to":"nm_convolution","to_port":0}],"label":"Normal Map","name":"normal_map","node_position":{"x":0,"y":0},"nodes":[{"name":"buffer","node_position":{"x":-687.663818,"y":125.60614},"parameters":{"size":10},"type":"buffer"},{"convolution_params":{"input_type":"f","matrix":[[[-1,-1,0],[0,-2,0],[1,-1,0]],[[-2,0,0],0,[2,0,0]],[[-1,1,0],[0,2,0],[1,1,0]]],"output_type":"rgb","x":1,"y":1},"name":"nm_convolution","node_position":{"x":-690.25,"y":174.25},"parameters":{"size":10},"type":"convolution"},{"name":"nm_postprocess","node_position":{"x":-690.25,"y":222.25},"parameters":{"amount":1,"format":0,"size":10,"type":0},"shader_model":{"code":"","global":"vec3 process_normal_default(vec3 v, float multiplier) {\n\treturn 0.5*normalize(v.xyz*multiplier+vec3(0.0, 0.0, -1.0))+vec3(0.5);\n}\n\nvec3 process_normal_opengl(vec3 v, float multiplier) {\n\treturn 0.5*normalize(v.xyz*multiplier+vec3(0.0, 0.0, 1.0))+vec3(0.5);\n}\n\nvec3 process_normal_directx(vec3 v, float multiplier) {\n\treturn 0.5*normalize(v.xyz*vec3(1.0, -1.0, 1.0)*multiplier+vec3(0.0, 0.0, 1.0))+vec3(0.5);\n}\n","inputs":[{"default":"vec3(0.0)","label":"","name":"in","type":"rgb"}],"instance":"","name":"NormalMapPostProcess","outputs":[{"rgb":"process_normal_$format($in($uv).xyz, $amount*$size/128.0)","type":"rgb"}],"parameters":[{"default":0,"label":"","name":"format","type":"enum","values":[{"name":"Default","value":"default"},{"name":"OpenGL","value":"opengl"},{"name":"DirectX","value":"directx"}]},{"default":9,"first":4,"label":"","last":11,"name":"size","type":"size"},{"default":1,"label":"","max":2,"min":0,"name":"amount","step":0.005,"type":"float"}]},"type":"shader"},{"name":"gen_parameters","node_position":{"x":-692.910156,"y":-4.916687},"parameters":{"amount":0.3,"param0":0,"param1":10,"param2":1,"param3":11,"size":4},"type":"remote","widgets":[{"label":"","linked_widgets":[{"node":"nm_postprocess","widget":"format"}],"name":"param0","type":"linked_control"},{"label":"","linked_widgets":[{"node":"buffer","widget":"size"},{"node":"nm_convolution","widget":"size"},{"node":"nm_postprocess","widget":"size"}],"name":"param1","type":"linked_control"},{"label":"","linked_widgets":[{"node":"nm_postprocess","widget":"amount"}],"name":"param2","type":"linked_control"}]},{"name":"gen_outputs","node_position":{"x":-407.663818,"y":151.047363},"parameters":{},"ports":[{"name":"port0","type":"rgba"}],"type":"ios"},{"name":"gen_inputs","node_position":{"x":-870.910156,"y":157.047363},"parameters":{},"ports":[{"name":"port0","type":"rgba"}],"type":"ios"}],"parameters":{"amount":0.3,"param0":0,"param1":10,"param2":1,"size":4},"type":"graph"} \ No newline at end of file