2019-08-02 08:17:32 +02:00
|
|
|
tool
|
2019-07-31 20:53:00 +02:00
|
|
|
extends Node
|
|
|
|
class_name MMGenBase
|
|
|
|
|
2019-08-25 23:27:07 +02:00
|
|
|
"""
|
|
|
|
Base class for texture generators, that defines their API
|
|
|
|
"""
|
|
|
|
|
2019-09-22 22:17:26 +02:00
|
|
|
signal parameter_changed
|
|
|
|
|
2019-09-14 09:14:27 +02:00
|
|
|
class InputPort:
|
|
|
|
var generator : MMGenBase = null
|
|
|
|
var input_index : int = 0
|
|
|
|
|
|
|
|
func _init(g : MMGenBase, i : int):
|
|
|
|
generator = g
|
|
|
|
input_index = i
|
|
|
|
|
|
|
|
func to_str():
|
|
|
|
return generator.name+".in("+str(input_index)+")"
|
|
|
|
|
2019-08-02 08:17:32 +02:00
|
|
|
class OutputPort:
|
|
|
|
var generator : MMGenBase = null
|
|
|
|
var output_index : int = 0
|
|
|
|
|
|
|
|
func _init(g : MMGenBase, o : int):
|
|
|
|
generator = g
|
|
|
|
output_index = o
|
|
|
|
|
2019-08-09 08:16:24 +02:00
|
|
|
func to_str():
|
2019-09-14 09:14:27 +02:00
|
|
|
return generator.name+".out("+str(output_index)+")"
|
2019-08-02 08:17:32 +02:00
|
|
|
|
2019-08-12 15:58:42 +02:00
|
|
|
var position : Vector2 = Vector2(0, 0)
|
2019-09-09 22:00:18 +02:00
|
|
|
var model = null
|
2019-08-12 15:58:42 +02:00
|
|
|
var parameters = {}
|
|
|
|
|
2019-08-17 17:35:48 +02:00
|
|
|
func _ready():
|
|
|
|
init_parameters()
|
|
|
|
|
|
|
|
func init_parameters():
|
|
|
|
for p in get_parameter_defs():
|
|
|
|
if !parameters.has(p.name):
|
|
|
|
if p.has("default"):
|
|
|
|
parameters[p.name] = MMType.deserialize_value(p.default)
|
|
|
|
else:
|
|
|
|
print("No default value for parameter "+p.name)
|
|
|
|
|
2019-10-02 23:06:20 +02:00
|
|
|
func set_position(p):
|
|
|
|
position = p
|
2019-08-02 08:17:32 +02:00
|
|
|
|
2019-08-12 15:58:42 +02:00
|
|
|
func get_type():
|
|
|
|
return "generic"
|
|
|
|
|
2019-08-17 17:35:48 +02:00
|
|
|
func get_type_name():
|
|
|
|
return "Unnamed"
|
|
|
|
|
|
|
|
func get_parameter_defs():
|
|
|
|
return []
|
|
|
|
|
2019-08-25 23:27:07 +02:00
|
|
|
func set_parameter(n : String, v):
|
|
|
|
parameters[n] = v
|
2019-09-14 09:14:27 +02:00
|
|
|
source_changed(0)
|
2019-09-22 22:17:26 +02:00
|
|
|
emit_signal("parameter_changed", n, v)
|
|
|
|
|
|
|
|
func notify_output_change(output_index : int):
|
|
|
|
var targets = get_targets(output_index)
|
|
|
|
for target in targets:
|
|
|
|
target.generator.source_changed(target.input_index)
|
2019-09-14 09:14:27 +02:00
|
|
|
|
2019-10-05 11:04:50 +02:00
|
|
|
func source_changed(__):
|
2019-09-14 09:14:27 +02:00
|
|
|
for i in range(get_output_defs().size()):
|
2019-09-22 22:17:26 +02:00
|
|
|
notify_output_change(i)
|
2019-08-25 23:27:07 +02:00
|
|
|
|
2019-08-17 17:35:48 +02:00
|
|
|
func get_input_defs():
|
|
|
|
return []
|
|
|
|
|
|
|
|
func get_output_defs():
|
|
|
|
return []
|
|
|
|
|
2019-08-02 08:17:32 +02:00
|
|
|
func get_source(input_index : int):
|
|
|
|
return get_parent().get_port_source(name, input_index)
|
2019-09-14 09:14:27 +02:00
|
|
|
|
2019-09-22 22:17:26 +02:00
|
|
|
func get_targets(output_index : int):
|
|
|
|
return get_parent().get_port_targets(name, output_index)
|
2019-08-02 08:17:32 +02:00
|
|
|
|
|
|
|
func get_input_shader(input_index : int):
|
|
|
|
var source = get_source(input_index)
|
|
|
|
if source != null:
|
|
|
|
return source.get_shader()
|
|
|
|
|
2019-08-17 17:35:48 +02:00
|
|
|
func get_shader(output_index : int, context):
|
2019-08-12 15:58:42 +02:00
|
|
|
return get_shader_code("UV", output_index, context);
|
2019-08-02 08:17:32 +02:00
|
|
|
|
2019-08-17 17:35:48 +02:00
|
|
|
func render(output_index : int, renderer : MMGenRenderer, size : int):
|
|
|
|
var context : MMGenContext = MMGenContext.new(renderer)
|
|
|
|
var source = get_shader_code("UV", output_index, context)
|
2019-08-18 16:28:50 +02:00
|
|
|
while source is GDScriptFunctionState:
|
|
|
|
source = yield(source, "completed")
|
2019-08-17 17:35:48 +02:00
|
|
|
if source == null:
|
2019-10-05 11:04:50 +02:00
|
|
|
source = { defs="", code="", textures={}, rgba="vec4(0.0)" }
|
2019-08-17 17:35:48 +02:00
|
|
|
var shader : String = renderer.generate_shader(source)
|
2019-10-05 11:04:50 +02:00
|
|
|
var result = renderer.render_shader(shader, source.textures, size)
|
|
|
|
while result is GDScriptFunctionState:
|
|
|
|
result = yield(result, "completed")
|
|
|
|
return result
|
2019-08-17 17:35:48 +02:00
|
|
|
|
|
|
|
func get_shader_code(uv : String, output_index : int, context : MMGenContext):
|
|
|
|
var rv = _get_shader_code(uv, output_index, context)
|
2019-08-18 16:28:50 +02:00
|
|
|
while rv is GDScriptFunctionState:
|
|
|
|
rv = yield(rv, "completed")
|
2019-08-12 15:58:42 +02:00
|
|
|
if rv != null:
|
|
|
|
if !rv.has("f"):
|
|
|
|
if rv.has("rgb"):
|
|
|
|
rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)"
|
|
|
|
elif rv.has("rgba"):
|
|
|
|
rv.f = "(dot("+rv.rgba+".rgb, vec3(1.0))/3.0)"
|
|
|
|
else:
|
|
|
|
rv.f = "0.0"
|
|
|
|
if !rv.has("rgb"):
|
|
|
|
if rv.has("rgba"):
|
|
|
|
rv.rgb = rv.rgba+".rgb"
|
|
|
|
else:
|
|
|
|
rv.rgb = "vec3("+rv.f+")"
|
|
|
|
if !rv.has("rgba"):
|
|
|
|
rv.rgba = "vec4("+rv.rgb+", 1.0)"
|
2019-08-02 08:17:32 +02:00
|
|
|
return rv
|
|
|
|
|
2019-10-05 11:04:50 +02:00
|
|
|
func _get_shader_code(__, __, __):
|
2019-08-02 08:17:32 +02:00
|
|
|
return null
|
2019-09-09 22:00:18 +02:00
|
|
|
|
|
|
|
func _serialize(data):
|
|
|
|
print("cannot save "+name)
|
|
|
|
return data
|
|
|
|
|
|
|
|
func serialize():
|
2019-09-16 20:45:47 +02:00
|
|
|
var rv = { name=name, type=get_type(), parameters={}, node_position={ x=position.x, y=position.y } }
|
2019-09-09 22:00:18 +02:00
|
|
|
for p in parameters.keys():
|
|
|
|
rv.parameters[p] = MMType.serialize_value(parameters[p])
|
|
|
|
if model != null:
|
|
|
|
rv.type = model
|
|
|
|
else:
|
|
|
|
rv = _serialize(rv)
|
|
|
|
return rv
|