mirror of
https://github.com/Relintai/material-maker.git
synced 2024-12-23 21:16:54 +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:
|
func _ready() -> void:
|
||||||
init_parameters()
|
init_parameters()
|
||||||
|
|
||||||
|
func _post_load() -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
func can_be_deleted() -> bool:
|
func can_be_deleted() -> bool:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
@ -68,6 +71,13 @@ func get_type_name() -> String:
|
|||||||
func get_parameter_defs() -> Array:
|
func get_parameter_defs() -> Array:
|
||||||
return []
|
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):
|
func set_parameter(n : String, v):
|
||||||
parameters[n] = v
|
parameters[n] = v
|
||||||
source_changed(0)
|
source_changed(0)
|
||||||
|
@ -7,6 +7,13 @@ var connections = []
|
|||||||
|
|
||||||
var editable = false
|
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:
|
func get_type() -> String:
|
||||||
return "graph"
|
return "graph"
|
||||||
@ -87,6 +94,9 @@ func remove_generator(generator : MMGenBase) -> void:
|
|||||||
if c.from != generator.name and c.to != generator.name:
|
if c.from != generator.name and c.to != generator.name:
|
||||||
new_connections.append(c)
|
new_connections.append(c)
|
||||||
connections = new_connections
|
connections = new_connections
|
||||||
|
remove_child(generator)
|
||||||
|
fix_remotes()
|
||||||
|
add_child(generator)
|
||||||
generator.queue_free()
|
generator.queue_free()
|
||||||
|
|
||||||
func replace_generator(old : MMGenBase, new : MMGenBase) -> void:
|
func replace_generator(old : MMGenBase, new : MMGenBase) -> void:
|
||||||
@ -152,13 +162,15 @@ func _serialize(data: Dictionary) -> Dictionary:
|
|||||||
func edit(node) -> void:
|
func edit(node) -> void:
|
||||||
node.get_parent().call_deferred("update_view", self)
|
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
|
# Remove material, gen_inputs and gen_outputs nodes
|
||||||
var generators = []
|
var generators = []
|
||||||
var center = Vector2(0, 0)
|
var center = Vector2(0, 0)
|
||||||
var left_bound = 65535
|
var left_bound = 65535
|
||||||
var right_bound = -65536
|
var right_bound = -65536
|
||||||
|
var upper_bound = 65536
|
||||||
var count = 0
|
var count = 0
|
||||||
|
# Filter group nodes and calculate boundin box
|
||||||
for g in gens:
|
for g in gens:
|
||||||
if g.name != "Material" and g.name != "gen_inputs" and g.name != "gen_outputs":
|
if g.name != "Material" and g.name != "gen_inputs" and g.name != "gen_outputs":
|
||||||
generators.push_back(g)
|
generators.push_back(g)
|
||||||
@ -167,22 +179,33 @@ func create_subgraph(gens) -> void:
|
|||||||
count += 1
|
count += 1
|
||||||
if left_bound > p.x: left_bound = p.x
|
if left_bound > p.x: left_bound = p.x
|
||||||
if right_bound < p.x: right_bound = p.x
|
if right_bound < p.x: right_bound = p.x
|
||||||
|
if upper_bound > p.y: upper_bound = p.y
|
||||||
if count == 0:
|
if count == 0:
|
||||||
return
|
return
|
||||||
center /= count
|
center /= count
|
||||||
|
# Create a new graph and add it to the current one
|
||||||
var new_graph = get_script().new()
|
var new_graph = get_script().new()
|
||||||
new_graph.name = "graph"
|
new_graph.name = "graph"
|
||||||
add_generator(new_graph)
|
add_generator(new_graph)
|
||||||
new_graph.position = center
|
new_graph.position = center
|
||||||
|
# Add grouped generators and keep their names
|
||||||
var names : Array = []
|
var names : Array = []
|
||||||
for g in generators:
|
for g in generators:
|
||||||
names.push_back(g.name)
|
names.push_back(g.name)
|
||||||
remove_child(g)
|
remove_child(g)
|
||||||
new_graph.add_generator(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 new_graph_connections = []
|
||||||
var my_new_connections = []
|
var my_new_connections = []
|
||||||
var gen_inputs = null
|
|
||||||
var gen_outputs = null
|
|
||||||
var inputs = []
|
var inputs = []
|
||||||
var outputs = []
|
var outputs = []
|
||||||
for c in connections:
|
for c in connections:
|
||||||
@ -194,11 +217,6 @@ func create_subgraph(gens) -> void:
|
|||||||
if port_index == -1:
|
if port_index == -1:
|
||||||
port_index = outputs.size()
|
port_index = outputs.size()
|
||||||
outputs.push_back(src_name)
|
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" } )
|
gen_outputs.ports.push_back( { name="port"+str(port_index), type="rgba" } )
|
||||||
print(gen_outputs.ports)
|
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 } )
|
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:
|
if port_index == -1:
|
||||||
port_index = inputs.size()
|
port_index = inputs.size()
|
||||||
inputs.push_back(src_name)
|
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" } )
|
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 } )
|
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 } )
|
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)
|
my_new_connections.push_back(c)
|
||||||
connections = my_new_connections
|
connections = my_new_connections
|
||||||
new_graph.connections = new_graph_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:
|
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"
|
g.name = "gen_parameters"
|
||||||
|
found_remote = true
|
||||||
|
new_graph.parameters = g.parameters.duplicate(true)
|
||||||
break
|
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 = []
|
var ports : Array = []
|
||||||
|
|
||||||
|
func can_be_deleted() -> bool:
|
||||||
|
return name != "gen_inputs" and name != "gen_outputs"
|
||||||
|
|
||||||
func get_type() -> String:
|
func get_type() -> String:
|
||||||
return "ios"
|
return "ios"
|
||||||
|
|
||||||
|
@ -6,16 +6,67 @@ class_name MMGenRemote
|
|||||||
Remote can be used to control parameters from several generators in the same graph
|
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
|
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
|
var i = 0
|
||||||
for w in widgets:
|
for w in widgets:
|
||||||
var param_name = "param"+str(i)
|
if !w.has("name"):
|
||||||
if !parameters.has(param_name):
|
w.name = get_next_widget_name()
|
||||||
parameters[param_name] = 0
|
print("Named "+w.name)
|
||||||
i += 1
|
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:
|
func get_type() -> String:
|
||||||
return "remote"
|
return "remote"
|
||||||
@ -29,7 +80,7 @@ func get_parameter_defs() -> Array:
|
|||||||
for w in widgets:
|
for w in widgets:
|
||||||
match w.type:
|
match w.type:
|
||||||
"config_control":
|
"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()
|
var configurations = w.configurations.keys()
|
||||||
configurations.sort()
|
configurations.sort()
|
||||||
for c in configurations:
|
for c in configurations:
|
||||||
@ -38,7 +89,7 @@ func get_parameter_defs() -> Array:
|
|||||||
i += 1
|
i += 1
|
||||||
"linked_control":
|
"linked_control":
|
||||||
var linked = w.linked_widgets[0]
|
var linked = w.linked_widgets[0]
|
||||||
var p = {}
|
var p : Dictionary
|
||||||
if linked != null && is_inside_tree():
|
if linked != null && is_inside_tree():
|
||||||
var gen = get_parent().get_node(linked.node)
|
var gen = get_parent().get_node(linked.node)
|
||||||
if gen != null:
|
if gen != null:
|
||||||
@ -47,26 +98,19 @@ func get_parameter_defs() -> Array:
|
|||||||
if pd.name == linked.widget:
|
if pd.name == linked.widget:
|
||||||
p = pd.duplicate(true)
|
p = pd.duplicate(true)
|
||||||
break
|
break
|
||||||
p.name = "param"+str(i)
|
p.name = w.name
|
||||||
p.label = w.label
|
p.label = w.label
|
||||||
rv.append(p)
|
rv.append(p)
|
||||||
i += 1
|
i += 1
|
||||||
_:
|
_:
|
||||||
print(w.type)
|
print("Unsupported widget of type "+str(w.type))
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
func set_parameter(p : String, v) -> void:
|
func set_parameter(p : String, v) -> void:
|
||||||
var parent = get_parent()
|
var parent = get_parent()
|
||||||
if parent == null:
|
if parent == null:
|
||||||
return
|
return
|
||||||
var param_index_str : String = p.trim_prefix("param")
|
var widget = get_widget(p)
|
||||||
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]
|
|
||||||
match widget.type:
|
match widget.type:
|
||||||
"linked_control":
|
"linked_control":
|
||||||
for w in widget.linked_widgets:
|
for w in widget.linked_widgets:
|
||||||
@ -92,52 +136,70 @@ func _serialize(data: Dictionary) -> Dictionary:
|
|||||||
data.widgets = widgets
|
data.widgets = widgets
|
||||||
return data
|
return data
|
||||||
|
|
||||||
func create_linked_control(label) -> int:
|
func create_linked_control(label : String) -> String:
|
||||||
var index = widgets.size()
|
var n = get_next_widget_name()
|
||||||
widgets.push_back({ label=label, type="linked_control", linked_widgets=[] })
|
widgets.push_back({ name=n, label=label, type="linked_control", linked_widgets=[] })
|
||||||
return index
|
return n
|
||||||
|
|
||||||
func create_config_control(label) -> int:
|
func create_config_control(label : String) -> String:
|
||||||
var index = widgets.size()
|
var n = get_next_widget_name()
|
||||||
widgets.push_back({ label=label, type="config_control", linked_widgets=[], configurations={} })
|
widgets.push_back({ name=n, label=label, type="config_control", linked_widgets=[], configurations={} })
|
||||||
return index
|
return n
|
||||||
|
|
||||||
func set_label(index, new_label) -> void:
|
func set_label(widget_name : String, new_label : String) -> void:
|
||||||
widgets[index].label = new_label
|
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
|
return true
|
||||||
|
|
||||||
func link_parameter(index, generator, param) -> void:
|
func link_parameter(widget_name : String, generator : MMGenBase, param : String) -> void:
|
||||||
if !can_link_parameter(index, generator, param):
|
if !can_link_parameter(widget_name, generator, param):
|
||||||
return
|
return
|
||||||
var widget = widgets[index]
|
var widget : Dictionary = get_widget(widget_name)
|
||||||
widget.linked_widgets.push_back({ node=generator.name, widget=param })
|
widget.linked_widgets.push_back({ node=generator.name, widget=param })
|
||||||
if widget.linked_widgets.size() == 1:
|
if widget.linked_widgets.size() == 1:
|
||||||
match widget.type:
|
match widget.type:
|
||||||
"linked_control":
|
"linked_control":
|
||||||
parameters["param"+str(index)] = generator.parameters[param]
|
parameters[widget_name] = generator.parameters[param]
|
||||||
"config_control":
|
"config_control":
|
||||||
parameters["param"+str(index)] = 0
|
parameters[widget_name] = 0
|
||||||
emit_signal("parameter_changed", "", null)
|
emit_signal("parameter_changed", "__update_all__", null)
|
||||||
|
|
||||||
func remove_parameter(index) -> void:
|
func remove_parameter(widget_name : String) -> void:
|
||||||
for i in range(index, widgets.size()-2):
|
for i in range(widgets.size()):
|
||||||
parameters["param"+str(i)] = parameters["param"+str(i+1)]
|
if widgets[i].name == widget_name:
|
||||||
widgets.remove(index)
|
widgets.remove(i)
|
||||||
emit_signal("parameter_changed", "", null)
|
break
|
||||||
|
emit_signal("parameter_changed", "__update_all__", null)
|
||||||
|
|
||||||
func add_configuration(index, config_name) -> void:
|
func add_configuration(widget_name : String, config_name : String) -> void:
|
||||||
var widget = widgets[index]
|
var widget = get_widget(widget_name)
|
||||||
if widget.type == "config_control":
|
if widget.type == "config_control":
|
||||||
widget.configurations[config_name] = []
|
widget.configurations[config_name] = []
|
||||||
var configurations = widget.configurations.keys()
|
var configurations = widget.configurations.keys()
|
||||||
configurations.sort()
|
configurations.sort()
|
||||||
parameters["param"+str(index)] =configurations.find(config_name)
|
parameters[widget.name] = configurations.find(config_name)
|
||||||
update_configuration(index, config_name)
|
update_configuration(widget_name, config_name)
|
||||||
|
|
||||||
func update_configuration(index, config_name) -> void:
|
func update_configuration(widget_name : String, config_name : String) -> void:
|
||||||
var widget = widgets[index]
|
var widget = get_widget(widget_name)
|
||||||
if widget.type == "config_control":
|
if widget.type == "config_control":
|
||||||
var c = []
|
var c = []
|
||||||
var parent = get_parent()
|
var parent = get_parent()
|
||||||
@ -147,10 +209,10 @@ func update_configuration(index, config_name) -> void:
|
|||||||
var value = MMType.serialize_value(g.parameters[w.widget])
|
var value = MMType.serialize_value(g.parameters[w.widget])
|
||||||
c.push_back({ node=w.node, widget=w.widget, value=value })
|
c.push_back({ node=w.node, widget=w.widget, value=value })
|
||||||
widget.configurations[config_name] = c
|
widget.configurations[config_name] = c
|
||||||
emit_signal("parameter_changed", "", null)
|
emit_signal("parameter_changed", "__update_all__", null)
|
||||||
|
|
||||||
func remove_configuration(index, config_name) -> void:
|
func remove_configuration(widget_name : String, config_name : String) -> void:
|
||||||
var widget = widgets[index]
|
var widget = get_widget(widget_name)
|
||||||
if widget.type == "config_control":
|
if widget.type == "config_control":
|
||||||
widget.configurations.erase(config_name)
|
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():
|
for p in generator.get_parameter_defs():
|
||||||
if data.has(p.name):
|
if data.has(p.name):
|
||||||
generator.set_parameter(p.name, MMType.deserialize_value(data[p.name]))
|
generator.set_parameter(p.name, MMType.deserialize_value(data[p.name]))
|
||||||
|
generator._post_load()
|
||||||
return generator
|
return generator
|
||||||
|
|
||||||
static func get_generator_list() -> Array:
|
static func get_generator_list() -> Array:
|
||||||
|
@ -143,7 +143,7 @@ func update_graph(generators, connections) -> Array:
|
|||||||
func new_material() -> void:
|
func new_material() -> void:
|
||||||
clear_material()
|
clear_material()
|
||||||
var loader = MMGenLoader.new()
|
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:
|
if top_generator != null:
|
||||||
add_child(top_generator)
|
add_child(top_generator)
|
||||||
update_view(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"):
|
if data.has("icon") and data.has("library"):
|
||||||
var image_path = data.library.left(data.library.rfind("."))+"/"+data.icon+".png"
|
var image_path = data.library.left(data.library.rfind("."))+"/"+data.icon+".png"
|
||||||
var t : ImageTexture
|
var t : ImageTexture
|
||||||
if image_path.left(6) == "res://":
|
if false && image_path.left(6) == "res://":
|
||||||
return load(image_path) as ImageTexture
|
t = load(image_path) as ImageTexture
|
||||||
else:
|
else:
|
||||||
t = ImageTexture.new()
|
t = ImageTexture.new()
|
||||||
var image : Image = Image.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)
|
new_parent.set_text(0, prefix)
|
||||||
return add_item(item, suffix, item_icon, new_parent, force_expand)
|
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:
|
if item == null:
|
||||||
item = tree.get_root()
|
item = tree.get_root()
|
||||||
item = item.get_children()
|
item = item.get_children()
|
||||||
while item != null:
|
while item != null:
|
||||||
var m = item.get_metadata(0)
|
if item.get_metadata(0) != null:
|
||||||
if m != null and (library_name == null or (m.has("library") and m.library == library_name)):
|
var m : Dictionary = item.get_metadata(0)
|
||||||
array.append(m)
|
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)
|
serialize_library(array, library_name, item)
|
||||||
item = item.get_next()
|
item = item.get_next()
|
||||||
|
|
||||||
func save_library(library_name, item = null) -> void:
|
func save_library(library_name : String, item : TreeItem = null) -> void:
|
||||||
var array = []
|
var array : Array = []
|
||||||
serialize_library(array, library_name)
|
serialize_library(array, library_name)
|
||||||
var file = File.new()
|
var file = File.new()
|
||||||
if file.open(library_name, File.WRITE) == OK:
|
if file.open(library_name, File.WRITE) == OK:
|
||||||
|
@ -23,17 +23,20 @@ const MENU = [
|
|||||||
{ menu="File" },
|
{ menu="File" },
|
||||||
{ menu="File", command="close_material", description="Close material" },
|
{ menu="File", command="close_material", description="Close material" },
|
||||||
{ menu="File", command="quit", shortcut="Control+Q", description="Quit" },
|
{ menu="File", command="quit", shortcut="Control+Q", description="Quit" },
|
||||||
|
|
||||||
{ menu="Edit", command="edit_cut", shortcut="Control+X", description="Cut" },
|
{ menu="Edit", command="edit_cut", shortcut="Control+X", description="Cut" },
|
||||||
{ menu="Edit", command="edit_copy", shortcut="Control+C", description="Copy" },
|
{ menu="Edit", command="edit_copy", shortcut="Control+C", description="Copy" },
|
||||||
{ menu="Edit", command="edit_paste", shortcut="Control+V", description="Paste" },
|
{ menu="Edit", command="edit_paste", shortcut="Control+V", description="Paste" },
|
||||||
|
|
||||||
{ menu="View", command="view_center", shortcut="C", description="Center view" },
|
{ menu="View", command="view_center", shortcut="C", description="Center view" },
|
||||||
{ menu="View", command="view_reset_zoom", shortcut="Control+0", description="Reset zoom" },
|
{ menu="View", command="view_reset_zoom", shortcut="Control+0", description="Reset zoom" },
|
||||||
|
|
||||||
{ menu="Tools", submenu="create", description="Create" },
|
{ menu="Tools", submenu="create", description="Create" },
|
||||||
{ menu="Tools", command="create_subgraph", shortcut="Control+G", description="Create group" },
|
{ 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", command="make_selected_nodes_editable", shortcut="Control+E", description="Make selected nodes editable" },
|
||||||
{ menu="Tools" },
|
{ menu="Tools" },
|
||||||
{ menu="Tools", command="add_to_user_library", description="Add selected node to user library" },
|
{ 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="show_doc", description="User manual" },
|
||||||
{ menu="Help", command="bug_report", description="Report a bug" },
|
{ menu="Help", command="bug_report", description="Report a bug" },
|
||||||
{ menu="Help" },
|
{ 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.save_to_file("user://library/user/"+data.icon+".png")
|
||||||
result.release()
|
result.release()
|
||||||
library.add_item(data, name, library.get_preview_texture(data))
|
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")
|
library.save_library("user://library/user.json")
|
||||||
|
|
||||||
func show_doc() -> void:
|
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()
|
var control : Control = Control.new()
|
||||||
control.rect_min_size.y = 16
|
control.rect_min_size.y = 16
|
||||||
hsizer.add_child(control)
|
hsizer.add_child(control)
|
||||||
|
|
||||||
add_child(hsizer)
|
add_child(hsizer)
|
||||||
var input_names_width : int = 0
|
var input_names_width : int = 0
|
||||||
for c in get_children():
|
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 index = grid.get_child_count() / 4
|
||||||
var label = preload("res://addons/material_maker/widgets/linked_widgets/editable_label.tscn").instance()
|
var label = preload("res://addons/material_maker/widgets/linked_widgets/editable_label.tscn").instance()
|
||||||
label.set_text(text)
|
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(label)
|
||||||
grid.add_child(control)
|
grid.add_child(control)
|
||||||
control.connect("mouse_entered", self, "on_enter_widget", [ control ])
|
control.connect("mouse_entered", self, "on_enter_widget", [ control ])
|
||||||
@ -18,13 +18,16 @@ func add_control(text, control) -> void:
|
|||||||
var button = Button.new()
|
var button = Button.new()
|
||||||
button.icon = preload("res://addons/material_maker/icons/link.tres")
|
button.icon = preload("res://addons/material_maker/icons/link.tres")
|
||||||
grid.add_child(button)
|
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 = Button.new()
|
||||||
button.icon = preload("res://addons/material_maker/icons/remove.tres")
|
button.icon = preload("res://addons/material_maker/icons/remove.tres")
|
||||||
grid.add_child(button)
|
grid.add_child(button)
|
||||||
button.connect("pressed", generator, "remove_parameter", [ index ])
|
button.connect("pressed", generator, "remove_parameter", [ control.name ])
|
||||||
|
|
||||||
func update_node() -> void:
|
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
|
var i : int = 0
|
||||||
for c in grid.get_children():
|
for c in grid.get_children():
|
||||||
c.queue_free()
|
c.queue_free()
|
||||||
@ -36,11 +39,11 @@ func update_node() -> void:
|
|||||||
if control != null:
|
if control != null:
|
||||||
control.name = p.name
|
control.name = p.name
|
||||||
controls[control.name] = control
|
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":
|
if generator.widgets[i].type == "config_control":
|
||||||
var current = null
|
var current = null
|
||||||
if control.get_item_count() > 0:
|
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)
|
current = control.get_item_text(control.selected)
|
||||||
control.add_separator()
|
control.add_separator()
|
||||||
control.add_item("<add configuration>")
|
control.add_item("<add configuration>")
|
||||||
@ -52,12 +55,11 @@ func update_node() -> void:
|
|||||||
rect_size = Vector2(0, 0)
|
rect_size = Vector2(0, 0)
|
||||||
initialize_properties()
|
initialize_properties()
|
||||||
|
|
||||||
func _on_value_changed(new_value, variable) -> void:
|
func _on_value_changed(new_value, variable : String) -> void:
|
||||||
var param_index = variable.trim_prefix("param").to_int()
|
var widget = generator.get_widget(variable)
|
||||||
var widget = generator.widgets[param_index]
|
|
||||||
if widget.type == "config_control":
|
if widget.type == "config_control":
|
||||||
var configuration_count = widget.configurations.size()
|
var configuration_count = widget.configurations.size()
|
||||||
var control = grid.get_child(param_index*4+1)
|
var control = controls[variable]
|
||||||
if new_value < configuration_count:
|
if new_value < configuration_count:
|
||||||
._on_value_changed(new_value, variable)
|
._on_value_changed(new_value, variable)
|
||||||
var current = control.get_item_text(new_value)
|
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()
|
var dialog = preload("res://addons/material_maker/widgets/line_dialog.tscn").instance()
|
||||||
add_child(dialog)
|
add_child(dialog)
|
||||||
dialog.set_texts("Configuration", "Enter a name for the new configuration")
|
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()
|
dialog.popup_centered()
|
||||||
3:
|
3:
|
||||||
generator.update_configuration(param_index, current)
|
generator.update_configuration(variable, current)
|
||||||
4:
|
4:
|
||||||
generator.parameters[variable] = 0
|
generator.parameters[variable] = 0
|
||||||
generator.remove_configuration(param_index, current)
|
generator.remove_configuration(variable, current)
|
||||||
_:
|
_:
|
||||||
print(command)
|
print(command)
|
||||||
else:
|
else:
|
||||||
._on_value_changed(new_value, variable)
|
._on_value_changed(new_value, variable)
|
||||||
|
|
||||||
func do_add_configuration(config_name, param_index) -> void:
|
func do_add_configuration(config_name : String, param_name : String) -> void:
|
||||||
generator.add_configuration(param_index, config_name)
|
generator.add_configuration(param_name, config_name)
|
||||||
|
|
||||||
func on_label_changed(new_name, index) -> void:
|
func on_label_changed(new_label, param_name) -> void:
|
||||||
generator.set_label(index, new_name)
|
generator.set_label(param_name, new_label)
|
||||||
|
|
||||||
func _on_AddLink_pressed() -> void:
|
func _on_AddLink_pressed() -> void:
|
||||||
|
var control = generator.create_linked_control("Unnamed")
|
||||||
var widget = Control.new()
|
var widget = Control.new()
|
||||||
|
widget.name = control
|
||||||
add_control("Unnamed", widget)
|
add_control("Unnamed", widget)
|
||||||
var link = MMNodeLink.new(get_parent())
|
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:
|
func _on_AddConfig_pressed() -> void:
|
||||||
|
var control = generator.create_config_control("Unnamed")
|
||||||
var widget = Control.new()
|
var widget = Control.new()
|
||||||
|
widget.name = control
|
||||||
add_control("Unnamed", widget)
|
add_control("Unnamed", widget)
|
||||||
var link = MMNodeLink.new(get_parent())
|
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())
|
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:
|
func _on_Remote_resize_request(new_minsize) -> void:
|
||||||
rect_size = new_minsize
|
rect_size = new_minsize
|
||||||
@ -118,8 +124,7 @@ func on_parameter_changed(p, v) -> void:
|
|||||||
.on_parameter_changed(p, v)
|
.on_parameter_changed(p, v)
|
||||||
|
|
||||||
func on_enter_widget(widget) -> void:
|
func on_enter_widget(widget) -> void:
|
||||||
var param_index = widget.name.trim_prefix("param").to_int()
|
var w = generator.get_widget(widget.name)
|
||||||
var w = generator.widgets[param_index]
|
|
||||||
var new_links = []
|
var new_links = []
|
||||||
for l in w.linked_widgets:
|
for l in w.linked_widgets:
|
||||||
var graph_node = get_parent().get_node("node_"+l.node)
|
var graph_node = get_parent().get_node("node_"+l.node)
|
||||||
|
@ -7,8 +7,8 @@ var source = null
|
|||||||
var target = null
|
var target = null
|
||||||
|
|
||||||
var generator = null
|
var generator = null
|
||||||
var param_index = 0
|
var param_name : String = ""
|
||||||
var creating = false
|
var creating : bool = false
|
||||||
|
|
||||||
func _init(parent) -> void:
|
func _init(parent) -> void:
|
||||||
size_flags_horizontal = SIZE_EXPAND_FILL
|
size_flags_horizontal = SIZE_EXPAND_FILL
|
||||||
@ -17,11 +17,11 @@ func _init(parent) -> void:
|
|||||||
rect_clip_content = true
|
rect_clip_content = true
|
||||||
parent.add_child(self)
|
parent.add_child(self)
|
||||||
|
|
||||||
func pick(s, g, i, c = false) -> void:
|
func pick(s, g, n : String, c : bool = false) -> void:
|
||||||
source = s
|
source = s
|
||||||
end = get_global_transform().xform_inv(source.get_global_transform().xform(0.5*source.rect_size))
|
end = get_global_transform().xform_inv(source.get_global_transform().xform(0.5*source.rect_size))
|
||||||
generator = g
|
generator = g
|
||||||
param_index = i
|
param_name = n
|
||||||
creating = c
|
creating = c
|
||||||
set_process_input(true)
|
set_process_input(true)
|
||||||
|
|
||||||
@ -69,16 +69,16 @@ func _input(event: InputEvent) -> void:
|
|||||||
elif event is InputEventMouseMotion:
|
elif event is InputEventMouseMotion:
|
||||||
var control = find_control(event.global_position)
|
var control = find_control(event.global_position)
|
||||||
end = get_global_transform().xform_inv(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()
|
update()
|
||||||
elif event is InputEventMouseButton:
|
elif event is InputEventMouseButton:
|
||||||
if event.pressed:
|
if event.pressed:
|
||||||
if event.button_index == BUTTON_LEFT:
|
if event.button_index == BUTTON_LEFT:
|
||||||
var control = find_control(event.global_position)
|
var control = find_control(event.global_position)
|
||||||
if control != null:
|
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:
|
elif creating:
|
||||||
generator.remove_parameter(param_index)
|
generator.remove_parameter(param_name)
|
||||||
set_process_input(false)
|
set_process_input(false)
|
||||||
queue_free()
|
queue_free()
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
Loading…
Reference in New Issue
Block a user