2019-08-02 08:17:32 +02:00
|
|
|
tool
|
2019-07-31 20:53:00 +02:00
|
|
|
extends MMGenBase
|
|
|
|
class_name MMGenGraph
|
2019-08-02 08:17:32 +02:00
|
|
|
|
2019-09-17 08:12:53 +02:00
|
|
|
var label : String = "Graph"
|
2019-08-15 11:53:21 +02:00
|
|
|
var connections = []
|
2019-08-02 08:17:32 +02:00
|
|
|
|
2019-08-17 17:35:48 +02:00
|
|
|
func get_type():
|
|
|
|
return "graph"
|
|
|
|
|
2019-09-17 08:12:53 +02:00
|
|
|
func get_type_name():
|
|
|
|
return label
|
|
|
|
|
|
|
|
func get_parameter_defs():
|
2019-09-29 10:07:32 +02:00
|
|
|
if has_node("gen_parameters"):
|
|
|
|
return get_node("gen_parameters").get_parameter_defs()
|
2019-09-17 08:12:53 +02:00
|
|
|
return []
|
|
|
|
|
2019-09-27 08:28:33 +02:00
|
|
|
func set_parameter(p, v):
|
2019-09-29 10:07:32 +02:00
|
|
|
if has_node("gen_parameters"):
|
|
|
|
return get_node("gen_parameters").set_parameter(p, v)
|
2019-09-27 08:28:33 +02:00
|
|
|
|
2019-09-17 08:12:53 +02:00
|
|
|
func get_input_defs():
|
2019-09-29 10:07:32 +02:00
|
|
|
if has_node("gen_inputs"):
|
2019-10-02 23:06:20 +02:00
|
|
|
return get_node("gen_inputs").get_output_defs()
|
2019-09-17 08:12:53 +02:00
|
|
|
return []
|
|
|
|
|
|
|
|
func get_output_defs():
|
2019-09-29 10:07:32 +02:00
|
|
|
if has_node("gen_outputs"):
|
2019-10-02 23:06:20 +02:00
|
|
|
return get_node("gen_outputs").get_input_defs()
|
2019-09-17 08:12:53 +02:00
|
|
|
return []
|
|
|
|
|
2019-09-22 22:17:26 +02:00
|
|
|
func source_changed(input_index : int):
|
2019-09-29 10:07:32 +02:00
|
|
|
if has_node("gen_inputs"):
|
|
|
|
return get_node("gen_inputs").source_changed(input_index)
|
2019-09-22 22:17:26 +02:00
|
|
|
|
2019-08-02 08:17:32 +02:00
|
|
|
func get_port_source(gen_name: String, input_index: int) -> OutputPort:
|
2019-09-17 08:12:53 +02:00
|
|
|
if gen_name == "gen_inputs":
|
|
|
|
var parent = get_parent()
|
2019-09-29 10:07:32 +02:00
|
|
|
if parent != null and parent.get_script() == get_script():
|
2019-09-17 08:12:53 +02:00
|
|
|
return parent.get_port_source(name, input_index)
|
|
|
|
else:
|
|
|
|
for c in connections:
|
|
|
|
if c.to == gen_name and c.to_port == input_index:
|
|
|
|
var src_gen = get_node(c.from)
|
|
|
|
if src_gen != null:
|
2019-09-29 10:07:32 +02:00
|
|
|
if src_gen.get_script() == get_script():
|
2019-09-17 08:12:53 +02:00
|
|
|
return src_gen.get_port_source("gen_outputs", c.from_port)
|
|
|
|
return OutputPort.new(src_gen, c.from_port)
|
2019-09-14 09:14:27 +02:00
|
|
|
return null
|
|
|
|
|
2019-10-19 01:30:25 +02:00
|
|
|
func get_port_targets(gen_name: String, output_index: int) -> Array:
|
2019-09-22 22:17:26 +02:00
|
|
|
var rv = []
|
2019-09-14 09:14:27 +02:00
|
|
|
for c in connections:
|
2019-09-17 08:12:53 +02:00
|
|
|
if c.from == gen_name and c.from_port == output_index:
|
2019-09-14 09:14:27 +02:00
|
|
|
var tgt_gen = get_node(c.to)
|
|
|
|
if tgt_gen != null:
|
2019-09-22 22:17:26 +02:00
|
|
|
rv.push_back(InputPort.new(tgt_gen, c.to_port))
|
|
|
|
return rv
|
2019-08-13 13:38:11 +02:00
|
|
|
|
2019-09-29 10:07:32 +02:00
|
|
|
func add_generator(generator : MMGenBase):
|
|
|
|
var name = generator.name
|
|
|
|
var index = 1
|
|
|
|
while has_node(name):
|
|
|
|
index += 1
|
|
|
|
name = generator.name + "_" + str(index)
|
|
|
|
generator.name = name
|
|
|
|
add_child(generator)
|
|
|
|
|
2019-08-19 16:37:17 +02:00
|
|
|
func remove_generator(generator : MMGenBase):
|
|
|
|
var new_connections = []
|
|
|
|
for c in connections:
|
|
|
|
if c.from != generator.name and c.to != generator.name:
|
|
|
|
new_connections.append(c)
|
|
|
|
connections = new_connections
|
2019-09-09 22:00:18 +02:00
|
|
|
generator.queue_free()
|
|
|
|
|
|
|
|
func replace_generator(old : MMGenBase, new : MMGenBase):
|
|
|
|
new.name = old.name
|
|
|
|
new.position = old.position
|
|
|
|
remove_child(old)
|
|
|
|
old.free()
|
|
|
|
add_child(new)
|
2019-08-19 16:37:17 +02:00
|
|
|
|
2019-08-14 09:02:38 +02:00
|
|
|
func connect_children(from, from_port : int, to, to_port : int):
|
2019-10-19 01:30:25 +02:00
|
|
|
# check the new connection does not create a loop
|
|
|
|
var spreadlist = [ InputPort.new(to, to_port) ]
|
|
|
|
while !spreadlist.empty():
|
|
|
|
var input : InputPort = spreadlist.pop_front()
|
|
|
|
for o in input.generator.follow_input(input.input_index):
|
|
|
|
if o.generator == from and o.output_index == from_port:
|
|
|
|
return false
|
|
|
|
for t in o.generator.get_parent().get_port_targets(o.generator.name, o.output_index):
|
|
|
|
spreadlist.push_back(t)
|
2019-08-14 09:02:38 +02:00
|
|
|
# disconnect target
|
|
|
|
while true:
|
|
|
|
var remove = -1
|
|
|
|
for i in connections.size():
|
|
|
|
if connections[i].to == to.name and connections[i].to_port == to_port:
|
|
|
|
remove = i
|
|
|
|
break
|
|
|
|
if remove == -1:
|
|
|
|
break
|
|
|
|
connections.remove(remove)
|
|
|
|
# create new connection
|
|
|
|
connections.append({from=from.name, from_port=from_port, to=to.name, to_port=to_port})
|
|
|
|
return true
|
|
|
|
|
|
|
|
func disconnect_children(from, from_port : int, to, to_port : int):
|
|
|
|
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)
|
2019-09-09 22:00:18 +02:00
|
|
|
return true
|
|
|
|
|
2019-09-17 08:12:53 +02:00
|
|
|
func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
|
|
|
|
var outputs = get_node("gen_outputs")
|
|
|
|
if outputs != null:
|
2019-09-22 22:17:26 +02:00
|
|
|
var rv = outputs._get_shader_code(uv, output_index, context)
|
|
|
|
while rv is GDScriptFunctionState:
|
|
|
|
rv = yield(rv, "completed")
|
|
|
|
return rv
|
2019-09-29 10:07:32 +02:00
|
|
|
return { globals=[], defs="", code="", textures={} }
|
2019-09-17 08:12:53 +02:00
|
|
|
|
2019-09-09 22:00:18 +02:00
|
|
|
func _serialize(data):
|
2019-09-17 08:12:53 +02:00
|
|
|
data.label = label
|
2019-09-09 22:00:18 +02:00
|
|
|
data.nodes = []
|
|
|
|
for c in get_children():
|
|
|
|
data.nodes.append(c.serialize())
|
|
|
|
data.connections = connections
|
|
|
|
return data
|
2019-09-19 07:56:32 +02:00
|
|
|
|
|
|
|
func edit(node):
|
2019-09-29 10:07:32 +02:00
|
|
|
node.get_parent().call_deferred("update_view", self)
|
|
|
|
|
2019-10-05 11:04:50 +02:00
|
|
|
func create_subgraph(gens):
|
|
|
|
# Remove material, gen_inputs and gen_outputs nodes
|
|
|
|
var generators = []
|
|
|
|
var center = Vector2(0, 0)
|
|
|
|
var left_bound = 65535
|
|
|
|
var right_bound = -65536
|
|
|
|
var count = 0
|
|
|
|
for g in gens:
|
|
|
|
if g.name != "Material" and g.name != "gen_inputs" and g.name != "gen_outputs":
|
|
|
|
generators.push_back(g)
|
|
|
|
var p = g.position
|
|
|
|
center += p
|
|
|
|
count += 1
|
|
|
|
if left_bound > p.x: left_bound = p.x
|
|
|
|
if right_bound < p.x: right_bound = p.x
|
|
|
|
if count == 0:
|
|
|
|
return
|
|
|
|
center /= count
|
2019-09-29 10:07:32 +02:00
|
|
|
var new_graph = get_script().new()
|
|
|
|
new_graph.name = "graph"
|
2019-10-05 11:04:50 +02:00
|
|
|
add_generator(new_graph)
|
|
|
|
new_graph.position = center
|
2019-09-29 10:07:32 +02:00
|
|
|
var names : Array = []
|
|
|
|
for g in generators:
|
|
|
|
names.push_back(g.name)
|
|
|
|
remove_child(g)
|
|
|
|
new_graph.add_generator(g)
|
|
|
|
var new_graph_connections = []
|
|
|
|
var my_new_connections = []
|
2019-10-05 11:04:50 +02:00
|
|
|
var gen_inputs = null
|
|
|
|
var gen_outputs = null
|
|
|
|
var inputs = []
|
|
|
|
var outputs = []
|
2019-09-29 10:07:32 +02:00
|
|
|
for c in connections:
|
2019-10-05 11:04:50 +02:00
|
|
|
var src_name = c.from+"."+str(c.from_port)
|
2019-09-29 10:07:32 +02:00
|
|
|
if names.find(c.from) != -1 and names.find(c.to) != -1:
|
|
|
|
new_graph_connections.push_back(c)
|
|
|
|
elif names.find(c.from) != -1:
|
2019-10-05 11:04:50 +02:00
|
|
|
var port_index = outputs.find(src_name)
|
|
|
|
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)
|
2019-09-29 10:07:32 +02:00
|
|
|
my_new_connections.push_back( { from=new_graph.name, from_port=port_index, to=c.to, to_port=c.to_port } )
|
|
|
|
new_graph_connections.push_back( { from=c.from, from_port=c.from_port, to="gen_outputs", to_port=port_index } )
|
|
|
|
elif names.find(c.to) != -1:
|
2019-10-05 11:04:50 +02:00
|
|
|
var port_index = inputs.find(src_name)
|
|
|
|
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" } )
|
2019-10-02 23:06:20 +02:00
|
|
|
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 } )
|
2019-09-29 10:07:32 +02:00
|
|
|
else:
|
|
|
|
my_new_connections.push_back(c)
|
|
|
|
connections = my_new_connections
|
|
|
|
new_graph.connections = new_graph_connections
|
|
|
|
for g in generators:
|
2019-10-19 01:30:25 +02:00
|
|
|
if g.get_script() == load("res://addons/material_maker/engine/gen_remote.gd"):
|
2019-09-29 10:07:32 +02:00
|
|
|
g.name = "gen_parameters"
|
|
|
|
break
|