mirror of
https://github.com/Relintai/material-maker.git
synced 2024-11-13 06:27:18 +01:00
Updated remote and group creation
This commit is contained in:
parent
4246673c85
commit
26f083cd3d
@ -37,6 +37,9 @@ var parameters = {}
|
||||
func _ready() -> void:
|
||||
init_parameters()
|
||||
|
||||
func _post_load() -> void:
|
||||
pass
|
||||
|
||||
func can_be_deleted() -> bool:
|
||||
return true
|
||||
|
||||
@ -68,6 +71,13 @@ func get_type_name() -> String:
|
||||
func get_parameter_defs() -> Array:
|
||||
return []
|
||||
|
||||
func get_parameter_def(param_name : String) -> Dictionary:
|
||||
var parameter_defs = get_parameter_defs()
|
||||
for p in parameter_defs:
|
||||
if p.name == param_name:
|
||||
return p
|
||||
return {}
|
||||
|
||||
func set_parameter(n : String, v):
|
||||
parameters[n] = v
|
||||
source_changed(0)
|
||||
|
@ -7,6 +7,13 @@ var connections = []
|
||||
|
||||
var editable = false
|
||||
|
||||
func fix_remotes() -> void:
|
||||
for c in get_children():
|
||||
if c is MMGenRemote:
|
||||
c.fix()
|
||||
|
||||
func _post_load() -> void:
|
||||
fix_remotes()
|
||||
|
||||
func get_type() -> String:
|
||||
return "graph"
|
||||
@ -87,6 +94,9 @@ func remove_generator(generator : MMGenBase) -> void:
|
||||
if c.from != generator.name and c.to != generator.name:
|
||||
new_connections.append(c)
|
||||
connections = new_connections
|
||||
remove_child(generator)
|
||||
fix_remotes()
|
||||
add_child(generator)
|
||||
generator.queue_free()
|
||||
|
||||
func replace_generator(old : MMGenBase, new : MMGenBase) -> void:
|
||||
@ -152,13 +162,15 @@ func _serialize(data: Dictionary) -> Dictionary:
|
||||
func edit(node) -> void:
|
||||
node.get_parent().call_deferred("update_view", self)
|
||||
|
||||
func create_subgraph(gens) -> void:
|
||||
func create_subgraph(gens : Array) -> void:
|
||||
# Remove material, gen_inputs and gen_outputs nodes
|
||||
var generators = []
|
||||
var center = Vector2(0, 0)
|
||||
var left_bound = 65535
|
||||
var right_bound = -65536
|
||||
var upper_bound = 65536
|
||||
var count = 0
|
||||
# Filter group nodes and calculate boundin box
|
||||
for g in gens:
|
||||
if g.name != "Material" and g.name != "gen_inputs" and g.name != "gen_outputs":
|
||||
generators.push_back(g)
|
||||
@ -167,22 +179,33 @@ func create_subgraph(gens) -> void:
|
||||
count += 1
|
||||
if left_bound > p.x: left_bound = p.x
|
||||
if right_bound < p.x: right_bound = p.x
|
||||
if upper_bound > p.y: upper_bound = p.y
|
||||
if count == 0:
|
||||
return
|
||||
center /= count
|
||||
# Create a new graph and add it to the current one
|
||||
var new_graph = get_script().new()
|
||||
new_graph.name = "graph"
|
||||
add_generator(new_graph)
|
||||
new_graph.position = center
|
||||
# Add grouped generators and keep their names
|
||||
var names : Array = []
|
||||
for g in generators:
|
||||
names.push_back(g.name)
|
||||
remove_child(g)
|
||||
new_graph.add_generator(g)
|
||||
# Create inputs and outputs generators
|
||||
var gen_inputs = MMGenIOs.new()
|
||||
gen_inputs.name = "gen_inputs"
|
||||
gen_inputs.position = Vector2(left_bound-300, center.y)
|
||||
new_graph.add_generator(gen_inputs)
|
||||
var gen_outputs = MMGenIOs.new()
|
||||
gen_outputs.name = "gen_outputs"
|
||||
gen_outputs.position = Vector2(right_bound+300, center.y)
|
||||
new_graph.add_generator(gen_outputs)
|
||||
# Process connections
|
||||
var new_graph_connections = []
|
||||
var my_new_connections = []
|
||||
var gen_inputs = null
|
||||
var gen_outputs = null
|
||||
var inputs = []
|
||||
var outputs = []
|
||||
for c in connections:
|
||||
@ -194,11 +217,6 @@ func create_subgraph(gens) -> void:
|
||||
if port_index == -1:
|
||||
port_index = outputs.size()
|
||||
outputs.push_back(src_name)
|
||||
if gen_outputs == null:
|
||||
gen_outputs = MMGenIOs.new()
|
||||
gen_outputs.name = "gen_outputs"
|
||||
gen_outputs.position = Vector2(right_bound+300, center.y)
|
||||
new_graph.add_generator(gen_outputs)
|
||||
gen_outputs.ports.push_back( { name="port"+str(port_index), type="rgba" } )
|
||||
print(gen_outputs.ports)
|
||||
my_new_connections.push_back( { from=new_graph.name, from_port=port_index, to=c.to, to_port=c.to_port } )
|
||||
@ -208,11 +226,6 @@ func create_subgraph(gens) -> void:
|
||||
if port_index == -1:
|
||||
port_index = inputs.size()
|
||||
inputs.push_back(src_name)
|
||||
if gen_inputs == null:
|
||||
gen_inputs = MMGenIOs.new()
|
||||
gen_inputs.name = "gen_inputs"
|
||||
gen_inputs.position = Vector2(left_bound-300, center.y)
|
||||
new_graph.add_generator(gen_inputs)
|
||||
gen_inputs.ports.push_back( { name="port"+str(port_index), type="rgba" } )
|
||||
my_new_connections.push_back( { from=c.from, from_port=c.from_port, to=new_graph.name, to_port=port_index } )
|
||||
new_graph_connections.push_back( { from="gen_inputs", from_port=port_index, to=c.to, to_port=c.to_port } )
|
||||
@ -220,7 +233,18 @@ func create_subgraph(gens) -> void:
|
||||
my_new_connections.push_back(c)
|
||||
connections = my_new_connections
|
||||
new_graph.connections = new_graph_connections
|
||||
var found_remote = false
|
||||
var remote_script = load("res://addons/material_maker/engine/gen_remote.gd")
|
||||
for g in generators:
|
||||
if g.get_script() == load("res://addons/material_maker/engine/gen_remote.gd"):
|
||||
if g.get_script() == remote_script:
|
||||
g.name = "gen_parameters"
|
||||
found_remote = true
|
||||
new_graph.parameters = g.parameters.duplicate(true)
|
||||
break
|
||||
if !found_remote:
|
||||
var gen_parameters = remote_script.new()
|
||||
gen_parameters.name = "gen_parameters"
|
||||
gen_parameters.position = Vector2(center.x - 200, upper_bound-300)
|
||||
new_graph.add_child(gen_parameters)
|
||||
fix_remotes()
|
||||
new_graph.fix_remotes()
|
||||
|
@ -8,6 +8,9 @@ IOs just forward their inputs to their outputs and are used to specify graph int
|
||||
|
||||
var ports : Array = []
|
||||
|
||||
func can_be_deleted() -> bool:
|
||||
return name != "gen_inputs" and name != "gen_outputs"
|
||||
|
||||
func get_type() -> String:
|
||||
return "ios"
|
||||
|
||||
|
@ -6,16 +6,67 @@ class_name MMGenRemote
|
||||
Remote can be used to control parameters from several generators in the same graph
|
||||
"""
|
||||
|
||||
var widgets = null
|
||||
var widgets = []
|
||||
|
||||
func set_widgets(w) -> void:
|
||||
func can_be_deleted() -> bool:
|
||||
return name != "gen_parameters"
|
||||
|
||||
func set_widgets(w : Array) -> void:
|
||||
widgets = w
|
||||
fix()
|
||||
|
||||
func get_widget(n : String) -> Dictionary:
|
||||
for w in widgets:
|
||||
if w.name == n:
|
||||
return w
|
||||
return {}
|
||||
|
||||
func get_next_widget_name():
|
||||
var i = 0
|
||||
while true:
|
||||
var param_name = "param"+str(i)
|
||||
var used = false
|
||||
for w in widgets:
|
||||
if w.has("name") and w.name == param_name:
|
||||
used = true
|
||||
break
|
||||
if !used:
|
||||
return param_name
|
||||
i += 1
|
||||
|
||||
func fix() -> void:
|
||||
# Make sure all widgets have a name
|
||||
var i = 0
|
||||
for w in widgets:
|
||||
var param_name = "param"+str(i)
|
||||
if !parameters.has(param_name):
|
||||
parameters[param_name] = 0
|
||||
i += 1
|
||||
if !w.has("name"):
|
||||
w.name = get_next_widget_name()
|
||||
print("Named "+w.name)
|
||||
var parent = get_parent()
|
||||
if parent == null:
|
||||
return
|
||||
var updated_widgets : Array = []
|
||||
var removed_widgets = false
|
||||
for w in widgets:
|
||||
var updated_linked_widgets : Array = []
|
||||
for l in w.linked_widgets:
|
||||
var linked_widget : MMGenBase = parent.get_node(l.node)
|
||||
if linked_widget != null and linked_widget.get_parameter_def(l.widget).size() > 0:
|
||||
updated_linked_widgets.push_back(l)
|
||||
if updated_linked_widgets.size() == 0:
|
||||
removed_widgets = true
|
||||
continue
|
||||
w.linked_widgets = updated_linked_widgets
|
||||
updated_widgets.push_back(w)
|
||||
if !parameters.has(w.name):
|
||||
match w.type:
|
||||
"config_control":
|
||||
parameters[w.name] = 0
|
||||
"linked_control":
|
||||
# Should get current value of a linked widget
|
||||
parameters[w.name] = 0
|
||||
if removed_widgets:
|
||||
widgets = updated_widgets
|
||||
emit_signal("parameter_changed", "__update_all__", null)
|
||||
|
||||
func get_type() -> String:
|
||||
return "remote"
|
||||
@ -29,7 +80,7 @@ func get_parameter_defs() -> Array:
|
||||
for w in widgets:
|
||||
match w.type:
|
||||
"config_control":
|
||||
var p = { name="param"+str(i), label=w.label, type="enum", values=[] }
|
||||
var p : Dictionary = { name=w.name, label=w.label, type="enum", values=[] }
|
||||
var configurations = w.configurations.keys()
|
||||
configurations.sort()
|
||||
for c in configurations:
|
||||
@ -38,7 +89,7 @@ func get_parameter_defs() -> Array:
|
||||
i += 1
|
||||
"linked_control":
|
||||
var linked = w.linked_widgets[0]
|
||||
var p = {}
|
||||
var p : Dictionary
|
||||
if linked != null && is_inside_tree():
|
||||
var gen = get_parent().get_node(linked.node)
|
||||
if gen != null:
|
||||
@ -47,26 +98,19 @@ func get_parameter_defs() -> Array:
|
||||
if pd.name == linked.widget:
|
||||
p = pd.duplicate(true)
|
||||
break
|
||||
p.name = "param"+str(i)
|
||||
p.name = w.name
|
||||
p.label = w.label
|
||||
rv.append(p)
|
||||
i += 1
|
||||
_:
|
||||
print(w.type)
|
||||
print("Unsupported widget of type "+str(w.type))
|
||||
return rv
|
||||
|
||||
func set_parameter(p : String, v) -> void:
|
||||
var parent = get_parent()
|
||||
if parent == null:
|
||||
return
|
||||
var param_index_str : String = p.trim_prefix("param")
|
||||
if !param_index_str.is_valid_integer():
|
||||
return
|
||||
var param_index : int = param_index_str.to_int()
|
||||
if param_index >= widgets.size():
|
||||
return
|
||||
print("Setting "+p+" to "+str(v))
|
||||
var widget = widgets[param_index]
|
||||
var widget = get_widget(p)
|
||||
match widget.type:
|
||||
"linked_control":
|
||||
for w in widget.linked_widgets:
|
||||
@ -92,52 +136,70 @@ func _serialize(data: Dictionary) -> Dictionary:
|
||||
data.widgets = widgets
|
||||
return data
|
||||
|
||||
func create_linked_control(label) -> int:
|
||||
var index = widgets.size()
|
||||
widgets.push_back({ label=label, type="linked_control", linked_widgets=[] })
|
||||
return index
|
||||
func create_linked_control(label : String) -> String:
|
||||
var n = get_next_widget_name()
|
||||
widgets.push_back({ name=n, label=label, type="linked_control", linked_widgets=[] })
|
||||
return n
|
||||
|
||||
func create_config_control(label) -> int:
|
||||
var index = widgets.size()
|
||||
widgets.push_back({ label=label, type="config_control", linked_widgets=[], configurations={} })
|
||||
return index
|
||||
func create_config_control(label : String) -> String:
|
||||
var n = get_next_widget_name()
|
||||
widgets.push_back({ name=n, label=label, type="config_control", linked_widgets=[], configurations={} })
|
||||
return n
|
||||
|
||||
func set_label(index, new_label) -> void:
|
||||
widgets[index].label = new_label
|
||||
func set_label(widget_name : String, new_label : String) -> void:
|
||||
get_widget(widget_name).label = new_label
|
||||
|
||||
func can_link_parameter(index, generator, param) -> bool:
|
||||
func can_link_parameter(widget_name : String, generator : MMGenBase, param : String) -> bool:
|
||||
var widget : Dictionary = get_widget(widget_name)
|
||||
if !widget.linked_widgets.empty():
|
||||
# Check if the param is already linked
|
||||
for lw in widget.linked_widgets:
|
||||
if lw.node == generator.name and lw.widget == param:
|
||||
return false
|
||||
# Check the parameter type
|
||||
var linked : Dictionary = widget.linked_widgets[0]
|
||||
var linked_generator : MMGenBase = get_parent().get_node(linked.node)
|
||||
var linked_parameter : Dictionary = linked_generator.get_parameter_def(linked.widget)
|
||||
var parameter : Dictionary = generator.get_parameter_def(param)
|
||||
if parameter.type != linked_parameter.type:
|
||||
return false
|
||||
match parameter.type:
|
||||
"enum":
|
||||
if to_json(linked_parameter.values) != to_json(parameter.values):
|
||||
return false
|
||||
return true
|
||||
|
||||
func link_parameter(index, generator, param) -> void:
|
||||
if !can_link_parameter(index, generator, param):
|
||||
func link_parameter(widget_name : String, generator : MMGenBase, param : String) -> void:
|
||||
if !can_link_parameter(widget_name, generator, param):
|
||||
return
|
||||
var widget = widgets[index]
|
||||
var widget : Dictionary = get_widget(widget_name)
|
||||
widget.linked_widgets.push_back({ node=generator.name, widget=param })
|
||||
if widget.linked_widgets.size() == 1:
|
||||
match widget.type:
|
||||
"linked_control":
|
||||
parameters["param"+str(index)] = generator.parameters[param]
|
||||
parameters[widget_name] = generator.parameters[param]
|
||||
"config_control":
|
||||
parameters["param"+str(index)] = 0
|
||||
emit_signal("parameter_changed", "", null)
|
||||
parameters[widget_name] = 0
|
||||
emit_signal("parameter_changed", "__update_all__", null)
|
||||
|
||||
func remove_parameter(index) -> void:
|
||||
for i in range(index, widgets.size()-2):
|
||||
parameters["param"+str(i)] = parameters["param"+str(i+1)]
|
||||
widgets.remove(index)
|
||||
emit_signal("parameter_changed", "", null)
|
||||
func remove_parameter(widget_name : String) -> void:
|
||||
for i in range(widgets.size()):
|
||||
if widgets[i].name == widget_name:
|
||||
widgets.remove(i)
|
||||
break
|
||||
emit_signal("parameter_changed", "__update_all__", null)
|
||||
|
||||
func add_configuration(index, config_name) -> void:
|
||||
var widget = widgets[index]
|
||||
func add_configuration(widget_name : String, config_name : String) -> void:
|
||||
var widget = get_widget(widget_name)
|
||||
if widget.type == "config_control":
|
||||
widget.configurations[config_name] = []
|
||||
var configurations = widget.configurations.keys()
|
||||
configurations.sort()
|
||||
parameters["param"+str(index)] =configurations.find(config_name)
|
||||
update_configuration(index, config_name)
|
||||
parameters[widget.name] = configurations.find(config_name)
|
||||
update_configuration(widget_name, config_name)
|
||||
|
||||
func update_configuration(index, config_name) -> void:
|
||||
var widget = widgets[index]
|
||||
func update_configuration(widget_name : String, config_name : String) -> void:
|
||||
var widget = get_widget(widget_name)
|
||||
if widget.type == "config_control":
|
||||
var c = []
|
||||
var parent = get_parent()
|
||||
@ -147,10 +209,10 @@ func update_configuration(index, config_name) -> void:
|
||||
var value = MMType.serialize_value(g.parameters[w.widget])
|
||||
c.push_back({ node=w.node, widget=w.widget, value=value })
|
||||
widget.configurations[config_name] = c
|
||||
emit_signal("parameter_changed", "", null)
|
||||
emit_signal("parameter_changed", "__update_all__", null)
|
||||
|
||||
func remove_configuration(index, config_name) -> void:
|
||||
var widget = widgets[index]
|
||||
func remove_configuration(widget_name : String, config_name : String) -> void:
|
||||
var widget = get_widget(widget_name)
|
||||
if widget.type == "config_control":
|
||||
widget.configurations.erase(config_name)
|
||||
emit_signal("parameter_changed", "", null)
|
||||
emit_signal("parameter_changed", "__update_all__", null)
|
||||
|
@ -120,6 +120,7 @@ static func create_gen(data) -> MMGenBase:
|
||||
for p in generator.get_parameter_defs():
|
||||
if data.has(p.name):
|
||||
generator.set_parameter(p.name, MMType.deserialize_value(data[p.name]))
|
||||
generator._post_load()
|
||||
return generator
|
||||
|
||||
static func get_generator_list() -> Array:
|
||||
|
@ -143,7 +143,7 @@ func update_graph(generators, connections) -> Array:
|
||||
func new_material() -> void:
|
||||
clear_material()
|
||||
var loader = MMGenLoader.new()
|
||||
top_generator = loader.create_gen({nodes=[{name="Material", type="material"}], connections=[]})
|
||||
top_generator = loader.create_gen({nodes=[{name="Material", type="material","parameters":{"size":11}}], connections=[]})
|
||||
if top_generator != null:
|
||||
add_child(top_generator)
|
||||
update_view(top_generator)
|
||||
|
@ -59,8 +59,8 @@ 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 image_path.left(6) == "res://":
|
||||
return load(image_path) as ImageTexture
|
||||
if false && image_path.left(6) == "res://":
|
||||
t = load(image_path) as ImageTexture
|
||||
else:
|
||||
t = ImageTexture.new()
|
||||
var image : Image = Image.new()
|
||||
@ -110,19 +110,22 @@ func add_item(item, item_name, item_icon = null, item_parent = null, force_expan
|
||||
new_parent.set_text(0, prefix)
|
||||
return add_item(item, suffix, item_icon, new_parent, force_expand)
|
||||
|
||||
func serialize_library(array, library_name = null, item = null) -> void:
|
||||
func serialize_library(array : Array, library_name : String = "", item : TreeItem = null) -> void:
|
||||
if item == null:
|
||||
item = tree.get_root()
|
||||
item = item.get_children()
|
||||
while item != null:
|
||||
var m = item.get_metadata(0)
|
||||
if m != null and (library_name == null or (m.has("library") and m.library == library_name)):
|
||||
array.append(m)
|
||||
if item.get_metadata(0) != null:
|
||||
var m : Dictionary = item.get_metadata(0)
|
||||
if library_name == "" or (m.has("library") and m.library == library_name):
|
||||
var copy : Dictionary = m.duplicate()
|
||||
copy.erase("library")
|
||||
array.append(copy)
|
||||
serialize_library(array, library_name, item)
|
||||
item = item.get_next()
|
||||
|
||||
func save_library(library_name, item = null) -> void:
|
||||
var array = []
|
||||
func save_library(library_name : String, item : TreeItem = null) -> void:
|
||||
var array : Array = []
|
||||
serialize_library(array, library_name)
|
||||
var file = File.new()
|
||||
if file.open(library_name, File.WRITE) == OK:
|
||||
|
@ -23,17 +23,20 @@ const MENU = [
|
||||
{ menu="File" },
|
||||
{ menu="File", command="close_material", description="Close material" },
|
||||
{ menu="File", command="quit", shortcut="Control+Q", description="Quit" },
|
||||
|
||||
{ menu="Edit", command="edit_cut", shortcut="Control+X", description="Cut" },
|
||||
{ menu="Edit", command="edit_copy", shortcut="Control+C", description="Copy" },
|
||||
{ menu="Edit", command="edit_paste", shortcut="Control+V", description="Paste" },
|
||||
|
||||
{ menu="View", command="view_center", shortcut="C", description="Center view" },
|
||||
{ menu="View", command="view_reset_zoom", shortcut="Control+0", description="Reset zoom" },
|
||||
|
||||
{ menu="Tools", submenu="create", description="Create" },
|
||||
{ menu="Tools", command="create_subgraph", shortcut="Control+G", description="Create group" },
|
||||
{ menu="Tools", command="make_selected_nodes_editable", shortcut="Control+E", description="Make selected nodes editable" },
|
||||
{ menu="Tools" },
|
||||
{ menu="Tools", command="add_to_user_library", description="Add selected node to user library" },
|
||||
{ menu="Tools", command="save_user_library", description="Save user library" },
|
||||
|
||||
{ menu="Help", command="show_doc", description="User manual" },
|
||||
{ menu="Help", command="bug_report", description="Report a bug" },
|
||||
{ menu="Help" },
|
||||
@ -346,9 +349,6 @@ func do_add_to_user_library(name, nodes) -> void:
|
||||
result.save_to_file("user://library/user/"+data.icon+".png")
|
||||
result.release()
|
||||
library.add_item(data, name, library.get_preview_texture(data))
|
||||
|
||||
func save_user_library() -> void:
|
||||
print("Saving user library")
|
||||
library.save_library("user://library/user.json")
|
||||
|
||||
func show_doc() -> void:
|
||||
|
Binary file not shown.
1
addons/material_maker/nodes/circle_map.mmg
Normal file
1
addons/material_maker/nodes/circle_map.mmg
Normal file
@ -0,0 +1 @@
|
||||
{"name":"circle_map","node_position":{"x":0,"y":0},"parameters":{},"shader_model":{"code":"","global":"","inputs":[{"default":"vec4($uv, 0.0, 1.0)","label":"","name":"in","type":"rgba"}],"instance":"","name":"CircleMap","outputs":[{"rgba":"$in(vec2(fract(atan($uv.y-0.5, $uv.x-0.5)*0.15915494309), min(0.99999, 2.0*length($uv-vec2(0.5)))))","type":"rgba"}],"parameters":[]},"type":"shader"}
|
@ -198,7 +198,6 @@ func update_node() -> void:
|
||||
var control : Control = Control.new()
|
||||
control.rect_min_size.y = 16
|
||||
hsizer.add_child(control)
|
||||
|
||||
add_child(hsizer)
|
||||
var input_names_width : int = 0
|
||||
for c in get_children():
|
||||
|
@ -1 +1 @@
|
||||
{"name":"pattern","node_position":{"x":0,"y":0},"parameters":{"mix":0,"x_scale":4,"x_wave":0,"y_scale":4,"y_wave":0},"shader_model":{"global":"float wave_constant(float x) {\n\treturn 1.0;\n}\n\nfloat wave_sine(float x) {\n\treturn 0.5-0.5*cos(3.14159265359*2.0*x);\n}\n\nfloat wave_triangle(float x) {\n\tx = fract(x);\n\treturn min(2.0*x, 2.0-2.0*x);\n}\n\nfloat wave_sawtooth(float x) {\n\treturn fract(x);\n}\n\nfloat wave_square(float x) {\n\treturn (fract(x) < 0.5) ? 0.0 : 1.0;\n}\n\nfloat mix_mul(float x, float y) {\n\treturn x*y;\n}\n\nfloat mix_add(float x, float y) {\n\treturn min(x+y, 1.0);\n}\n\nfloat mix_max(float x, float y) {\n\treturn max(x, y);\n}\n\nfloat mix_min(float x, float y) {\n\treturn min(x, y);\n}\n\nfloat mix_xor(float x, float y) {\n\treturn min(x+y, 2.0-x-y);\n}\n\nfloat mix_pow(float x, float y) {\n\treturn pow(x, y);\n}","inputs":[],"instance":"float $(name)_fct(vec2 uv) {\n\treturn mix_$(mix)(wave_$(x_wave)($(x_scale)*uv.x), wave_$(y_wave)($(y_scale)*uv.y));\n}","name":"Pattern","outputs":[{"f":"$(name)_fct($(uv))","type":"f"}],"parameters":[{"default":0,"label":"Combiner","name":"mix","type":"enum","values":[{"name":"Multiply","value":"mul"},{"name":"Add","value":"add"},{"name":"Max","value":"max"},{"name":"Min","value":"min"},{"name":"Xor","value":"xor"},{"name":"Pow","value":"pow"}]},{"default":0,"label":"X","name":"x_wave","type":"enum","values":[{"name":"Sine","value":"sine"},{"name":"Triangle","value":"triangle"},{"name":"Square","value":"square"},{"name":"Sawtooth","value":"sawtooth"},{"name":"Constant","value":"constant"}]},{"default":4,"label":"2:","max":32,"min":0,"name":"x_scale","step":1,"type":"float","widget":"spinbox"},{"default":0,"label":"Y","name":"y_wave","type":"enum","values":[{"name":"Sine","value":"sine"},{"name":"Triangle","value":"triangle"},{"name":"Square","value":"square"},{"name":"Sawtooth","value":"sawtooth"},{"name":"Constant","value":"constant"}]},{"default":4,"label":"3:","max":32,"min":0,"name":"y_scale","step":1,"type":"float","widget":"spinbox"}]}}
|
||||
{"name":"pattern","node_position":{"x":0,"y":0},"parameters":{"mix":0,"x_scale":4,"x_wave":0,"y_scale":4,"y_wave":0},"shader_model":{"code":"","global":"float wave_constant(float x) {\n\treturn 1.0;\n}\n\nfloat wave_sine(float x) {\n\treturn 0.5-0.5*cos(3.14159265359*2.0*x);\n}\n\nfloat wave_triangle(float x) {\n\tx = fract(x);\n\treturn min(2.0*x, 2.0-2.0*x);\n}\n\nfloat wave_sawtooth(float x) {\n\treturn fract(x);\n}\n\nfloat wave_square(float x) {\n\treturn (fract(x) < 0.5) ? 0.0 : 1.0;\n}\n\nfloat wave_bounce(float x) {\n\tx = 2.0*(fract(x)-0.5);\n\treturn sqrt(1.0-x*x);\n}\n\nfloat mix_mul(float x, float y) {\n\treturn x*y;\n}\n\nfloat mix_add(float x, float y) {\n\treturn min(x+y, 1.0);\n}\n\nfloat mix_max(float x, float y) {\n\treturn max(x, y);\n}\n\nfloat mix_min(float x, float y) {\n\treturn min(x, y);\n}\n\nfloat mix_xor(float x, float y) {\n\treturn min(x+y, 2.0-x-y);\n}\n\nfloat mix_pow(float x, float y) {\n\treturn pow(x, y);\n}","inputs":[],"instance":"float $(name)_fct(vec2 uv) {\n\treturn mix_$(mix)(wave_$(x_wave)($(x_scale)*uv.x), wave_$(y_wave)($(y_scale)*uv.y));\n}","name":"Pattern","outputs":[{"f":"$(name)_fct($(uv))","type":"f"}],"parameters":[{"default":0,"label":"Combiner","name":"mix","type":"enum","values":[{"name":"Multiply","value":"mul"},{"name":"Add","value":"add"},{"name":"Max","value":"max"},{"name":"Min","value":"min"},{"name":"Xor","value":"xor"},{"name":"Pow","value":"pow"}]},{"default":5,"label":"X","name":"x_wave","type":"enum","values":[{"name":"Sine","value":"sine"},{"name":"Triangle","value":"triangle"},{"name":"Square","value":"square"},{"name":"Sawtooth","value":"sawtooth"},{"name":"Constant","value":"constant"},{"name":"Bounce","value":"bounce"}]},{"default":4,"label":"2:","max":32,"min":0,"name":"x_scale","step":1,"type":"float","widget":"spinbox"},{"default":5,"label":"Y","name":"y_wave","type":"enum","values":[{"name":"Sine","value":"sine"},{"name":"Triangle","value":"triangle"},{"name":"Square","value":"square"},{"name":"Sawtooth","value":"sawtooth"},{"name":"Constant","value":"constant"},{"name":"Bounce","value":"bounce"}]},{"default":4,"label":"3:","max":32,"min":0,"name":"y_scale","step":1,"type":"float","widget":"spinbox"}]},"type":"shader"}
|
@ -10,7 +10,7 @@ func add_control(text, control) -> void:
|
||||
var index = grid.get_child_count() / 4
|
||||
var label = preload("res://addons/material_maker/widgets/linked_widgets/editable_label.tscn").instance()
|
||||
label.set_text(text)
|
||||
label.connect("label_changed", self, "on_label_changed", [ index ])
|
||||
label.connect("label_changed", self, "on_label_changed", [ control.name ])
|
||||
grid.add_child(label)
|
||||
grid.add_child(control)
|
||||
control.connect("mouse_entered", self, "on_enter_widget", [ control ])
|
||||
@ -18,13 +18,16 @@ func add_control(text, control) -> void:
|
||||
var button = Button.new()
|
||||
button.icon = preload("res://addons/material_maker/icons/link.tres")
|
||||
grid.add_child(button)
|
||||
button.connect("pressed", self, "_on_Link_pressed", [ index ])
|
||||
button.connect("pressed", self, "_on_Link_pressed", [ control.name ])
|
||||
button = Button.new()
|
||||
button.icon = preload("res://addons/material_maker/icons/remove.tres")
|
||||
grid.add_child(button)
|
||||
button.connect("pressed", generator, "remove_parameter", [ index ])
|
||||
button.connect("pressed", generator, "remove_parameter", [ control.name ])
|
||||
|
||||
func update_node() -> void:
|
||||
# Show or hide the close button
|
||||
show_close = generator.can_be_deleted()
|
||||
# Delete the contents and wait until it's done
|
||||
var i : int = 0
|
||||
for c in grid.get_children():
|
||||
c.queue_free()
|
||||
@ -36,11 +39,11 @@ func update_node() -> void:
|
||||
if control != null:
|
||||
control.name = p.name
|
||||
controls[control.name] = control
|
||||
add_control(generator.widgets[i].label, control)
|
||||
add_control(generator.get_widget(p.name).label, control)
|
||||
if generator.widgets[i].type == "config_control":
|
||||
var current = null
|
||||
if control.get_item_count() > 0:
|
||||
control.selected = generator.parameters["param"+str(i)]
|
||||
control.selected = generator.parameters[p.name]
|
||||
current = control.get_item_text(control.selected)
|
||||
control.add_separator()
|
||||
control.add_item("<add configuration>")
|
||||
@ -52,12 +55,11 @@ func update_node() -> void:
|
||||
rect_size = Vector2(0, 0)
|
||||
initialize_properties()
|
||||
|
||||
func _on_value_changed(new_value, variable) -> void:
|
||||
var param_index = variable.trim_prefix("param").to_int()
|
||||
var widget = generator.widgets[param_index]
|
||||
func _on_value_changed(new_value, variable : String) -> void:
|
||||
var widget = generator.get_widget(variable)
|
||||
if widget.type == "config_control":
|
||||
var configuration_count = widget.configurations.size()
|
||||
var control = grid.get_child(param_index*4+1)
|
||||
var control = controls[variable]
|
||||
if new_value < configuration_count:
|
||||
._on_value_changed(new_value, variable)
|
||||
var current = control.get_item_text(new_value)
|
||||
@ -71,39 +73,43 @@ func _on_value_changed(new_value, variable) -> void:
|
||||
var dialog = preload("res://addons/material_maker/widgets/line_dialog.tscn").instance()
|
||||
add_child(dialog)
|
||||
dialog.set_texts("Configuration", "Enter a name for the new configuration")
|
||||
dialog.connect("ok", self, "do_add_configuration", [ param_index ])
|
||||
dialog.connect("ok", self, "do_add_configuration", [ variable ])
|
||||
dialog.popup_centered()
|
||||
3:
|
||||
generator.update_configuration(param_index, current)
|
||||
generator.update_configuration(variable, current)
|
||||
4:
|
||||
generator.parameters[variable] = 0
|
||||
generator.remove_configuration(param_index, current)
|
||||
generator.remove_configuration(variable, current)
|
||||
_:
|
||||
print(command)
|
||||
else:
|
||||
._on_value_changed(new_value, variable)
|
||||
|
||||
func do_add_configuration(config_name, param_index) -> void:
|
||||
generator.add_configuration(param_index, config_name)
|
||||
func do_add_configuration(config_name : String, param_name : String) -> void:
|
||||
generator.add_configuration(param_name, config_name)
|
||||
|
||||
func on_label_changed(new_name, index) -> void:
|
||||
generator.set_label(index, new_name)
|
||||
func on_label_changed(new_label, param_name) -> void:
|
||||
generator.set_label(param_name, new_label)
|
||||
|
||||
func _on_AddLink_pressed() -> void:
|
||||
var control = generator.create_linked_control("Unnamed")
|
||||
var widget = Control.new()
|
||||
widget.name = control
|
||||
add_control("Unnamed", widget)
|
||||
var link = MMNodeLink.new(get_parent())
|
||||
link.pick(widget, generator, generator.create_linked_control("Unnamed"), true)
|
||||
link.pick(widget, generator, control, true)
|
||||
|
||||
func _on_AddConfig_pressed() -> void:
|
||||
var control = generator.create_config_control("Unnamed")
|
||||
var widget = Control.new()
|
||||
widget.name = control
|
||||
add_control("Unnamed", widget)
|
||||
var link = MMNodeLink.new(get_parent())
|
||||
link.pick(widget, generator, generator.create_config_control("Unnamed"), true)
|
||||
link.pick(widget, generator, control, true)
|
||||
|
||||
func _on_Link_pressed(index) -> void:
|
||||
func _on_Link_pressed(param_name) -> void:
|
||||
var link = MMNodeLink.new(get_parent())
|
||||
link.pick(grid.get_child(index*4+1), generator, index)
|
||||
link.pick(controls[param_name], generator, param_name)
|
||||
|
||||
func _on_Remote_resize_request(new_minsize) -> void:
|
||||
rect_size = new_minsize
|
||||
@ -118,8 +124,7 @@ func on_parameter_changed(p, v) -> void:
|
||||
.on_parameter_changed(p, v)
|
||||
|
||||
func on_enter_widget(widget) -> void:
|
||||
var param_index = widget.name.trim_prefix("param").to_int()
|
||||
var w = generator.widgets[param_index]
|
||||
var w = generator.get_widget(widget.name)
|
||||
var new_links = []
|
||||
for l in w.linked_widgets:
|
||||
var graph_node = get_parent().get_node("node_"+l.node)
|
||||
|
@ -7,8 +7,8 @@ var source = null
|
||||
var target = null
|
||||
|
||||
var generator = null
|
||||
var param_index = 0
|
||||
var creating = false
|
||||
var param_name : String = ""
|
||||
var creating : bool = false
|
||||
|
||||
func _init(parent) -> void:
|
||||
size_flags_horizontal = SIZE_EXPAND_FILL
|
||||
@ -17,11 +17,11 @@ func _init(parent) -> void:
|
||||
rect_clip_content = true
|
||||
parent.add_child(self)
|
||||
|
||||
func pick(s, g, i, c = false) -> void:
|
||||
func pick(s, g, n : String, c : bool = false) -> void:
|
||||
source = s
|
||||
end = get_global_transform().xform_inv(source.get_global_transform().xform(0.5*source.rect_size))
|
||||
generator = g
|
||||
param_index = i
|
||||
param_name = n
|
||||
creating = c
|
||||
set_process_input(true)
|
||||
|
||||
@ -69,16 +69,16 @@ func _input(event: InputEvent) -> void:
|
||||
elif event is InputEventMouseMotion:
|
||||
var control = find_control(event.global_position)
|
||||
end = get_global_transform().xform_inv(event.global_position)
|
||||
target = control.widget if control != null and generator.can_link_parameter(param_index, control.node.generator, control.widget.name) else null
|
||||
target = control.widget if control != null and generator.can_link_parameter(param_name, control.node.generator, control.widget.name) else null
|
||||
update()
|
||||
elif event is InputEventMouseButton:
|
||||
if event.pressed:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
var control = find_control(event.global_position)
|
||||
if control != null:
|
||||
generator.link_parameter(param_index, control.node.generator, control.widget.name)
|
||||
generator.link_parameter(param_name, control.node.generator, control.widget.name)
|
||||
elif creating:
|
||||
generator.remove_parameter(param_index)
|
||||
generator.remove_parameter(param_name)
|
||||
set_process_input(false)
|
||||
queue_free()
|
||||
get_tree().set_input_as_handled()
|
||||
|
Loading…
Reference in New Issue
Block a user