Add return type hints to all scripts

This also simplifies some functions.

This partially addresses #30.
This commit is contained in:
Hugo Locurcio 2019-10-20 16:22:06 +02:00
parent 159ee7678b
commit 93c84650cd
No known key found for this signature in database
GPG Key ID: 39E8F8BE30B0A49C
57 changed files with 534 additions and 562 deletions

View File

@ -11,42 +11,42 @@ signal parameter_changed
class InputPort: class InputPort:
var generator : MMGenBase = null var generator : MMGenBase = null
var input_index : int = 0 var input_index : int = 0
func _init(g : MMGenBase, i : int): func _init(g : MMGenBase, i : int) -> void:
generator = g generator = g
input_index = i input_index = i
func to_str(): func to_str() -> String:
return generator.name+".in("+str(input_index)+")" return generator.name+".in("+str(input_index)+")"
class OutputPort: class OutputPort:
var generator : MMGenBase = null var generator : MMGenBase = null
var output_index : int = 0 var output_index : int = 0
func _init(g : MMGenBase, o : int): func _init(g : MMGenBase, o : int) -> void:
generator = g generator = g
output_index = o output_index = o
func to_str(): func to_str() -> String:
return generator.name+".out("+str(output_index)+")" return generator.name+".out("+str(output_index)+")"
var position : Vector2 = Vector2(0, 0) var position : Vector2 = Vector2(0, 0)
var model = null var model = null
var parameters = {} var parameters = {}
func _ready(): func _ready() -> void:
init_parameters() init_parameters()
func can_be_deleted() -> bool: func can_be_deleted() -> bool:
return true return true
func toggle_editable(): func toggle_editable() -> bool:
return false
func is_editable():
return false return false
func init_parameters(): func is_editable() -> bool:
return false
func init_parameters() -> void:
for p in get_parameter_defs(): for p in get_parameter_defs():
if !parameters.has(p.name): if !parameters.has(p.name):
if p.has("default"): if p.has("default"):
@ -56,16 +56,16 @@ func init_parameters():
else: else:
print("No default value for parameter "+p.name) print("No default value for parameter "+p.name)
func set_position(p): func set_position(p) -> void:
position = p position = p
func get_type(): func get_type() -> String:
return "generic" return "generic"
func get_type_name(): func get_type_name() -> String:
return "Unnamed" return "Unnamed"
func get_parameter_defs(): func get_parameter_defs() -> Array:
return [] return []
func set_parameter(n : String, v): func set_parameter(n : String, v):
@ -83,16 +83,16 @@ func source_changed(__):
for i in range(get_output_defs().size()): for i in range(get_output_defs().size()):
notify_output_change(i) notify_output_change(i)
func get_input_defs(): func get_input_defs() -> Array:
return [] return []
func get_output_defs(): func get_output_defs() -> Array:
return [] return []
func get_source(input_index : int): func get_source(input_index : int) -> OutputPort:
return get_parent().get_port_source(name, input_index) return get_parent().get_port_source(name, input_index)
func get_targets(output_index : int): func get_targets(output_index : int) -> Array:
return get_parent().get_port_targets(name, output_index) return get_parent().get_port_targets(name, output_index)
# get the list of outputs that depend on the input whose index is passed as parameter # get the list of outputs that depend on the input whose index is passed as parameter
@ -107,15 +107,15 @@ func get_input_shader(input_index : int):
if source != null: if source != null:
return source.get_shader() return source.get_shader()
func get_shader(output_index : int, context): func get_shader(output_index : int, context) -> Dictionary:
return get_shader_code("UV", output_index, context); return get_shader_code("UV", output_index, context)
func render(output_index : int, renderer : MMGenRenderer, size : int): func render(output_index : int, renderer : MMGenRenderer, size : int):
var context : MMGenContext = MMGenContext.new(renderer) var context : MMGenContext = MMGenContext.new(renderer)
var source = get_shader_code("UV", output_index, context) var source = get_shader_code("UV", output_index, context)
while source is GDScriptFunctionState: while source is GDScriptFunctionState:
source = yield(source, "completed") source = yield(source, "completed")
if source == null: if source.empty():
source = { defs="", code="", textures={}, rgba="vec4(0.0)" } source = { defs="", code="", textures={}, rgba="vec4(0.0)" }
var shader : String = renderer.generate_shader(source) var shader : String = renderer.generate_shader(source)
var result = renderer.render_shader(shader, source.textures, size) var result = renderer.render_shader(shader, source.textures, size)
@ -123,11 +123,11 @@ func render(output_index : int, renderer : MMGenRenderer, size : int):
result = yield(result, "completed") result = yield(result, "completed")
return result return result
func get_shader_code(uv : String, output_index : int, context : MMGenContext): func get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var rv = _get_shader_code(uv, output_index, context) var rv = _get_shader_code(uv, output_index, context)
while rv is GDScriptFunctionState: while rv is GDScriptFunctionState:
rv = yield(rv, "completed") rv = yield(rv, "completed")
if rv != null: if !rv.empty():
if !rv.has("f"): if !rv.has("f"):
if rv.has("rgb"): if rv.has("rgb"):
rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)" rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)"
@ -144,10 +144,10 @@ func get_shader_code(uv : String, output_index : int, context : MMGenContext):
rv.rgba = "vec4("+rv.rgb+", 1.0)" rv.rgba = "vec4("+rv.rgb+", 1.0)"
return rv return rv
func _get_shader_code(__, __, __): func _get_shader_code(__, __, __) -> Dictionary:
return null return {}
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
print("cannot save "+name) print("cannot save "+name)
return data return data

View File

@ -4,35 +4,35 @@ class_name MMGenBuffer
""" """
Texture generator buffers, that render their input in a specific resolution and provide the result as output. Texture generator buffers, that render their input in a specific resolution and provide the result as output.
This is useful when using generators that sample their inputs several times (such as convolutions) This is useful when using generators that sample their inputs several times (such as convolutions)
""" """
var updated : bool = false var updated : bool = false
func _ready(): func _ready() -> void:
if !parameters.has("size"): if !parameters.has("size"):
parameters.size = 4 parameters.size = 4
func get_type(): func get_type() -> String:
return "buffer" return "buffer"
func get_type_name(): func get_type_name() -> String:
return "Buffer" return "Buffer"
func get_parameter_defs(): func get_parameter_defs() -> Array:
return [ { name="size", type="size", first=4, last=11, default=4 } ] return [ { name="size", type="size", first=4, last=11, default=4 } ]
func get_input_defs(): func get_input_defs() -> Array:
return [ { name="in", type="rgba" } ] return [ { name="in", type="rgba" } ]
func get_output_defs(): func get_output_defs() -> Array:
return [ { type="rgba" } ] return [ { type="rgba" } ]
func source_changed(input_port_index : int): func source_changed(input_port_index : int):
updated = false updated = false
.source_changed(input_port_index) .source_changed(input_port_index)
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var source = get_source(0) var source = get_source(0)
if source != null and !updated: if source != null and !updated:
var result = source.generator.render(source.output_index, context.renderer, pow(2, 4+parameters.size)) var result = source.generator.render(source.output_index, context.renderer, pow(2, 4+parameters.size))
@ -47,6 +47,6 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
rv = yield(rv, "completed") rv = yield(rv, "completed")
return rv return rv
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
data.type = "buffer" data.type = "buffer"
return data return data

View File

@ -9,26 +9,26 @@ Comments to put in the graph
var text : String = "Double-click to write a comment" var text : String = "Double-click to write a comment"
var size : Vector2 = Vector2(0, 0) var size : Vector2 = Vector2(0, 0)
func _ready(): func _ready() -> void:
if !parameters.has("size"): if !parameters.has("size"):
parameters.size = 4 parameters.size = 4
func get_type(): func get_type() -> String:
return "comment" return "comment"
func get_type_name(): func get_type_name() -> String:
return "Comment" return "Comment"
func get_parameter_defs(): func get_parameter_defs() -> Array:
return [] return []
func get_input_defs(): func get_input_defs() -> Array:
return []
func get_output_defs():
return [] return []
func _serialize(data): func get_output_defs() -> Array:
return []
func _serialize(data: Dictionary) -> Dictionary:
data.type = "comment" data.type = "comment"
data.text = text data.text = text
data.size = { x=size.x, y=size.y } data.size = { x=size.x, y=size.y }

View File

@ -5,13 +5,13 @@ class_name MMGenContext
var renderer : MMGenRenderer var renderer : MMGenRenderer
var variants : Dictionary = {} var variants : Dictionary = {}
func _init(r : MMGenRenderer): func _init(r : MMGenRenderer) -> void:
renderer = r renderer = r
func has_variant(generator): func has_variant(generator) -> bool:
return variants.has(generator) return variants.has(generator)
func get_variant(generator, variant): func get_variant(generator, variant) -> int:
var rv = -1 var rv = -1
if variants.has(generator): if variants.has(generator):
rv = variants[generator].find(variant) rv = variants[generator].find(variant)

View File

@ -4,27 +4,27 @@ class_name MMGenConvolution
var convolution_params : Dictionary = {} var convolution_params : Dictionary = {}
func get_type(): func get_type() -> String:
return "shader" return "shader"
func get_type_name(): func get_type_name() -> String:
if convolution_params.has("name"): if convolution_params.has("name"):
return convolution_params.name return convolution_params.name
return .get_type_name() return .get_type_name()
func get_parameter_defs(): func get_parameter_defs() -> Array:
return [ { name="size", type="size", first=4, last=11, default=4 } ] return [ { name="size", type="size", first=4, last=11, default=4 } ]
func get_input_defs(): func get_input_defs() -> Array:
return [ { name="in", type=convolution_params.input_type } ] return [ { name="in", type=convolution_params.input_type } ]
func get_output_defs(): func get_output_defs() -> Array:
return [ { type=convolution_params.output_type } ] return [ { type=convolution_params.output_type } ]
func set_convolution_params(data: Dictionary): func set_convolution_params(data: Dictionary) -> void:
convolution_params = data convolution_params = data
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var genname = "o"+str(get_instance_id()) var genname = "o"+str(get_instance_id())
var epsilon = 1.0/pow(2, 4+parameters.size) var epsilon = 1.0/pow(2, 4+parameters.size)
var types = { "rgba": { type="vec4", init="vec4(0.0)" }, "rgb": { type="vec3", init="vec3(0.0)" }, "f": { type="float", init="0.0" } } var types = { "rgba": { type="vec4", init="vec4(0.0)" }, "rgb": { type="vec3", init="vec3(0.0)" }, "f": { type="float", init="0.0" } }
@ -58,6 +58,6 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
rv.rgb = "%s_%d" % [ genname, variant_index ] rv.rgb = "%s_%d" % [ genname, variant_index ]
return rv return rv
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
data.convolution_params = convolution_params data.convolution_params = convolution_params
return data return data

View File

@ -8,24 +8,24 @@ var connections = []
var editable = false var editable = false
func get_type(): func get_type() -> String:
return "graph" return "graph"
func get_type_name(): func get_type_name() -> String:
return label return label
func toggle_editable(): func toggle_editable() -> bool:
editable = !editable editable = !editable
if editable: if editable:
model = null model = null
return true return true
func is_editable(): func is_editable() -> bool:
return editable return editable
func get_parameter_defs(): func get_parameter_defs() -> Array:
if has_node("gen_parameters"): if has_node("gen_parameters"):
return get_node("gen_parameters").get_parameter_defs() return get_node("gen_parameters").get_parameter_defs()
return [] return []
@ -34,12 +34,12 @@ func set_parameter(p, v):
if has_node("gen_parameters"): if has_node("gen_parameters"):
return get_node("gen_parameters").set_parameter(p, v) return get_node("gen_parameters").set_parameter(p, v)
func get_input_defs(): func get_input_defs() -> Array:
if has_node("gen_inputs"): if has_node("gen_inputs"):
return get_node("gen_inputs").get_output_defs() return get_node("gen_inputs").get_output_defs()
return [] return []
func get_output_defs(): func get_output_defs() -> Array:
if has_node("gen_outputs"): if has_node("gen_outputs"):
return get_node("gen_outputs").get_input_defs() return get_node("gen_outputs").get_input_defs()
return [] return []
@ -72,7 +72,7 @@ func get_port_targets(gen_name: String, output_index: int) -> Array:
rv.push_back(InputPort.new(tgt_gen, c.to_port)) rv.push_back(InputPort.new(tgt_gen, c.to_port))
return rv return rv
func add_generator(generator : MMGenBase): func add_generator(generator : MMGenBase) -> void:
var name = generator.name var name = generator.name
var index = 1 var index = 1
while has_node(name): while has_node(name):
@ -81,22 +81,22 @@ func add_generator(generator : MMGenBase):
generator.name = name generator.name = name
add_child(generator) add_child(generator)
func remove_generator(generator : MMGenBase): func remove_generator(generator : MMGenBase) -> void:
var new_connections = [] var new_connections = []
for c in connections: for c in connections:
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
generator.queue_free() generator.queue_free()
func replace_generator(old : MMGenBase, new : MMGenBase): func replace_generator(old : MMGenBase, new : MMGenBase) -> void:
new.name = old.name new.name = old.name
new.position = old.position new.position = old.position
remove_child(old) remove_child(old)
old.free() old.free()
add_child(new) add_child(new)
func connect_children(from, from_port : int, to, to_port : int): func connect_children(from, from_port : int, to, to_port : int) -> bool:
# check the new connection does not create a loop # check the new connection does not create a loop
var spreadlist = [ InputPort.new(to, to_port) ] var spreadlist = [ InputPort.new(to, to_port) ]
while !spreadlist.empty(): while !spreadlist.empty():
@ -120,7 +120,7 @@ func connect_children(from, from_port : int, to, to_port : int):
connections.append({from=from.name, from_port=from_port, to=to.name, to_port=to_port}) connections.append({from=from.name, from_port=from_port, to=to.name, to_port=to_port})
return true return true
func disconnect_children(from, from_port : int, to, to_port : int): func disconnect_children(from, from_port : int, to, to_port : int) -> bool:
while true: while true:
var remove = -1 var remove = -1
for i in connections.size(): for i in connections.size():
@ -132,7 +132,7 @@ func disconnect_children(from, from_port : int, to, to_port : int):
connections.remove(remove) connections.remove(remove)
return true return true
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var outputs = get_node("gen_outputs") var outputs = get_node("gen_outputs")
if outputs != null: if outputs != null:
var rv = outputs._get_shader_code(uv, output_index, context) var rv = outputs._get_shader_code(uv, output_index, context)
@ -141,7 +141,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
return rv return rv
return { globals=[], defs="", code="", textures={} } return { globals=[], defs="", code="", textures={} }
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
data.label = label data.label = label
data.nodes = [] data.nodes = []
for c in get_children(): for c in get_children():
@ -149,10 +149,10 @@ func _serialize(data):
data.connections = connections data.connections = connections
return data return data
func edit(node): func edit(node) -> void:
node.get_parent().call_deferred("update_view", self) node.get_parent().call_deferred("update_view", self)
func create_subgraph(gens): func create_subgraph(gens) -> 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)

View File

@ -6,16 +6,16 @@ class_name MMGenImage
Texture generator from image Texture generator from image
""" """
func get_type(): func get_type() -> String:
return "image" return "image"
func get_type_name(): func get_type_name() -> String:
return "Image" return "Image"
func get_parameter_defs(): func get_parameter_defs() -> Array:
return [ { name="image", type="path" } ] return [ { name="image", type="path" } ]
func set_parameter(n : String, v): func set_parameter(n : String, v) -> void:
.set_parameter(n, v) .set_parameter(n, v)
if n == "image": if n == "image":
texture.load(v) texture.load(v)

View File

@ -8,34 +8,34 @@ IOs just forward their inputs to their outputs and are used to specify graph int
var ports : Array = [] var ports : Array = []
func get_type(): func get_type() -> String:
return "ios" return "ios"
func get_type_name(): func get_type_name() -> String:
match name: match name:
"gen_inputs": return "Inputs" "gen_inputs": return "Inputs"
"gen_outputs": return "Outputs" "gen_outputs": return "Outputs"
_: return "IOs" _: return "IOs"
func get_io_defs(): func get_io_defs() -> Array:
var rv : Array = [] var rv : Array = []
for p in ports: for p in ports:
rv.push_back({ name=p.name, type="rgba" }) rv.push_back({ name=p.name, type="rgba" })
return rv return rv
func get_input_defs(): func get_input_defs() -> Array:
return [] if name == "gen_inputs" else get_io_defs() return [] if name == "gen_inputs" else get_io_defs()
func get_output_defs(): func get_output_defs() -> Array:
return [] if name == "gen_outputs" else get_io_defs() return [] if name == "gen_outputs" else get_io_defs()
func source_changed(input_index : int): func source_changed(input_index : int) -> void:
if name == "gen_outputs": if name == "gen_outputs":
get_parent().notify_output_change(input_index) get_parent().notify_output_change(input_index)
else: else:
notify_output_change(input_index) notify_output_change(input_index)
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var source = get_source(output_index) var source = get_source(output_index)
if source != null: if source != null:
var rv = source.generator._get_shader_code(uv, source.output_index, context) var rv = source.generator._get_shader_code(uv, source.output_index, context)
@ -44,7 +44,7 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
return rv return rv
return { defs="", code="", textures={} } return { defs="", code="", textures={} }
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
data.type = "ios" data.type = "ios"
data.ports = ports data.ports = ports
return data return data

View File

@ -15,7 +15,7 @@ const TEXTURE_LIST = [
{ port=6, texture="depth_texture" } { port=6, texture="depth_texture" }
] ]
func _ready(): func _ready() -> void:
texture_list = TEXTURE_LIST texture_list = TEXTURE_LIST
for t in texture_list: for t in texture_list:
generated_textures[t.texture] = null generated_textures[t.texture] = null
@ -24,13 +24,13 @@ func _ready():
func can_be_deleted() -> bool: func can_be_deleted() -> bool:
return false return false
func get_type(): func get_type() -> String:
return "material" return "material"
func get_type_name(): func get_type_name() -> String:
return "Material" return "Material"
func get_parameter_defs(): func get_parameter_defs() -> Array:
return [ return [
{ name="albedo_color", label="Albedo", type="color", default={ r=1.0, g=1.0, b=1.0, a=1.0} }, { name="albedo_color", label="Albedo", type="color", default={ r=1.0, g=1.0, b=1.0, a=1.0} },
{ name="metallic", label="Metallic", type="float", min=0.0, max=1.0, step=0.05, default=1.0 }, { name="metallic", label="Metallic", type="float", min=0.0, max=1.0, step=0.05, default=1.0 },
@ -42,7 +42,7 @@ func get_parameter_defs():
{ name="size", label="Size", type="size", first=7, last=11, default=9 } { name="size", label="Size", type="size", first=7, last=11, default=9 }
] ]
func get_input_defs(): func get_input_defs() -> Array:
return [ return [
{ name="albedo_texture", label="", type="rgb" }, { name="albedo_texture", label="", type="rgb" },
{ name="metallic_texture", label="", type="f" }, { name="metallic_texture", label="", type="f" },
@ -53,7 +53,7 @@ func get_input_defs():
{ name="depth_texture", label="", type="f" } { name="depth_texture", label="", type="f" }
] ]
func get_image_size(): func get_image_size() -> int:
var rv : int var rv : int
if parameters.has("size"): if parameters.has("size"):
rv = int(pow(2, parameters.size+7)) rv = int(pow(2, parameters.size+7))
@ -61,21 +61,21 @@ func get_image_size():
rv = 512 rv = 512
return rv return rv
func update_preview(): func update_preview() -> void:
var graph_edit = self var graph_edit = self
while graph_edit is MMGenBase: while graph_edit is MMGenBase:
graph_edit = graph_edit.get_parent() graph_edit = graph_edit.get_parent()
if graph_edit.has_method("send_changed_signal"): if graph_edit.has_method("send_changed_signal"):
graph_edit.send_changed_signal() graph_edit.send_changed_signal()
func set_parameter(p, v): func set_parameter(p, v) -> void:
.set_parameter(p, v) .set_parameter(p, v)
update_preview() update_preview()
func source_changed(input_index : int): func source_changed(input_index : int) -> void:
update_preview() update_preview()
func render_textures(renderer : MMGenRenderer): func render_textures(renderer : MMGenRenderer) -> void:
for t in texture_list: for t in texture_list:
var texture = null var texture = null
if t.has("port"): if t.has("port"):
@ -116,21 +116,21 @@ func render_textures(renderer : MMGenRenderer):
generated_textures[t.texture] = texture generated_textures[t.texture] = texture
func update_materials(material_list): func update_materials(material_list) -> void:
for m in material_list: for m in material_list:
update_spatial_material(m) update_spatial_material(m)
func get_generated_texture(slot, file_prefix = null): func get_generated_texture(slot, file_prefix = null) -> ImageTexture:
if file_prefix != null: if file_prefix != null:
var file_name = "%s_%s.png" % [ file_prefix, slot ] var file_name = "%s_%s.png" % [ file_prefix, slot ]
if File.new().file_exists(file_name): if File.new().file_exists(file_name):
return load(file_name) return load(file_name) as ImageTexture
else: else:
return null return null
else: else:
return generated_textures[slot] return generated_textures[slot]
func update_spatial_material(m, file_prefix = null): func update_spatial_material(m, file_prefix = null) -> void:
var texture var texture
m.albedo_color = parameters.albedo_color m.albedo_color = parameters.albedo_color
m.albedo_texture = get_generated_texture("albedo", file_prefix) m.albedo_texture = get_generated_texture("albedo", file_prefix)
@ -138,7 +138,7 @@ func update_spatial_material(m, file_prefix = null):
m.roughness = parameters.roughness m.roughness = parameters.roughness
# Metallic # Metallic
texture = get_generated_texture("orm", file_prefix) texture = get_generated_texture("orm", file_prefix)
m.metallic_texture = texture m.metallic_texture = texture
m.metallic_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE m.metallic_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE
# Roughness # Roughness
m.roughness_texture = texture m.roughness_texture = texture
@ -176,7 +176,7 @@ func update_spatial_material(m, file_prefix = null):
else: else:
m.depth_enabled = false m.depth_enabled = false
func export_textures(prefix, editor_interface = null): func export_textures(prefix, editor_interface = null) -> SpatialMaterial:
for t in texture_list: for t in texture_list:
var texture = generated_textures[t.texture] var texture = generated_textures[t.texture]
if texture != null: if texture != null:
@ -192,5 +192,7 @@ func export_textures(prefix, editor_interface = null):
resource_filesystem.scan() resource_filesystem.scan()
return new_material return new_material
func _serialize(data): return null
func _serialize(data: Dictionary) -> Dictionary:
return data return data

View File

@ -8,7 +8,7 @@ Remote can be used to control parameters from several generators in the same gra
var widgets = null var widgets = null
func set_widgets(w): func set_widgets(w) -> void:
widgets = w widgets = w
var i = 0 var i = 0
for w in widgets: for w in widgets:
@ -17,13 +17,13 @@ func set_widgets(w):
parameters[param_name] = 0 parameters[param_name] = 0
i += 1 i += 1
func get_type(): func get_type() -> String:
return "remote" return "remote"
func get_type_name(): func get_type_name() -> String:
return "Parameters" if name == "gen_parameters" else "Remote" return "Parameters" if name == "gen_parameters" else "Remote"
func get_parameter_defs(): func get_parameter_defs() -> Array:
var rv = [] var rv = []
var i = 0 var i = 0
for w in widgets: for w in widgets:
@ -55,7 +55,7 @@ func get_parameter_defs():
print(w.type) print(w.type)
return rv return rv
func set_parameter(p, v): func set_parameter(p, v) -> void:
var parent = get_parent() var parent = get_parent()
var param_index = p.trim_prefix("param").to_int() var param_index = p.trim_prefix("param").to_int()
var widget = widgets[param_index] var widget = widgets[param_index]
@ -79,28 +79,28 @@ func set_parameter(p, v):
if name == "gen_parameters": if name == "gen_parameters":
get_parent().parameters[p] = v get_parent().parameters[p] = v
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
data.type = "remote" data.type = "remote"
data.widgets = widgets data.widgets = widgets
return data return data
func create_linked_control(label): func create_linked_control(label) -> int:
var index = widgets.size() var index = widgets.size()
widgets.push_back({ label=label, type="linked_control", linked_widgets=[] }) widgets.push_back({ label=label, type="linked_control", linked_widgets=[] })
return index return index
func create_config_control(label): func create_config_control(label) -> int:
var index = widgets.size() var index = widgets.size()
widgets.push_back({ label=label, type="config_control", linked_widgets=[], configurations={} }) widgets.push_back({ label=label, type="config_control", linked_widgets=[], configurations={} })
return index return index
func set_label(index, new_label): func set_label(index, new_label) -> void:
widgets[index].label = new_label widgets[index].label = new_label
func can_link_parameter(index, generator, param): func can_link_parameter(index, generator, param) -> bool:
return true return true
func link_parameter(index, generator, param): func link_parameter(index, generator, param) -> void:
if !can_link_parameter(index, generator, param): if !can_link_parameter(index, generator, param):
return return
var widget = widgets[index] var widget = widgets[index]
@ -113,13 +113,13 @@ func link_parameter(index, generator, param):
parameters["param"+str(index)] = 0 parameters["param"+str(index)] = 0
emit_signal("parameter_changed", "", null) emit_signal("parameter_changed", "", null)
func remove_parameter(index): func remove_parameter(index) -> void:
for i in range(index, widgets.size()-2): for i in range(index, widgets.size()-2):
parameters["param"+str(i)] = parameters["param"+str(i+1)] parameters["param"+str(i)] = parameters["param"+str(i+1)]
widgets.remove(index) widgets.remove(index)
emit_signal("parameter_changed", "", null) emit_signal("parameter_changed", "", null)
func add_configuration(index, config_name): func add_configuration(index, config_name) -> void:
var widget = widgets[index] var widget = widgets[index]
if widget.type == "config_control": if widget.type == "config_control":
widget.configurations[config_name] = [] widget.configurations[config_name] = []
@ -128,7 +128,7 @@ func add_configuration(index, config_name):
parameters["param"+str(index)] =configurations.find(config_name) parameters["param"+str(index)] =configurations.find(config_name)
update_configuration(index, config_name) update_configuration(index, config_name)
func update_configuration(index, config_name): func update_configuration(index, config_name) -> void:
var widget = widgets[index] var widget = widgets[index]
if widget.type == "config_control": if widget.type == "config_control":
var c = [] var c = []
@ -141,7 +141,7 @@ func update_configuration(index, config_name):
widget.configurations[config_name] = c widget.configurations[config_name] = c
emit_signal("parameter_changed", "", null) emit_signal("parameter_changed", "", null)
func remove_configuration(index, config_name): func remove_configuration(index, config_name) -> void:
var widget = widgets[index] var widget = widgets[index]
if widget.type == "config_control": if widget.type == "config_control":
widget.configurations.erase(config_name) widget.configurations.erase(config_name)

View File

@ -7,30 +7,30 @@ var uses_seed = false
var editable = false var editable = false
func toggle_editable(): func toggle_editable() -> bool:
editable = !editable editable = !editable
if editable: if editable:
model = null model = null
return true return true
func is_editable(): func is_editable() -> bool:
return editable return editable
func get_type(): func get_type() -> String:
return "shader" return "shader"
func get_type_name(): func get_type_name() -> String:
if shader_model.has("name"): if shader_model.has("name"):
return shader_model.name return shader_model.name
return .get_type_name() return .get_type_name()
func get_parameter_defs(): func get_parameter_defs() -> Array:
if shader_model == null or !shader_model.has("parameters"): if shader_model == null or !shader_model.has("parameters"):
return [] return []
else: else:
return shader_model.parameters return shader_model.parameters
func get_input_defs(): func get_input_defs() -> Array:
if shader_model == null or !shader_model.has("inputs"): if shader_model == null or !shader_model.has("inputs"):
return [] return []
else: else:
@ -55,12 +55,12 @@ func set_shader_model(data: Dictionary):
else: else:
shader_model.outputs[i].type = "f" shader_model.outputs[i].type = "f"
func set_position(p): func set_position(p) -> void:
.set_position(p) .set_position(p)
if uses_seed: if uses_seed:
source_changed(0) source_changed(0)
func get_seed(): func get_seed() -> int:
var s = ((int(position.x) * 0x1f1f1f1f) ^ int(position.y)) % 65536 var s = ((int(position.x) * 0x1f1f1f1f) ^ int(position.y)) % 65536
return s return s
@ -81,7 +81,7 @@ func find_keyword_call(string, keyword):
parenthesis_level -= 1 parenthesis_level -= 1
return "" return ""
func replace_input(string, context, input, type, src, default): func replace_input(string, context, input, type, src, default) -> Dictionary:
var required_globals = [] var required_globals = []
var required_defs = "" var required_defs = ""
var required_code = "" var required_code = ""
@ -117,10 +117,10 @@ func replace_input(string, context, input, type, src, default):
string = string.replace("$%s(%s)" % [ input, uv ], src_code.string) 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 } return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures, new_pass_required=new_pass_required }
func is_word_letter(l): func is_word_letter(l) -> bool:
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1 return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
func replace_variable(string, variable, value): func replace_variable(string, variable, value) -> String:
string = string.replace("$(%s)" % variable, value) string = string.replace("$(%s)" % variable, value)
var keyword_size = variable.length()+1 var keyword_size = variable.length()+1
var new_string = "" var new_string = ""
@ -138,7 +138,7 @@ func replace_variable(string, variable, value):
string = string.right(keyword_size) string = string.right(keyword_size)
return new_string return new_string
func subst(string, context, uv = ""): func subst(string, context, uv = "") -> Dictionary:
var genname = "o"+str(get_instance_id()) var genname = "o"+str(get_instance_id())
var required_globals = [] var required_globals = []
var required_defs = "" var required_defs = ""
@ -205,7 +205,7 @@ func subst(string, context, uv = ""):
cont = changed and new_pass_required cont = changed and new_pass_required
return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures } return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures }
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
uses_seed = false uses_seed = false
var genname = "o"+str(get_instance_id()) var genname = "o"+str(get_instance_id())
var output_info = [ { field="rgba", type="vec4" }, { field="rgb", type="vec3" }, { field="f", type="float" } ] var output_info = [ { field="rgba", type="vec4" }, { field="rgb", type="vec3" }, { field="f", type="float" } ]
@ -271,11 +271,11 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
rv.globals.push_back(shader_model.global) rv.globals.push_back(shader_model.global)
return rv return rv
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
data.shader_model = shader_model data.shader_model = shader_model
return data return data
func edit(node): func edit(node) -> void:
if shader_model != null: if shader_model != null:
var edit_window = load("res://addons/material_maker/widgets/node_editor/node_editor.tscn").instance() var edit_window = load("res://addons/material_maker/widgets/node_editor/node_editor.tscn").instance()
node.get_parent().add_child(edit_window) node.get_parent().add_child(edit_window)

View File

@ -8,20 +8,20 @@ Texture generator switch
var editable = false var editable = false
func get_type(): func get_type() -> String:
return "switch" return "switch"
func get_type_name(): func get_type_name() -> String:
return "Switch" return "Switch"
func toggle_editable(): func toggle_editable() -> bool:
editable = !editable editable = !editable
return true return true
func is_editable(): func is_editable() -> bool:
return editable return editable
func get_parameter_defs(): func get_parameter_defs() -> Array:
var choices = parameters.choices if parameters.has("choices") else 2 var choices = parameters.choices if parameters.has("choices") else 2
return [ return [
{ name="outputs", label="Outputs", type="float", min=1, max=5, step=1, default=2 }, { name="outputs", label="Outputs", type="float", min=1, max=5, step=1, default=2 },
@ -29,7 +29,7 @@ func get_parameter_defs():
{ name="source", label="Source", type="float", min=0, max=choices-1, step=1, default=0 }, { name="source", label="Source", type="float", min=0, max=choices-1, step=1, default=0 },
] ]
func get_input_defs(): func get_input_defs() -> Array:
var rv : Array = [] var rv : Array = []
for c in range(parameters.choices): for c in range(parameters.choices):
for o in range(parameters.outputs): for o in range(parameters.outputs):
@ -37,21 +37,21 @@ func get_input_defs():
rv.push_back({ name=n, label=n, type="rgba" }) rv.push_back({ name=n, label=n, type="rgba" })
return rv return rv
func get_output_defs(): func get_output_defs() -> Array:
var rv : Array = [] var rv : Array = []
for o in range(parameters.outputs): for o in range(parameters.outputs):
var n = PoolByteArray([65+o]).get_string_from_ascii() var n = PoolByteArray([65+o]).get_string_from_ascii()
rv.push_back({ name=n, type="rgba" }) rv.push_back({ name=n, type="rgba" })
return rv return rv
func set_parameter(p, v): func set_parameter(p, v) -> void:
.set_parameter(p, v) .set_parameter(p, v)
emit_signal("parameter_changed", "__update_all__", null) emit_signal("parameter_changed", "__update_all__", null)
func source_changed(input_index : int): func source_changed(input_index : int) -> void:
notify_output_change(input_index % int(parameters.outputs)) notify_output_change(input_index % int(parameters.outputs))
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var source = get_source(output_index+parameters.source*parameters.outputs) var source = get_source(output_index+parameters.source*parameters.outputs)
if source != null: if source != null:
var rv = source.generator._get_shader_code(uv, source.output_index, context) var rv = source.generator._get_shader_code(uv, source.output_index, context)
@ -60,5 +60,5 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext):
return rv return rv
return { globals=[], defs="", code="", textures={} } return { globals=[], defs="", code="", textures={} }
func _serialize(data): func _serialize(data: Dictionary) -> Dictionary:
return data return data

View File

@ -8,10 +8,10 @@ Base class for texture generators that provide a texture as output
var texture : ImageTexture = ImageTexture.new() var texture : ImageTexture = ImageTexture.new()
func get_output_defs(): func get_output_defs() -> Array:
return [ { rgba="" } ] return [ { rgba="" } ]
func _get_shader_code(uv : String, output_index : int, context : MMGenContext): func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var genname = "o"+str(get_instance_id()) var genname = "o"+str(get_instance_id())
var rv = { globals=[], defs="", code="" } var rv = { globals=[], defs="", code="" }
var texture_name = genname+"_tex" var texture_name = genname+"_tex"

View File

@ -17,7 +17,7 @@ static func load_gen(filename: String) -> MMGenBase:
return create_gen(data) return create_gen(data)
return null return null
static func add_to_gen_graph(gen_graph, generators, connections): static func add_to_gen_graph(gen_graph, generators, connections) -> Dictionary:
var rv = { generators=[], connections=[] } var rv = { generators=[], connections=[] }
var gennames = {} var gennames = {}
for n in generators: for n in generators:

View File

@ -8,10 +8,10 @@ var debug_file_index : int = 0
var rendering : bool = false var rendering : bool = false
signal done signal done
func _ready(): func _ready() -> void:
$ColorRect.material = $ColorRect.material.duplicate(true) $ColorRect.material = $ColorRect.material.duplicate(true)
static func generate_shader(src_code): static func generate_shader(src_code) -> String:
var code var code
code = "shader_type canvas_item;\n" code = "shader_type canvas_item;\n"
code += "render_mode blend_disabled;\n" code += "render_mode blend_disabled;\n"
@ -34,7 +34,7 @@ static func generate_shader(src_code):
code += shader_code code += shader_code
return code return code
static func generate_combined_shader(red_code, green_code, blue_code): static func generate_combined_shader(red_code, green_code, blue_code) -> String:
var code var code
code = "shader_type canvas_item;\n" code = "shader_type canvas_item;\n"
code += "render_mode blend_disabled;\n" code += "render_mode blend_disabled;\n"
@ -64,12 +64,12 @@ static func generate_combined_shader(red_code, green_code, blue_code):
code += shader_code code += shader_code
return code return code
func setup_material(shader_material, textures, shader_code): func setup_material(shader_material, textures, shader_code) -> void:
for k in textures.keys(): for k in textures.keys():
shader_material.set_shader_param(k+"_tex", textures[k]) shader_material.set_shader_param(k+"_tex", textures[k])
shader_material.shader.code = shader_code shader_material.shader.code = shader_code
func render_shader(shader, textures, render_size): func render_shader(shader, textures, render_size) -> Object:
if debug_path != null and debug_path != "": if debug_path != null and debug_path != "":
var file_name = debug_path+str(debug_file_index)+".shader" var file_name = debug_path+str(debug_file_index)+".shader"
var f = File.new() var f = File.new()
@ -95,19 +95,19 @@ func render_shader(shader, textures, render_size):
yield(get_tree(), "idle_frame") yield(get_tree(), "idle_frame")
return self return self
func copy_to_texture(t : ImageTexture): func copy_to_texture(t : ImageTexture) -> void:
var image : Image = get_texture().get_data() var image : Image = get_texture().get_data()
if image != null: if image != null:
image.lock() image.lock()
t.create_from_image(get_texture().get_data()) t.create_from_image(get_texture().get_data())
image.unlock() image.unlock()
func save_to_file(fn : String): func save_to_file(fn : String) -> void:
var image : Image = get_texture().get_data() var image : Image = get_texture().get_data()
image.lock() image.lock()
image.save_png(fn) image.save_png(fn)
image.unlock() image.unlock()
func release(): func release() -> void:
rendering = false rendering = false
emit_signal("done") emit_signal("done")

View File

@ -19,11 +19,11 @@ onready var subgraph_ui : HBoxContainer = $GraphUI/SubGraphUI
signal save_path_changed signal save_path_changed
signal graph_changed signal graph_changed
func _ready(): func _ready() -> void:
OS.low_processor_usage_mode = true OS.low_processor_usage_mode = true
center_view() center_view()
func _gui_input(event): func _gui_input(event) -> void:
if event is InputEventKey and event.pressed: if event is InputEventKey and event.pressed:
var scancode_with_modifiers = event.get_scancode_with_modifiers() var scancode_with_modifiers = event.get_scancode_with_modifiers()
if scancode_with_modifiers == KEY_DELETE || scancode_with_modifiers == KEY_BACKSPACE: if scancode_with_modifiers == KEY_DELETE || scancode_with_modifiers == KEY_BACKSPACE:
@ -36,10 +36,10 @@ func get_source(node, port):
if c.to == node and c.to_port == port: if c.to == node and c.to_port == port:
return { node=c.from, slot=c.from_port } return { node=c.from, slot=c.from_port }
func offset_from_global_position(global_position): func offset_from_global_position(global_position) -> Vector2:
return (scroll_offset + global_position - rect_global_position) / zoom return (scroll_offset + global_position - rect_global_position) / zoom
func add_node(node): func add_node(node) -> void:
add_child(node) add_child(node)
node.connect("close_request", self, "remove_node", [ node ]) node.connect("close_request", self, "remove_node", [ node ])
@ -51,12 +51,12 @@ func connect_node(from, from_slot, to, to_slot):
.connect_node(from, from_slot, to, to_slot) .connect_node(from, from_slot, to, to_slot)
send_changed_signal() send_changed_signal()
func disconnect_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): if generator.disconnect_children(get_node(from).generator, from_slot, get_node(to).generator, to_slot):
.disconnect_node(from, from_slot, to, to_slot) .disconnect_node(from, from_slot, to, to_slot)
send_changed_signal(); send_changed_signal();
func remove_node(node): func remove_node(node) -> void:
generator.remove_generator(node.generator) generator.remove_generator(node.generator)
var node_name = node.name var node_name = node.name
for c in get_connection_list(): for c in get_connection_list():
@ -67,7 +67,7 @@ func remove_node(node):
# Global operations on graph # Global operations on graph
func update_tab_title(): func update_tab_title() -> void:
if !get_parent().has_method("set_tab_title"): if !get_parent().has_method("set_tab_title"):
print("no set_tab_title method") print("no set_tab_title method")
return return
@ -79,18 +79,18 @@ func update_tab_title():
if get_parent().has_method("set_tab_title"): if get_parent().has_method("set_tab_title"):
get_parent().set_tab_title(get_index(), title) get_parent().set_tab_title(get_index(), title)
func set_need_save(ns): func set_need_save(ns) -> void:
if ns != need_save: if ns != need_save:
need_save = ns need_save = ns
update_tab_title() update_tab_title()
func set_save_path(path): func set_save_path(path) -> void:
if path != save_path: if path != save_path:
save_path = path save_path = path
update_tab_title() update_tab_title()
emit_signal("save_path_changed", self, path) emit_signal("save_path_changed", self, path)
func clear_view(): func clear_view() -> void:
clear_connections() clear_connections()
for c in get_children(): for c in get_children():
if c is GraphNode: if c is GraphNode:
@ -99,7 +99,7 @@ func clear_view():
# Center view # Center view
func center_view(): func center_view() -> void:
var center = Vector2(0, 0) var center = Vector2(0, 0)
var node_count = 0 var node_count = 0
for c in get_children(): for c in get_children():
@ -110,7 +110,7 @@ func center_view():
center /= node_count center /= node_count
scroll_offset = center - 0.5*rect_size scroll_offset = center - 0.5*rect_size
func update_view(g): func update_view(g) -> void:
clear_view() clear_view()
generator = g generator = g
update_graph(generator.get_children(), generator.connections) update_graph(generator.get_children(), generator.connections)
@ -118,7 +118,7 @@ func update_view(g):
subgraph_ui.get_node("Label").text = generator.label subgraph_ui.get_node("Label").text = generator.label
center_view() center_view()
func clear_material(): func clear_material() -> void:
if top_generator != null: if top_generator != null:
remove_child(top_generator) remove_child(top_generator)
top_generator.free() top_generator.free()
@ -126,7 +126,7 @@ func clear_material():
generator = null generator = null
send_changed_signal() send_changed_signal()
func update_graph(generators, connections): func update_graph(generators, connections) -> Array:
var rv = [] var rv = []
for g in generators: for g in generators:
var node = node_factory.create_node(g.get_type()) var node = node_factory.create_node(g.get_type())
@ -140,7 +140,7 @@ func update_graph(generators, connections):
.connect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port) .connect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port)
return rv return rv
func new_material(): 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"}], connections=[]})
@ -171,10 +171,10 @@ func create_nodes(data, position : Vector2 = Vector2(0, 0)):
return update_graph(new_stuff.generators, new_stuff.connections) return update_graph(new_stuff.generators, new_stuff.connections)
return [] return []
func create_gen_from_type(gen_name): func create_gen_from_type(gen_name) -> void:
create_nodes({ type=gen_name, parameters={} }, scroll_offset+0.5*rect_size) create_nodes({ type=gen_name, parameters={} }, scroll_offset+0.5*rect_size)
func load_file(filename): func load_file(filename) -> void:
clear_material() clear_material()
top_generator = MMGenLoader.load_gen(filename) top_generator = MMGenLoader.load_gen(filename)
if top_generator != null: if top_generator != null:
@ -184,7 +184,7 @@ func load_file(filename):
set_need_save(false) set_need_save(false)
center_view() center_view()
func save_file(filename): func save_file(filename) -> void:
var data = top_generator.serialize() var data = top_generator.serialize()
var file = File.new() var file = File.new()
if file.open(filename, File.WRITE) == OK: if file.open(filename, File.WRITE) == OK:
@ -193,7 +193,7 @@ func save_file(filename):
set_save_path(filename) set_save_path(filename)
set_need_save(false) set_need_save(false)
func export_textures(): func export_textures() -> void:
if save_path != null: if save_path != null:
var prefix = save_path.left(save_path.rfind(".")) var prefix = save_path.left(save_path.rfind("."))
for c in get_children(): for c in get_children():
@ -202,27 +202,27 @@ func export_textures():
# Cut / copy / paste # Cut / copy / paste
func get_selected_nodes(): func get_selected_nodes() -> Array:
var selected_nodes = [] var selected_nodes = []
for n in get_children(): for n in get_children():
if n is GraphNode and n.selected: if n is GraphNode and n.selected:
selected_nodes.append(n) selected_nodes.append(n)
return selected_nodes return selected_nodes
func remove_selection(): func remove_selection() -> void:
for c in get_children(): for c in get_children():
if c is GraphNode and c.selected and c.name != "Material": if c is GraphNode and c.selected and c.name != "Material":
remove_node(c) remove_node(c)
# Maybe move this to gen_graph... # Maybe move this to gen_graph...
func serialize_selection(): func serialize_selection() -> Dictionary:
var data = { nodes = [], connections = [] } var data = { nodes = [], connections = [] }
var nodes = [] var nodes = []
for c in get_children(): for c in get_children():
if c is GraphNode and c.selected and c.name != "Material": if c is GraphNode and c.selected and c.name != "Material":
nodes.append(c) nodes.append(c)
if nodes.empty(): if nodes.empty():
return null return {}
var center = Vector2(0, 0) var center = Vector2(0, 0)
for n in nodes: for n in nodes:
center += n.offset+0.5*n.rect_size center += n.offset+0.5*n.rect_size
@ -242,20 +242,20 @@ func serialize_selection():
data.connections.append(connection) data.connections.append(connection)
return data return data
func can_copy(): func can_copy() -> bool:
for c in get_children(): for c in get_children():
if c is GraphNode and c.selected and c.name != "Material": if c is GraphNode and c.selected and c.name != "Material":
return true return true
return false return false
func cut(): func cut() -> void:
copy() copy()
remove_selection() remove_selection()
func copy(): func copy() -> void:
OS.clipboard = to_json(serialize_selection()) OS.clipboard = to_json(serialize_selection())
func paste(pos = Vector2(0, 0)): func paste(pos = Vector2(0, 0)) -> void:
for c in get_children(): for c in get_children():
if c is GraphNode: if c is GraphNode:
c.selected = false c.selected = false
@ -265,42 +265,41 @@ func paste(pos = Vector2(0, 0)):
# Delay after graph update # Delay after graph update
func send_changed_signal(): func send_changed_signal() -> void:
set_need_save(true) set_need_save(true)
timer.start(0.1) timer.start(0.1)
func do_send_changed_signal(): func do_send_changed_signal() -> void:
emit_signal("graph_changed") emit_signal("graph_changed")
# Drag and drop # Drag and drop
func can_drop_data(position, data): func can_drop_data(position, data) -> bool:
return typeof(data) == TYPE_DICTIONARY and (data.has('type') or (data.has('nodes') and data.has('connections'))) return typeof(data) == TYPE_DICTIONARY and (data.has('type') or (data.has('nodes') and data.has('connections')))
func drop_data(position, data): func drop_data(position, data) -> void:
# The following mitigates the SpinBox problem (captures mouse while dragging) # The following mitigates the SpinBox problem (captures mouse while dragging)
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
create_nodes(data, offset_from_global_position(get_global_transform().xform(position))) create_nodes(data, offset_from_global_position(get_global_transform().xform(position)))
return true
func on_ButtonUp_pressed(): func on_ButtonUp_pressed() -> void:
if generator != top_generator && generator.get_parent() is MMGenGraph: if generator != top_generator && generator.get_parent() is MMGenGraph:
call_deferred("update_view", generator.get_parent()) call_deferred("update_view", generator.get_parent())
func _on_Label_text_changed(new_text): func _on_Label_text_changed(new_text) -> void:
generator.label = new_text generator.label = new_text
# Create subgraph # Create subgraph
func create_subgraph(): func create_subgraph() -> void:
var generators = [] var generators = []
for n in get_selected_nodes(): for n in get_selected_nodes():
generators.push_back(n.generator) generators.push_back(n.generator)
generator.create_subgraph(generators) generator.create_subgraph(generators)
update_view(generator) update_view(generator)
func _on_ButtonShowTree_pressed(): func _on_ButtonShowTree_pressed() -> void:
var graph_tree : Popup = preload("res://addons/material_maker/widgets/graph_tree/graph_tree.tscn").instance() var graph_tree : Popup = preload("res://addons/material_maker/widgets/graph_tree/graph_tree.tscn").instance()
graph_tree.init("Top", top_generator) graph_tree.init("Top", top_generator)
add_child(graph_tree) add_child(graph_tree)

View File

@ -9,40 +9,40 @@ const PRESET_OPTIONS = [
[{ name="skip", default_value=false }] [{ name="skip", default_value=false }]
] ]
func _init(p): func _init(p) -> void:
plugin = p plugin = p
func get_import_options(preset : int): func get_import_options(preset : int) -> Array:
return PRESET_OPTIONS[preset] return PRESET_OPTIONS[preset]
func get_import_order(): func get_import_order() -> int:
return 1 return 1
func get_importer_name(): func get_importer_name() -> String:
return "material_maker.import" return "material_maker.import"
func get_option_visibility(option: String, options: Dictionary): func get_option_visibility(option: String, options: Dictionary) -> bool:
return true return true
func get_preset_count(): func get_preset_count() -> int:
return 2 return 2
func get_preset_name(preset: int) -> String: func get_preset_name(preset: int) -> String:
return PRESET_NAMES[preset] return PRESET_NAMES[preset]
func get_priority(): func get_priority() -> float:
return 0.1 return 0.1
func get_recognized_extensions(): func get_recognized_extensions() -> Array:
return [ "ptex" ] return [ "ptex" ]
func get_resource_type(): func get_resource_type() -> String:
return "Material" return "Material"
func get_save_extension(): func get_save_extension() -> String:
return "tres" return "tres"
func get_visible_name(): func get_visible_name() -> String:
return "Material Maker Importer" return "Material Maker Importer"
func import(source_file: String, save_path: String, options: Dictionary, platform_variants: Array, gen_files: Array) -> int: func import(source_file: String, save_path: String, options: Dictionary, platform_variants: Array, gen_files: Array) -> int:

View File

@ -6,7 +6,7 @@ var libraries = []
onready var tree : Tree = $Tree onready var tree : Tree = $Tree
onready var filter_line_edit : LineEdit = $HBoxContainer/Filter onready var filter_line_edit : LineEdit = $HBoxContainer/Filter
func _ready(): func _ready() -> void:
tree.set_column_expand(0, true) tree.set_column_expand(0, true)
tree.set_column_expand(1, false) tree.set_column_expand(1, false)
tree.set_column_min_width(1, 32) tree.set_column_min_width(1, 32)
@ -21,7 +21,7 @@ func _unhandled_input(event : InputEvent) -> void:
filter_line_edit.grab_focus() filter_line_edit.grab_focus()
filter_line_edit.select_all() filter_line_edit.select_all()
func get_selected_item_name(): func get_selected_item_name() -> String:
var tree_item : TreeItem = tree.get_selected() var tree_item : TreeItem = tree.get_selected()
var rv = "" var rv = ""
while tree_item != null and tree_item != tree.get_root(): while tree_item != null and tree_item != tree.get_root():
@ -32,7 +32,7 @@ func get_selected_item_name():
tree_item = tree_item.get_parent() tree_item = tree_item.get_parent()
return rv return rv
func add_library(file_name : String, filter : String = ""): func add_library(file_name : String, filter : String = "") -> bool:
var root = tree.get_root() var root = tree.get_root()
var file = File.new() var file = File.new()
if file.open(file_name, File.READ) != OK: if file.open(file_name, File.READ) != OK:
@ -46,7 +46,7 @@ func add_library(file_name : String, filter : String = ""):
return true return true
return false return false
func update_tree(filter : String = ""): func update_tree(filter : String = "") -> void:
filter = filter.to_lower() filter = filter.to_lower()
tree.clear() tree.clear()
var root = tree.create_item() var root = tree.create_item()
@ -55,12 +55,12 @@ func update_tree(filter : String = ""):
if filter == "" or m.tree_item.to_lower().find(filter) != -1: if filter == "" or m.tree_item.to_lower().find(filter) != -1:
add_item(m, m.tree_item, get_preview_texture(m), null, filter != "") add_item(m, m.tree_item, get_preview_texture(m), null, filter != "")
func get_preview_texture(data : Dictionary): 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 image_path.left(6) == "res://":
return load(image_path) return load(image_path) as ImageTexture
else: else:
t = ImageTexture.new() t = ImageTexture.new()
var image : Image = Image.new() var image : Image = Image.new()
@ -69,7 +69,7 @@ func get_preview_texture(data : Dictionary):
return t return t
return null return null
func add_item(item, item_name, item_icon = null, item_parent = null, force_expand = false): func add_item(item, item_name, item_icon = null, item_parent = null, force_expand = false) -> TreeItem:
if item_parent == null: if item_parent == null:
item.tree_item = item_name item.tree_item = item_name
item_parent = tree.get_root() item_parent = tree.get_root()
@ -110,7 +110,7 @@ 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): func serialize_library(array, library_name = null, item = null) -> void:
if item == null: if item == null:
item = tree.get_root() item = tree.get_root()
item = item.get_children() item = item.get_children()
@ -121,7 +121,7 @@ func serialize_library(array, library_name = null, item = null):
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): func save_library(library_name, item = null) -> void:
var array = [] var array = []
serialize_library(array, library_name) serialize_library(array, library_name)
var file = File.new() var file = File.new()
@ -129,5 +129,5 @@ func save_library(library_name, item = null):
file.store_string(to_json({lib=array})) file.store_string(to_json({lib=array}))
file.close() file.close()
func _on_Filter_text_changed(filter): func _on_Filter_text_changed(filter) -> void:
update_tree(filter) update_tree(filter)

View File

@ -21,5 +21,5 @@ func get_drag_data(position):
preview = Label.new() preview = Label.new()
preview.text = data.tree_item preview.text = data.tree_item
set_drag_preview(preview) set_drag_preview(preview)
return data return data
return null return null

View File

@ -44,10 +44,10 @@ signal quit
var is_mac = false var is_mac = false
func _ready(): func _ready() -> void:
if OS.get_name() == "OSX": if OS.get_name() == "OSX":
is_mac = true is_mac = true
# In HTML5 export, copy all examples to the filesystem # In HTML5 export, copy all examples to the filesystem
if OS.get_name() == "HTML5": if OS.get_name() == "HTML5":
print("Copying samples") print("Copying samples")
@ -63,6 +63,7 @@ func _ready():
print(f) print(f)
dir.copy("res://addons/material_maker/examples/"+f, "/examples/"+f) dir.copy("res://addons/material_maker/examples/"+f, "/examples/"+f)
print("Done") print("Done")
# Upscale everything if the display requires it (crude hiDPI support). # Upscale everything if the display requires it (crude hiDPI support).
# This prevents UI elements from being too small on hiDPI displays. # This prevents UI elements from being too small on hiDPI displays.
if OS.get_screen_dpi() >= 192 and OS.get_screen_size().x >= 2048: if OS.get_screen_dpi() >= 192 and OS.get_screen_size().x >= 2048:
@ -87,7 +88,7 @@ func get_current_graph_edit() -> MMGraphEdit:
return graph_edit return graph_edit
return null return null
func create_menu(menu, menu_name): func create_menu(menu, menu_name) -> PopupMenu:
menu.clear() menu.clear()
menu.connect("id_pressed", self, "_on_PopupMenu_id_pressed") menu.connect("id_pressed", self, "_on_PopupMenu_id_pressed")
for i in MENU.size(): for i in MENU.size():
@ -121,23 +122,23 @@ func create_menu(menu, menu_name):
menu.add_separator() menu.add_separator()
return menu return menu
func create_menu_load_recent(menu): func create_menu_load_recent(menu) -> void:
menu.clear() menu.clear()
for i in recent_files.size(): for i in recent_files.size():
menu.add_item(recent_files[i], i) menu.add_item(recent_files[i], i)
if !menu.is_connected("id_pressed", self, "_on_LoadRecent_id_pressed"): if !menu.is_connected("id_pressed", self, "_on_LoadRecent_id_pressed"):
menu.connect("id_pressed", self, "_on_LoadRecent_id_pressed") menu.connect("id_pressed", self, "_on_LoadRecent_id_pressed")
func _on_LoadRecent_id_pressed(id): func _on_LoadRecent_id_pressed(id) -> void:
do_load_material(recent_files[id]) do_load_material(recent_files[id])
func load_recents(): func load_recents() -> void:
var f = File.new() var f = File.new()
if f.open("user://recent_files.bin", File.READ) == OK: if f.open("user://recent_files.bin", File.READ) == OK:
recent_files = parse_json(f.get_as_text()) recent_files = parse_json(f.get_as_text())
f.close() f.close()
func add_recent(path): func add_recent(path) -> void:
while true: while true:
var index = recent_files.find(path) var index = recent_files.find(path)
if index >= 0: if index >= 0:
@ -150,7 +151,7 @@ func add_recent(path):
f.store_string(to_json(recent_files)) f.store_string(to_json(recent_files))
f.close() f.close()
func create_menu_create(menu): func create_menu_create(menu) -> void:
var gens = MMGenLoader.get_generator_list() var gens = MMGenLoader.get_generator_list()
menu.clear() menu.clear()
for i in gens.size(): for i in gens.size():
@ -158,13 +159,13 @@ func create_menu_create(menu):
if !menu.is_connected("id_pressed", self, "_on_Create_id_pressed"): if !menu.is_connected("id_pressed", self, "_on_Create_id_pressed"):
menu.connect("id_pressed", self, "_on_Create_id_pressed") menu.connect("id_pressed", self, "_on_Create_id_pressed")
func _on_Create_id_pressed(id): func _on_Create_id_pressed(id) -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
var gens = MMGenLoader.get_generator_list() var gens = MMGenLoader.get_generator_list()
graph_edit.create_gen_from_type(gens[id]) graph_edit.create_gen_from_type(gens[id])
func menu_about_to_show(name, menu): func menu_about_to_show(name, menu) -> void:
for i in MENU.size(): for i in MENU.size():
if MENU[i].menu != name: if MENU[i].menu != name:
continue continue
@ -176,21 +177,21 @@ func menu_about_to_show(name, menu):
var is_disabled = call(command_name) var is_disabled = call(command_name)
menu.set_item_disabled(menu.get_item_index(i), is_disabled) menu.set_item_disabled(menu.get_item_index(i), is_disabled)
func new_pane(): func new_pane() -> GraphEdit:
var graph_edit = preload("res://addons/material_maker/graph_edit.tscn").instance() var graph_edit = preload("res://addons/material_maker/graph_edit.tscn").instance()
graph_edit.node_factory = $NodeFactory graph_edit.node_factory = $NodeFactory
graph_edit.renderer = $Renderer graph_edit.renderer = $Renderer
graph_edit.editor_interface = editor_interface graph_edit.editor_interface = editor_interface
projects.add_child(graph_edit) projects.add_child(graph_edit)
projects.current_tab = graph_edit.get_index() projects.current_tab = graph_edit.get_index()
return graph_edit return graph_edit
func new_material(): func new_material() -> void:
var graph_edit = new_pane() var graph_edit = new_pane()
graph_edit.new_material() graph_edit.new_material()
graph_edit.update_tab_title() graph_edit.update_tab_title()
func load_material(): func load_material() -> void:
var dialog = FileDialog.new() var dialog = FileDialog.new()
add_child(dialog) add_child(dialog)
dialog.rect_min_size = Vector2(500, 500) dialog.rect_min_size = Vector2(500, 500)
@ -200,11 +201,11 @@ func load_material():
dialog.connect("files_selected", self, "do_load_materials") dialog.connect("files_selected", self, "do_load_materials")
dialog.popup_centered() dialog.popup_centered()
func do_load_materials(filenames): func do_load_materials(filenames) -> void:
for f in filenames: for f in filenames:
do_load_material(f) do_load_material(f)
func do_load_material(filename): func do_load_material(filename) -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
var node_count = 2 # So test below succeeds if graph_edit is null... var node_count = 2 # So test below succeeds if graph_edit is null...
if graph_edit != null: if graph_edit != null:
@ -219,7 +220,7 @@ func do_load_material(filename):
graph_edit.load_file(filename) graph_edit.load_file(filename)
add_recent(filename) add_recent(filename)
func save_material(): func save_material() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
if graph_edit.save_path != null: if graph_edit.save_path != null:
@ -227,7 +228,7 @@ func save_material():
else: else:
save_material_as() save_material_as()
func save_material_as(): func save_material_as() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
var dialog = FileDialog.new() var dialog = FileDialog.new()
@ -239,81 +240,79 @@ func save_material_as():
dialog.connect("file_selected", graph_edit, "save_file") dialog.connect("file_selected", graph_edit, "save_file")
dialog.popup_centered() dialog.popup_centered()
func close_material(): func close_material() -> void:
projects.close_tab() projects.close_tab()
func export_material(): func export_material() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null : if graph_edit != null :
graph_edit.export_textures() graph_edit.export_textures()
func export_material_is_disabled(): func export_material_is_disabled() -> bool:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit == null or graph_edit.save_path == null: return graph_edit == null or graph_edit.save_path == null
return true
return false
func quit(): func quit() -> void:
if Engine.editor_hint: if Engine.editor_hint:
emit_signal("quit") emit_signal("quit")
else: else:
get_tree().quit() get_tree().quit()
func edit_cut(): func edit_cut() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
graph_edit.cut() graph_edit.cut()
func edit_cut_is_disabled(): func edit_cut_is_disabled() -> bool:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
return graph_edit == null or !graph_edit.can_copy() return graph_edit == null or !graph_edit.can_copy()
func edit_copy(): func edit_copy() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
graph_edit.copy() graph_edit.copy()
func edit_copy_is_disabled(): func edit_copy_is_disabled() -> bool:
return edit_cut_is_disabled() return edit_cut_is_disabled()
func edit_paste(): func edit_paste() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
graph_edit.paste() graph_edit.paste()
func edit_paste_is_disabled(): func edit_paste_is_disabled() -> bool:
var data = parse_json(OS.clipboard) var data = parse_json(OS.clipboard)
return data == null return data == null
func view_center(): func view_center() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
graph_edit.center_view() graph_edit.center_view()
func view_reset_zoom(): func view_reset_zoom() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
graph_edit.zoom = 1 graph_edit.zoom = 1
func get_selected_nodes():
func get_selected_nodes() -> Array:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
return graph_edit.get_selected_nodes() return graph_edit.get_selected_nodes()
else: else:
return [] return []
func create_subgraph(): func create_subgraph() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
graph_edit.create_subgraph() graph_edit.create_subgraph()
func make_selected_nodes_editable(): func make_selected_nodes_editable() -> void:
var selected_nodes = get_selected_nodes() var selected_nodes = get_selected_nodes()
if !selected_nodes.empty(): if !selected_nodes.empty():
for n in selected_nodes: for n in selected_nodes:
if n.generator.toggle_editable(): if n.generator.toggle_editable():
n.update_node() n.update_node()
func add_to_user_library(): func add_to_user_library() -> void:
var selected_nodes = get_selected_nodes() var selected_nodes = get_selected_nodes()
if !selected_nodes.empty(): if !selected_nodes.empty():
var dialog = preload("res://addons/material_maker/widgets/line_dialog.tscn").instance() var dialog = preload("res://addons/material_maker/widgets/line_dialog.tscn").instance()
@ -323,7 +322,7 @@ func add_to_user_library():
dialog.connect("ok", self, "do_add_to_user_library", [ selected_nodes ]) dialog.connect("ok", self, "do_add_to_user_library", [ selected_nodes ])
dialog.popup_centered() dialog.popup_centered()
func do_add_to_user_library(name, nodes): func do_add_to_user_library(name, nodes) -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
var data var data
if nodes.size() == 1: if nodes.size() == 1:
@ -343,11 +342,11 @@ func do_add_to_user_library(name, nodes):
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(): func save_user_library() -> void:
print("Saving user library") print("Saving user library")
library.save_library("user://library/user.json") library.save_library("user://library/user.json")
func show_doc(): func show_doc() -> void:
var base_dir = OS.get_executable_path().replace("\\", "/").get_base_dir() var base_dir = OS.get_executable_path().replace("\\", "/").get_base_dir()
# In release builds, documentation is expected to be located in # In release builds, documentation is expected to be located in
@ -369,15 +368,15 @@ func show_doc():
# Open online documentation # Open online documentation
OS.shell_open("https://rodzill4.github.io/godot-procedural-textures/doc/") OS.shell_open("https://rodzill4.github.io/godot-procedural-textures/doc/")
func bug_report(): func bug_report() -> void:
OS.shell_open("https://github.com/RodZill4/godot-procedural-textures/issues") OS.shell_open("https://github.com/RodZill4/godot-procedural-textures/issues")
func about(): func about() -> void:
var about_box = preload("res://addons/material_maker/widgets/about/about.tscn").instance() var about_box = preload("res://addons/material_maker/widgets/about/about.tscn").instance()
add_child(about_box) add_child(about_box)
about_box.popup_centered() about_box.popup_centered()
func _on_PopupMenu_id_pressed(id): func _on_PopupMenu_id_pressed(id) -> void:
var node_type = null var node_type = null
if MENU[id].has("command"): if MENU[id].has("command"):
var command = MENU[id].command var command = MENU[id].command
@ -386,11 +385,11 @@ func _on_PopupMenu_id_pressed(id):
# Preview # Preview
func update_preview(): func update_preview() -> void:
update_preview_2d() update_preview_2d()
update_preview_3d() update_preview_3d()
func update_preview_2d(node = null): func update_preview_2d(node = null) -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null: if graph_edit != null:
var preview = $VBoxContainer/HBoxContainer/VBoxContainer/Preview var preview = $VBoxContainer/HBoxContainer/VBoxContainer/Preview
@ -408,7 +407,7 @@ func update_preview_2d(node = null):
result.release() result.release()
preview.set_2d(tex) preview.set_2d(tex)
func update_preview_3d(): func update_preview_3d() -> void:
var graph_edit : MMGraphEdit = get_current_graph_edit() var graph_edit : MMGraphEdit = get_current_graph_edit()
if graph_edit != null and graph_edit.top_generator != null and graph_edit.top_generator.has_node("Material"): if graph_edit != null and graph_edit.top_generator != null and graph_edit.top_generator.has_node("Material"):
var gen_material = graph_edit.top_generator.get_node("Material") var gen_material = graph_edit.top_generator.get_node("Material")
@ -417,7 +416,7 @@ func update_preview_3d():
status = yield(status, "completed") status = yield(status, "completed")
gen_material.update_materials($VBoxContainer/HBoxContainer/VBoxContainer/Preview.get_materials()) gen_material.update_materials($VBoxContainer/HBoxContainer/VBoxContainer/Preview.get_materials())
func _on_Projects_tab_changed(tab): func _on_Projects_tab_changed(tab) -> void:
var new_tab = projects.get_current_tab_control() var new_tab = projects.get_current_tab_control()
if new_tab != current_tab: if new_tab != current_tab:
if new_tab != null: if new_tab != null:
@ -429,7 +428,7 @@ func _on_Projects_tab_changed(tab):
current_tab = new_tab current_tab = new_tab
update_preview() update_preview()
func _on_Preview_show_background_preview(v): func _on_Preview_show_background_preview(v) -> void:
var pv = $VBoxContainer/HBoxContainer/VBoxContainer/Preview/MaterialPreview var pv = $VBoxContainer/HBoxContainer/VBoxContainer/Preview/MaterialPreview
var bgpv = $VBoxContainer/HBoxContainer/ProjectsPane/BackgroundPreview/Viewport var bgpv = $VBoxContainer/HBoxContainer/ProjectsPane/BackgroundPreview/Viewport
bgpv.world = pv.find_world() bgpv.world = pv.find_world()

View File

@ -5,17 +5,17 @@ extends GraphNode
class OutPort: class OutPort:
var node = null var node = null
var port = null var port = null
func get_shader_code(uv): func get_shader_code(uv) -> String:
return node.get_shader_code(uv, port) return node.get_shader_code(uv, port)
func generate_shader(): func generate_shader() -> String:
return node.generate_shader(port) return node.generate_shader(port)
func get_globals(): func get_globals() -> String:
return node.get_globals() return node.get_globals()
func get_textures(): func get_textures() -> Dictionary:
return node.get_textures() return node.get_textures()
var generated = false var generated = false
@ -113,7 +113,7 @@ func get_source(index = 0):
return out_port return out_port
return null return null
func get_source_f(source): func get_source_f(source) -> String:
var rv var rv
if source.has("f"): if source.has("f"):
rv = source.f rv = source.f
@ -123,7 +123,7 @@ func get_source_f(source):
rv = "***error***" rv = "***error***"
return rv return rv
func get_source_rgb(source): func get_source_rgb(source) -> String:
var rv var rv
if source.has("rgb") or source.has("rgba"): if source.has("rgb") or source.has("rgba"):
rv = source.rgb rv = source.rgb
@ -133,7 +133,7 @@ func get_source_rgb(source):
rv = "***error***" rv = "***error***"
return rv return rv
func get_source_rgba(source): func get_source_rgba(source) -> String:
var rv var rv
if source.has("rgba"): if source.has("rgba"):
rv = source.rgba rv = source.rgba
@ -145,14 +145,14 @@ func get_source_rgba(source):
rv = "***error***" rv = "***error***"
return rv return rv
func reset(): func reset() -> void:
generated = false generated = false
generated_variants = [] generated_variants = []
func _get_shader_code(uv, slot = 0): func _get_shader_code(uv, slot = 0) -> Dictionary:
pass return {}
func get_shader_code(uv, slot = 0): func get_shader_code(uv, slot = 0) -> String:
var rv var rv
if slot == 0: if slot == 0:
rv = _get_shader_code(uv) rv = _get_shader_code(uv)
@ -174,12 +174,12 @@ func get_shader_code(uv, slot = 0):
rv.rgba = "vec4("+rv.rgb+", 1.0)" rv.rgba = "vec4("+rv.rgb+", 1.0)"
return rv return rv
func get_shader_code_with_globals(uv, slot = 0): func get_shader_code_with_globals(uv, slot = 0) -> String:
var code = get_shader_code(uv, slot) var code = get_shader_code(uv, slot)
code.globals = get_globals() code.globals = get_globals()
return code return code
func get_globals(): func get_globals() -> Array:
var list = [] var list = []
for i in range(get_connection_input_count()): for i in range(get_connection_input_count()):
var source = get_source(i) var source = get_source(i)
@ -189,8 +189,8 @@ func get_globals():
if list.find(g) == -1: if list.find(g) == -1:
list.append(g) list.append(g)
return list return list
func get_textures(): func get_textures() -> Dictionary:
var list = {} var list = {}
for i in range(get_connection_input_count()): for i in range(get_connection_input_count()):
var source = get_source(i) var source = get_source(i)
@ -204,7 +204,7 @@ func serialize_element(e):
if typeof(e) == TYPE_COLOR: if typeof(e) == TYPE_COLOR:
return { type= "Color", r=e.r, g=e.g, b=e.b, a=e.a } return { type= "Color", r=e.r, g=e.g, b=e.b, a=e.a }
return e return e
func deserialize_element(e): func deserialize_element(e):
if typeof(e) == TYPE_DICTIONARY: if typeof(e) == TYPE_DICTIONARY:
if e.has("type") and e.type == "Color": if e.has("type") and e.type == "Color":
@ -215,7 +215,7 @@ func deserialize_element(e):
return gradient return gradient
return e return e
func generate_shader(slot = 0): func generate_shader(slot = 0) -> String:
# Reset all nodes # Reset all nodes
for c in get_parent().get_children(): for c in get_parent().get_children():
if c is GraphNode: if c is GraphNode:
@ -247,19 +247,19 @@ func deserialize(data):
# Render targets again for multipass filters # Render targets again for multipass filters
func rerender_targets(): func rerender_targets() -> void:
for c in get_parent().get_connection_list(): for c in get_parent().get_connection_list():
if c.from == name: if c.from == name:
var node = get_parent().get_node(c.to) var node = get_parent().get_node(c.to)
if node != null and node is GraphNode: if node != null and node is GraphNode:
node._rerender() node._rerender()
func _rerender(): func _rerender() -> void:
rerender_targets() rerender_targets()
# Generic code for convolution nodes # Generic code for convolution nodes
func get_convolution_shader(convolution): func get_convolution_shader(convolution) -> String:
var shader_code var shader_code
shader_code = "shader_type canvas_item;\n" shader_code = "shader_type canvas_item;\n"
shader_code += "uniform sampler2D input_tex;\n" shader_code += "uniform sampler2D input_tex;\n"
@ -288,9 +288,9 @@ func get_convolution_shader(convolution):
shader_code += "color += vec3(%.9f, %.9f, %.9f);\n" % [ convolution.translate.x, convolution.translate.y, convolution.translate.z ] shader_code += "color += vec3(%.9f, %.9f, %.9f);\n" % [ convolution.translate.x, convolution.translate.y, convolution.translate.z ]
shader_code += "COLOR = vec4(color, 1.0);\n" shader_code += "COLOR = vec4(color, 1.0);\n"
shader_code += "}\n" shader_code += "}\n"
return shader_code; return shader_code
func get_shader_code_convolution(src, convolution, uv): func get_shader_code_convolution(src, convolution, uv) -> String:
var rv = { defs="", code="" } var rv = { defs="", code="" }
var variant_index = generated_variants.find(uv) var variant_index = generated_variants.find(uv)
var need_defs = false var need_defs = false

View File

@ -3,10 +3,7 @@ extends Node
var includes var includes
func _ready(): func create_node(type) -> Node:
pass
func create_node(type):
var node = null var node = null
var file_name = "res://addons/material_maker/nodes/"+type+".tscn" var file_name = "res://addons/material_maker/nodes/"+type+".tscn"
if ResourceLoader.exists(file_name): if ResourceLoader.exists(file_name):

View File

@ -12,7 +12,7 @@ const DIRECTIONS = [
{ name="Y", mask=DIRECTION_V } { name="Y", mask=DIRECTION_V }
] ]
func _ready(): func _ready() -> void:
# init size widget # init size widget
$HBoxContainer1/size.clear() $HBoxContainer1/size.clear()
for i in range(7): for i in range(7):
@ -26,7 +26,7 @@ func _ready():
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction, $HBoxContainer3/sigma ]) initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction, $HBoxContainer3/sigma ])
saved_texture = ImageTexture.new() saved_texture = ImageTexture.new()
func get_gaussian_blur_shader(horizontal): func get_gaussian_blur_shader(horizontal) -> String:
var convolution = { x=0, y=0, kernel=[], epsilon=1.0/pow(2, 5+parameters.size) } var convolution = { x=0, y=0, kernel=[], epsilon=1.0/pow(2, 5+parameters.size) }
var kernel_size = 50 var kernel_size = 50
if horizontal: if horizontal:
@ -43,27 +43,27 @@ func get_gaussian_blur_shader(horizontal):
convolution.kernel[x+kernel_size] /= sum convolution.kernel[x+kernel_size] /= sum
return get_convolution_shader(convolution) return get_convolution_shader(convolution)
func _rerender(): func _rerender() -> void:
if DIRECTIONS[parameters.direction].mask & DIRECTION_H != 0: if DIRECTIONS[parameters.direction].mask & DIRECTION_H != 0:
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_1", []) get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_1", [])
else: else:
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", []) get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", [])
func pass_1(): func pass_1() -> void:
if DIRECTIONS[parameters.direction].mask & DIRECTION_V != 0: if DIRECTIONS[parameters.direction].mask & DIRECTION_V != 0:
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", []) get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "pass_2", [])
else: else:
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", []) get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(true), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", [])
func pass_2(): func pass_2() -> void:
get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(false), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", []) get_parent().renderer.precalculate_shader(get_gaussian_blur_shader(false), { input=saved_texture }, int(pow(2, 5+parameters.size)), saved_texture, self, "rerender_targets", [])
func get_textures(): func get_textures() -> Dictionary:
var list = {} var list = {}
list[name] = saved_texture list[name] = saved_texture
return list return list
func _get_shader_code(uv, slot = 0): func _get_shader_code(uv, slot = 0) -> Dictionary:
var rv = { defs="", code="" } var rv = { defs="", code="" }
var src = get_source() var src = get_source()
if src == null: if src == null:

View File

@ -6,16 +6,16 @@ var generator = null setget set_generator
onready var label = $VBox/Label onready var label = $VBox/Label
onready var editor = $VBox/TextEdit onready var editor = $VBox/TextEdit
func set_generator(g): func set_generator(g) -> void:
generator = g generator = g
label.text = generator.text label.text = generator.text
rect_size = generator.size rect_size = generator.size
func _on_resize_request(new_size): func _on_resize_request(new_size) -> void:
rect_size = new_size rect_size = new_size
generator.size = new_size generator.size = new_size
func _on_Label_gui_input(ev): func _on_Label_gui_input(ev) -> void:
if ev is InputEventMouseButton and ev.doubleclick and ev.button_index == BUTTON_LEFT: if ev is InputEventMouseButton and ev.doubleclick and ev.button_index == BUTTON_LEFT:
editor.rect_min_size = label.rect_size + Vector2(0, rect_size.y - get_minimum_size().y) editor.rect_min_size = label.rect_size + Vector2(0, rect_size.y - get_minimum_size().y)
editor.text = label.text editor.text = label.text
@ -24,7 +24,7 @@ func _on_Label_gui_input(ev):
editor.select_all() editor.select_all()
editor.grab_focus() editor.grab_focus()
func _on_TextEdit_focus_exited(): func _on_TextEdit_focus_exited() -> void:
label.text = editor.text label.text = editor.text
generator.text = editor.text generator.text = editor.text
label.visible = true label.visible = true

View File

@ -1,7 +1,7 @@
tool tool
extends HBoxContainer extends HBoxContainer
func connect_buttons(object, edit_fct, load_fct, save_fct): func connect_buttons(object, edit_fct, load_fct, save_fct) -> void:
$Edit.connect("pressed", object, edit_fct) $Edit.connect("pressed", object, edit_fct)
$Load.connect("pressed", object, load_fct) $Load.connect("pressed", object, load_fct)
$Save.connect("pressed", object, save_fct) $Save.connect("pressed", object, save_fct)

View File

@ -21,7 +21,7 @@ const CONVOLUTION = {
const INDICES = [ 0, 1, 2, 5, 8, 7, 6, 3 ] const INDICES = [ 0, 1, 2, 5, 8, 7, 6, 3 ]
const COEFS = [ 1, 2, 1, 0, -1, -2, -1, 0 ] const COEFS = [ 1, 2, 1, 0, -1, -2, -1, 0 ]
func _ready(): func _ready() -> void:
$HBoxContainer1/size.clear() $HBoxContainer1/size.clear()
for i in range(7): for i in range(7):
$HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i) $HBoxContainer1/size.add_item(str(int(pow(2, 5+i))), i)
@ -30,22 +30,22 @@ func _ready():
final_texture = ImageTexture.new() final_texture = ImageTexture.new()
initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction ]) initialize_properties([ $HBoxContainer1/size, $HBoxContainer2/direction ])
func _rerender(): func _rerender() -> void:
get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), input_texture, self, "pass_1", []) get_parent().renderer.precalculate_shader(input_shader, get_source().get_textures(), int(pow(2, 5+parameters.size)), input_texture, self, "pass_1", [])
func pass_1(): func pass_1() -> void:
var convolution = CONVOLUTION var convolution = CONVOLUTION
convolution.epsilon=1.0/pow(2, 5+parameters.size) convolution.epsilon=1.0/pow(2, 5+parameters.size)
for i in range(8): for i in range(8):
convolution.kernel[INDICES[i]] = COEFS[(i+8-int(parameters.direction))%8] convolution.kernel[INDICES[i]] = COEFS[(i+8-int(parameters.direction))%8]
get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), {input=input_texture}, int(pow(2, 5+parameters.size)), final_texture, self, "rerender_targets", []) get_parent().renderer.precalculate_shader(get_convolution_shader(convolution), {input=input_texture}, int(pow(2, 5+parameters.size)), final_texture, self, "rerender_targets", [])
func get_textures(): func get_textures() -> Dictionary:
var list = {} var list = {}
list[name] = final_texture list[name] = final_texture
return list return list
func _get_shader_code(uv, slot = 0): func _get_shader_code(uv, slot = 0) -> Dictionary:
var rv = { defs="", code="" } var rv = { defs="", code="" }
var src = get_source() var src = get_source()
if src == null: if src == null:

View File

@ -3,29 +3,29 @@ extends "res://addons/material_maker/node_base.gd"
var suffix = "suffix" var suffix = "suffix"
func _ready(): func _ready() -> void:
initialize_properties([ $resolution ]) initialize_properties([ $resolution ])
func _get_shader_code(uv, slot = 0): func _get_shader_code(uv, slot = 0) -> Dictionary:
var rv = { defs="", code="", f="0.0" } var rv = { defs="", code="", f="0.0" }
var src = get_source() var src = get_source()
if src != null: if src != null:
rv = src.get_shader_code(uv) rv = src.get_shader_code(uv)
return rv return rv
func export_textures(prefix, size = null): func export_textures(prefix, size = null) -> void:
var suffix = $Suffix.text var suffix = $Suffix.text
if suffix != "": if suffix != "":
if size == null: if size == null:
size = int(pow(2, 8+parameters.resolution)) size = int(pow(2, 8+parameters.resolution))
get_parent().renderer.export_texture(get_source(), "%s_%s.png" % [ prefix, suffix ], size) get_parent().renderer.export_texture(get_source(), "%s_%s.png" % [ prefix, suffix ], size)
func serialize(): func serialize() -> Dictionary:
var data = .serialize() var data = .serialize()
data.suffix = $Suffix.text data.suffix = $Suffix.text
return data return data
func deserialize(data): func deserialize(data) -> void:
if data.has("suffix"): if data.has("suffix"):
$Suffix.text = data.suffix $Suffix.text = data.suffix
.deserialize(data) .deserialize(data)

View File

@ -14,18 +14,18 @@ var preview_position : int
var preview_size : int var preview_size : int
var preview_timer : Timer = null var preview_timer : Timer = null
func set_generator(g): func set_generator(g) -> void:
generator = g generator = g
generator.connect("parameter_changed", self, "on_parameter_changed") generator.connect("parameter_changed", self, "on_parameter_changed")
call_deferred("update_node") call_deferred("update_node")
func on_close_request(): func on_close_request() -> void:
generator.get_parent().remove_generator(generator) generator.get_parent().remove_generator(generator)
func on_offset_changed(): func on_offset_changed() -> void:
generator.set_position(offset) generator.set_position(offset)
func on_parameter_changed(p, v): func on_parameter_changed(p, v) -> void:
if ignore_parameter_change == p: if ignore_parameter_change == p:
return return
if p == "__update_all__": if p == "__update_all__":
@ -52,7 +52,7 @@ func on_parameter_changed(p, v):
print("unsupported widget "+str(o)) print("unsupported widget "+str(o))
update_shaders() update_shaders()
func initialize_properties(): func initialize_properties() -> void:
var parameter_names = [] var parameter_names = []
for p in generator.get_parameter_defs(): for p in generator.get_parameter_defs():
parameter_names.push_back(p.name) parameter_names.push_back(p.name)
@ -79,35 +79,35 @@ func initialize_properties():
else: else:
print("unsupported widget "+str(o)) print("unsupported widget "+str(o))
func update_shaders(): func update_shaders() -> void:
get_parent().send_changed_signal() get_parent().send_changed_signal()
update_preview() update_preview()
func _on_text_changed(new_text, variable): func _on_text_changed(new_text, variable) -> void:
ignore_parameter_change = variable ignore_parameter_change = variable
generator.set_parameter(variable, float(new_text)) generator.set_parameter(variable, float(new_text))
ignore_parameter_change = "" ignore_parameter_change = ""
update_shaders() update_shaders()
func _on_value_changed(new_value, variable): func _on_value_changed(new_value, variable) -> void:
ignore_parameter_change = variable ignore_parameter_change = variable
generator.set_parameter(variable, new_value) generator.set_parameter(variable, new_value)
ignore_parameter_change = "" ignore_parameter_change = ""
update_shaders() update_shaders()
func _on_color_changed(new_color, variable): func _on_color_changed(new_color, variable) -> void:
ignore_parameter_change = variable ignore_parameter_change = variable
generator.set_parameter(variable, new_color) generator.set_parameter(variable, new_color)
ignore_parameter_change = "" ignore_parameter_change = ""
update_shaders() update_shaders()
func _on_gradient_changed(new_gradient, variable): func _on_gradient_changed(new_gradient, variable) -> void:
ignore_parameter_change = variable ignore_parameter_change = variable
generator.set_parameter(variable, MMType.serialize_value(new_gradient)) generator.set_parameter(variable, MMType.serialize_value(new_gradient))
ignore_parameter_change = "" ignore_parameter_change = ""
update_shaders() update_shaders()
func create_parameter_control(p : Dictionary): func create_parameter_control(p : Dictionary) -> Control:
var control = null var control = null
if p.type == "float": if p.type == "float":
if p.has("widget") and p.widget == "spinbox": if p.has("widget") and p.widget == "spinbox":
@ -142,14 +142,14 @@ func create_parameter_control(p : Dictionary):
control = preload("res://addons/material_maker/widgets/gradient_editor.tscn").instance() control = preload("res://addons/material_maker/widgets/gradient_editor.tscn").instance()
return control return control
func save_preview_widget(): func save_preview_widget() -> void:
if preview != null: if preview != null:
remove_child(preview) remove_child(preview)
if preview_timer != null: if preview_timer != null:
preview_timer.stop() preview_timer.stop()
remove_child(preview_timer) remove_child(preview_timer)
func restore_preview_widget(): func restore_preview_widget() -> void:
if preview == null: if preview == null:
preview = TextureRect.new() preview = TextureRect.new()
preview.visible = false preview.visible = false
@ -165,7 +165,7 @@ func restore_preview_widget():
preview_timer.connect("timeout", self, "do_update_preview") preview_timer.connect("timeout", self, "do_update_preview")
add_child(preview_timer) add_child(preview_timer)
func update_node(): func update_node() -> void:
# Clean node # Clean node
var custom_node_buttons = null var custom_node_buttons = null
save_preview_widget() save_preview_widget()
@ -203,7 +203,7 @@ func update_node():
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():
@ -305,16 +305,16 @@ func update_node():
# Preview # Preview
restore_preview_widget() restore_preview_widget()
func edit_generator(): func edit_generator() -> void:
if generator.has_method("edit"): if generator.has_method("edit"):
generator.edit(self) generator.edit(self)
func update_generator(shader_model): func update_generator(shader_model) -> void:
generator.set_shader_model(shader_model) generator.set_shader_model(shader_model)
update_node() update_node()
update_shaders() update_shaders()
func load_generator(): func load_generator() -> void:
var dialog = FileDialog.new() var dialog = FileDialog.new()
add_child(dialog) add_child(dialog)
dialog.rect_min_size = Vector2(500, 500) dialog.rect_min_size = Vector2(500, 500)
@ -324,7 +324,7 @@ func load_generator():
dialog.connect("file_selected", self, "do_load_generator") dialog.connect("file_selected", self, "do_load_generator")
dialog.popup_centered() dialog.popup_centered()
func do_load_generator(file_name : String): func do_load_generator(file_name : String) -> void:
var new_generator = null var new_generator = null
if file_name.ends_with(".mmn"): if file_name.ends_with(".mmn"):
var file = File.new() var file = File.new()
@ -343,7 +343,7 @@ func do_load_generator(file_name : String):
generator = new_generator generator = new_generator
call_deferred("update_node") call_deferred("update_node")
func save_generator(): func save_generator() -> void:
var dialog = FileDialog.new() var dialog = FileDialog.new()
add_child(dialog) add_child(dialog)
dialog.rect_min_size = Vector2(500, 500) dialog.rect_min_size = Vector2(500, 500)
@ -353,7 +353,7 @@ func save_generator():
dialog.connect("file_selected", self, "do_save_generator") dialog.connect("file_selected", self, "do_save_generator")
dialog.popup_centered() dialog.popup_centered()
func do_save_generator(file_name : String): func do_save_generator(file_name : String) -> void:
var file = File.new() var file = File.new()
if file.open(file_name, File.WRITE) == OK: if file.open(file_name, File.WRITE) == OK:
var data = generator.serialize() var data = generator.serialize()
@ -362,13 +362,13 @@ func do_save_generator(file_name : String):
file.store_string(to_json(data)) file.store_string(to_json(data))
file.close() file.close()
func update_preview_buttons(index : int): func update_preview_buttons(index : int) -> void:
for i in range(output_count): for i in range(output_count):
if i != index: if i != index:
var line = get_child(i) var line = get_child(i)
line.get_child(line.get_child_count()-1).pressed = false line.get_child(line.get_child_count()-1).pressed = false
func on_preview_button(pressed : bool, index : int): func on_preview_button(pressed : bool, index : int) -> void:
if pressed: if pressed:
preview_index = index preview_index = index
var width var width
@ -385,14 +385,14 @@ func on_preview_button(pressed : bool, index : int):
remove_child(preview) remove_child(preview)
rect_size = Vector2(0, 0) rect_size = Vector2(0, 0)
func update_preview(size : int = 0): func update_preview(size : int = 0) -> void:
if preview_index == -1: if preview_index == -1:
return return
if size != 0: if size != 0:
preview_size = size preview_size = size
preview_timer.start(0.2) preview_timer.start(0.2)
func do_update_preview(): func do_update_preview() -> void:
var renderer = get_parent().renderer var renderer = get_parent().renderer
var result = generator.render(preview_index, renderer, preview_size) var result = generator.render(preview_index, renderer, preview_size)
while result is GDScriptFunctionState: while result is GDScriptFunctionState:

View File

@ -3,22 +3,22 @@ extends GraphNode
var generator = null var generator = null
func _ready(): func _ready() -> void:
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1)) set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
func set_texture(path): func set_texture(path) -> void:
if path == null: if path == null:
return return
if generator != null: if generator != null:
generator.set_parameter("image", path) generator.set_parameter("image", path)
$TextureButton.texture_normal = generator.texture $TextureButton.texture_normal = generator.texture
func get_textures(): func get_textures() -> Dictionary:
var list = {} var list = {}
list[name] = $TextureButton.texture_normal list[name] = $TextureButton.texture_normal
return list return list
func _on_TextureButton_pressed(): func _on_TextureButton_pressed() -> void:
var dialog = FileDialog.new() var dialog = FileDialog.new()
add_child(dialog) add_child(dialog)
dialog.rect_min_size = Vector2(500, 500) dialog.rect_min_size = Vector2(500, 500)

View File

@ -6,7 +6,7 @@ var links = {}
onready var grid = $Controls onready var grid = $Controls
func add_control(text, control): 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)
@ -24,7 +24,7 @@ func add_control(text, control):
grid.add_child(button) grid.add_child(button)
button.connect("pressed", generator, "remove_parameter", [ index ]) button.connect("pressed", generator, "remove_parameter", [ index ])
func update_node(): func update_node() -> void:
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()
@ -52,7 +52,7 @@ func update_node():
rect_size = Vector2(0, 0) rect_size = Vector2(0, 0)
initialize_properties() initialize_properties()
func _on_value_changed(new_value, variable): func _on_value_changed(new_value, variable) -> void:
var param_index = variable.trim_prefix("param").to_int() var param_index = variable.trim_prefix("param").to_int()
var widget = generator.widgets[param_index] var widget = generator.widgets[param_index]
if widget.type == "config_control": if widget.type == "config_control":
@ -83,41 +83,41 @@ func _on_value_changed(new_value, variable):
else: else:
._on_value_changed(new_value, variable) ._on_value_changed(new_value, variable)
func do_add_configuration(config_name, param_index): func do_add_configuration(config_name, param_index) -> void:
generator.add_configuration(param_index, config_name) generator.add_configuration(param_index, config_name)
func on_label_changed(new_name, index): func on_label_changed(new_name, index) -> void:
generator.set_label(index, new_name) generator.set_label(index, new_name)
func _on_AddLink_pressed(): func _on_AddLink_pressed() -> void:
var widget = Control.new() var widget = Control.new()
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, generator.create_linked_control("Unnamed"), true)
func _on_AddConfig_pressed(): func _on_AddConfig_pressed() -> void:
var widget = Control.new() var widget = Control.new()
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, generator.create_config_control("Unnamed"), true)
func _on_Link_pressed(index): func _on_Link_pressed(index) -> 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(grid.get_child(index*4+1), generator, index)
func _on_Remote_resize_request(new_minsize): func _on_Remote_resize_request(new_minsize) -> void:
rect_size = new_minsize rect_size = new_minsize
func _on_HBoxContainer_minimum_size_changed(): func _on_HBoxContainer_minimum_size_changed() -> void:
print("_on_HBoxContainer_minimum_size_changed "+str($HBoxContainer.rect_min_size)) print("_on_HBoxContainer_minimum_size_changed "+str($HBoxContainer.rect_min_size))
func on_parameter_changed(p, v): func on_parameter_changed(p, v) -> void:
if p == "": if p == "":
update_node() update_node()
else: else:
.on_parameter_changed(p, v) .on_parameter_changed(p, v)
func on_enter_widget(widget): func on_enter_widget(widget) -> void:
var param_index = widget.name.trim_prefix("param").to_int() var param_index = widget.name.trim_prefix("param").to_int()
var w = generator.widgets[param_index] var w = generator.widgets[param_index]
var new_links = [] var new_links = []
@ -134,7 +134,7 @@ func on_enter_widget(widget):
# store new links # store new links
links[widget] = new_links links[widget] = new_links
func on_exit_widget(widget): func on_exit_widget(widget) -> void:
if links.has(widget): if links.has(widget):
for l in links[widget]: for l in links[widget]:
l.queue_free() l.queue_free()

View File

@ -3,16 +3,16 @@ extends MMGraphNodeGeneric
var fixed_lines : int = 0 var fixed_lines : int = 0
func _ready(): func _ready() -> void:
update_node() update_node()
func update_preview_buttons(index : int): func update_preview_buttons(index : int) -> void:
for i in range(generator.parameters.outputs): for i in range(generator.parameters.outputs):
if i != index: if i != index:
var line = get_child(i) var line = get_child(i)
line.get_child(2).pressed = false line.get_child(2).pressed = false
func update_node(): func update_node() -> void:
print("update_node") print("update_node")
if generator == null or !generator.parameters.has("outputs") or !generator.parameters.has("choices"): if generator == null or !generator.parameters.has("outputs") or !generator.parameters.has("choices"):
return return

View File

@ -6,25 +6,25 @@ var material_maker = null
var importer = null var importer = null
var renderer = null var renderer = null
func _enter_tree(): func _enter_tree() -> void:
add_tool_menu_item("Material Maker", self, "open_material_maker") add_tool_menu_item("Material Maker", self, "open_material_maker")
add_tool_menu_item("Register Material Maker Import", self, "register_material_maker_import") add_tool_menu_item("Register Material Maker Import", self, "register_material_maker_import")
renderer = preload("res://addons/material_maker/engine/renderer.tscn").instance() renderer = preload("res://addons/material_maker/engine/renderer.tscn").instance()
add_child(renderer) add_child(renderer)
func register_material_maker_import(__): func register_material_maker_import(__) -> void:
importer = preload("res://addons/material_maker/import_plugin/ptex_import.gd").new(self) importer = preload("res://addons/material_maker/import_plugin/ptex_import.gd").new(self)
add_import_plugin(importer) add_import_plugin(importer)
remove_tool_menu_item("Register Material Maker Import") remove_tool_menu_item("Register Material Maker Import")
add_tool_menu_item("Unregister Material Maker Import", self, "unregister_material_maker_import") add_tool_menu_item("Unregister Material Maker Import", self, "unregister_material_maker_import")
func unregister_material_maker_import(__): func unregister_material_maker_import(__) -> void:
remove_import_plugin(importer) remove_import_plugin(importer)
importer = null importer = null
remove_tool_menu_item("Unregister Material Maker Import") remove_tool_menu_item("Unregister Material Maker Import")
add_tool_menu_item("Register Material Maker Import", self, "register_material_maker_import") add_tool_menu_item("Register Material Maker Import", self, "register_material_maker_import")
func _exit_tree(): func _exit_tree() -> void:
remove_tool_menu_item("Material Maker") remove_tool_menu_item("Material Maker")
if material_maker != null: if material_maker != null:
material_maker.hide() material_maker.hide()
@ -34,15 +34,14 @@ func _exit_tree():
remove_import_plugin(importer) remove_import_plugin(importer)
importer = null importer = null
func _get_state(): func _get_state() -> Dictionary:
var s = { mm_button=mm_button, material_maker=material_maker } return { mm_button=mm_button, material_maker=material_maker }
return s
func _set_state(s): func _set_state(s) -> void:
mm_button = s.mm_button mm_button = s.mm_button
material_maker = s.material_maker material_maker = s.material_maker
func open_material_maker(__): func open_material_maker(__) -> void:
if material_maker == null: if material_maker == null:
material_maker = preload("res://addons/material_maker/window_dialog.tscn").instance() material_maker = preload("res://addons/material_maker/window_dialog.tscn").instance()
var panel = material_maker.get_node("MainWindow") var panel = material_maker.get_node("MainWindow")
@ -51,7 +50,7 @@ func open_material_maker(__):
add_child(material_maker) add_child(material_maker)
material_maker.popup_centered() material_maker.popup_centered()
func close_material_maker(): func close_material_maker() -> void:
if material_maker != null: if material_maker != null:
material_maker.hide() material_maker.hide()
material_maker.queue_free() material_maker.queue_free()

View File

@ -22,7 +22,7 @@ onready var camera = $MaterialPreview/Preview3d/CameraPivot/Camera
signal need_update signal need_update
signal show_background_preview signal show_background_preview
func _ready(): func _ready() -> void:
$Config/Model.clear() $Config/Model.clear()
for o in objects.get_children(): for o in objects.get_children():
var m = o.get_surface_material(0) var m = o.get_surface_material(0)
@ -38,26 +38,26 @@ func _ready():
_on_Preview_resized() _on_Preview_resized()
$MaterialPreview/Preview3d/CameraPivot/Camera/RemoteTransform.set_remote_node("../../../../../../../ProjectsPane/BackgroundPreview/Viewport/Camera") $MaterialPreview/Preview3d/CameraPivot/Camera/RemoteTransform.set_remote_node("../../../../../../../ProjectsPane/BackgroundPreview/Viewport/Camera")
func _on_Environment_item_selected(id): func _on_Environment_item_selected(id) -> void:
current_environment.visible = false current_environment.visible = false
current_environment = environments.get_child(id) current_environment = environments.get_child(id)
$MaterialPreview/Preview3d/CameraPivot/Camera.set_environment(current_environment.environment) $MaterialPreview/Preview3d/CameraPivot/Camera.set_environment(current_environment.environment)
get_node("../../ProjectsPane/BackgroundPreview/Viewport/Camera").set_environment(current_environment.environment) get_node("../../ProjectsPane/BackgroundPreview/Viewport/Camera").set_environment(current_environment.environment)
current_environment.visible = true current_environment.visible = true
func _on_Model_item_selected(id): func _on_Model_item_selected(id) -> void:
current_object.visible = false current_object.visible = false
current_object = objects.get_child(id) current_object = objects.get_child(id)
current_object.visible = true current_object.visible = true
emit_signal("need_update") emit_signal("need_update")
func get_materials(): func get_materials() -> Array:
return [ current_object.get_surface_material(0) ] return [ current_object.get_surface_material(0) ]
func set_2d(tex: Texture): func set_2d(tex: Texture) -> void:
$Preview2D.material.set_shader_param("tex", tex) $Preview2D.material.set_shader_param("tex", tex)
func _on_Preview_resized(): func _on_Preview_resized() -> void:
if preview_maximized: if preview_maximized:
var size = min(rect_size.x, rect_size.y) var size = min(rect_size.x, rect_size.y)
$Preview2D.rect_position = 0.5*Vector2(rect_size.x-size, rect_size.y-size) $Preview2D.rect_position = 0.5*Vector2(rect_size.x-size, rect_size.y-size)
@ -66,15 +66,15 @@ func _on_Preview_resized():
$Preview2D.rect_position = Vector2(0, rect_size.y-64) $Preview2D.rect_position = Vector2(0, rect_size.y-64)
$Preview2D.rect_size = Vector2(64, 64) $Preview2D.rect_size = Vector2(64, 64)
func _on_Preview2D_gui_input(ev : InputEvent): func _on_Preview2D_gui_input(ev : InputEvent) -> void:
if ev is InputEventMouseButton and ev.button_index == 1 and ev.pressed: if ev is InputEventMouseButton and ev.button_index == 1 and ev.pressed:
preview_maximized = !preview_maximized preview_maximized = !preview_maximized
_on_Preview_resized() _on_Preview_resized()
func _on_Background_toggled(button_pressed): func _on_Background_toggled(button_pressed) -> void:
emit_signal("show_background_preview", button_pressed) emit_signal("show_background_preview", button_pressed)
func on_gui_input(event): func on_gui_input(event) -> void:
if event is InputEventMouseButton: if event is InputEventMouseButton:
$MaterialPreview/Preview3d/ObjectRotate.stop(false) $MaterialPreview/Preview3d/ObjectRotate.stop(false)
$Config/Rotate.pressed = false $Config/Rotate.pressed = false
@ -107,7 +107,7 @@ func on_gui_input(event):
elif event.button_mask & BUTTON_MASK_RIGHT: elif event.button_mask & BUTTON_MASK_RIGHT:
camera_stand.rotate(camera_basis.z.normalized(), -motion.x) camera_stand.rotate(camera_basis.z.normalized(), -motion.x)
func _on_Rotate_toggled(button_pressed): func _on_Rotate_toggled(button_pressed) -> void:
if button_pressed: if button_pressed:
$MaterialPreview/Preview3d/ObjectRotate.play("rotate") $MaterialPreview/Preview3d/ObjectRotate.play("rotate")
else: else:

View File

@ -1,5 +1,5 @@
tool tool
extends Area extends Area
func _on_Light_input_event(camera, event, click_position, click_normal, shape_idx): func _on_Light_input_event(camera, event, click_position, click_normal, shape_idx) -> void:
print(event) print(event)

View File

@ -2,39 +2,39 @@ extends Object
class_name MMGradient class_name MMGradient
class CustomSorter: class CustomSorter:
static func compare(a, b): static func compare(a, b) -> bool:
return a.v < b.v return a.v < b.v
var points = [ { v=0.0, c=Color(0.0, 0.0, 0.0, 0.0) }, { v=1.0, c=Color(1.0, 1.0, 1.0, 1.0) } ] var points = [ { v=0.0, c=Color(0.0, 0.0, 0.0, 0.0) }, { v=1.0, c=Color(1.0, 1.0, 1.0, 1.0) } ]
var sorted = true var sorted = true
func to_string(): func to_string() -> String:
var rv = PoolStringArray() var rv = PoolStringArray()
for p in points: for p in points:
rv.append("("+str(p.v)+","+str(p.c)+")") rv.append("("+str(p.v)+","+str(p.c)+")")
return rv.join(",") return rv.join(",")
func duplicate(): func duplicate() -> Object:
var copy = get_script().new() var copy = get_script().new()
copy.clear() copy.clear()
for p in points: for p in points:
copy.add_point(p.v, p.c) copy.add_point(p.v, p.c)
return copy return copy
func clear(): func clear() -> void:
points.clear() points.clear()
sorted = true sorted = true
func add_point(v, c): func add_point(v, c) -> void:
points.append({ v=v, c=c }) points.append({ v=v, c=c })
sorted = false sorted = false
func sort(): func sort() -> void:
if !sorted: if !sorted:
points.sort_custom(CustomSorter, "compare") points.sort_custom(CustomSorter, "compare")
sorted = true sorted = true
func get_color(x): func get_color(x) -> Color:
sort() sort()
if points.size() > 0: if points.size() > 0:
if x < points[0].v: if x < points[0].v:
@ -52,10 +52,10 @@ func get_color(x):
return Color(0.0, 0.0, 0.0, 1.0) return Color(0.0, 0.0, 0.0, 1.0)
# get_color_in_shader # get_color_in_shader
func gcis(color): func gcis(color) -> String:
return "vec4(%.9f,%.9f,%.9f,%.9f)" % [color.r, color.g, color.b, color.a] return "vec4(%.9f,%.9f,%.9f,%.9f)" % [color.r, color.g, color.b, color.a]
func get_shader(name): func get_shader(name) -> String:
sort() sort()
var shader var shader
shader = "vec4 "+name+"(float x) {\n" shader = "vec4 "+name+"(float x) {\n"
@ -78,7 +78,7 @@ func get_shader(name):
shader += "}\n" shader += "}\n"
return shader return shader
func serialize(): func serialize() -> Dictionary:
sort() sort()
var rv = [] var rv = []
for p in points: for p in points:
@ -86,7 +86,7 @@ func serialize():
rv = { type="Gradient", points=rv } rv = { type="Gradient", points=rv }
return rv return rv
func deserialize(v): func deserialize(v) -> void:
clear() clear()
if typeof(v) == TYPE_ARRAY: if typeof(v) == TYPE_ARRAY:
for i in v: for i in v:

View File

@ -3,7 +3,7 @@ class_name MMType
const Gradient = preload("res://addons/material_maker/types/gradient.gd") const Gradient = preload("res://addons/material_maker/types/gradient.gd")
static func serialize_value(value): static func serialize_value(value) -> Dictionary:
if typeof(value) == TYPE_COLOR: if typeof(value) == TYPE_COLOR:
return { type="Color", r=value.r, g=value.g, b=value.b, a=value.a } return { type="Color", r=value.r, g=value.g, b=value.b, a=value.a }
elif typeof(value) == TYPE_OBJECT and value.has_method("serialize"): elif typeof(value) == TYPE_OBJECT and value.has_method("serialize"):

View File

@ -2,12 +2,11 @@ tool
extends WindowDialog extends WindowDialog
func _ready(): func _ready() -> void:
if Engine.editor_hint: if Engine.editor_hint:
$VBoxContainer/VBoxContainer1/ApplicationName.text = "Material Maker" $VBoxContainer/VBoxContainer1/ApplicationName.text = "Material Maker"
else: else:
$VBoxContainer/VBoxContainer1/ApplicationName.text = ProjectSettings.get_setting("application/config/name")+" v"+ProjectSettings.get_setting("application/config/release") $VBoxContainer/VBoxContainer1/ApplicationName.text = ProjectSettings.get_setting("application/config/name")+" v"+ProjectSettings.get_setting("application/config/release")
pass
func open_url(url): func open_url(url) -> void:
OS.shell_open(url) OS.shell_open(url)

View File

@ -4,14 +4,14 @@ class_name MMGradientEditor
class GradientCursor: class GradientCursor:
extends ColorRect extends ColorRect
const WIDTH = 10 const WIDTH = 10
func _ready(): func _ready() -> void:
rect_position = Vector2(0, 15) rect_position = Vector2(0, 15)
rect_size = Vector2(WIDTH, 15) rect_size = Vector2(WIDTH, 15)
func _gui_input(ev): func _gui_input(ev) -> void:
if ev is InputEventMouseButton: if ev is InputEventMouseButton:
if ev.button_index == BUTTON_LEFT && ev.doubleclick: if ev.button_index == BUTTON_LEFT && ev.doubleclick:
get_parent().select_color(self, ev.global_position) get_parent().select_color(self, ev.global_position)
@ -24,20 +24,18 @@ class GradientCursor:
rect_position.x += ev.relative.x rect_position.x += ev.relative.x
rect_position.x = min(max(0, rect_position.x), get_parent().rect_size.x-rect_size.x) rect_position.x = min(max(0, rect_position.x), get_parent().rect_size.x-rect_size.x)
get_parent().update_value() get_parent().update_value()
func get_position(): func get_position() -> Vector2:
return rect_position.x / (get_parent().rect_size.x - WIDTH) return rect_position.x / (get_parent().rect_size.x - WIDTH)
func set_color(c): func set_color(c) -> void:
color = c color = c
get_parent().update_value() get_parent().update_value()
static func sort(a, b): static func sort(a, b) -> bool:
if a.get_position() < b.get_position(): return a.get_position() < b.get_position()
return true
return false func _draw() -> void:
func _draw():
var c = color var c = color
c.a = 1.0 c.a = 1.0
draw_rect(Rect2(0, 0, rect_size.x, rect_size.y), c, false) draw_rect(Rect2(0, 0, rect_size.x, rect_size.y), c, false)
@ -47,11 +45,11 @@ export var embedded : bool = true
signal updated(value) signal updated(value)
func _ready(): func _ready() -> void:
$Gradient.material = $Gradient.material.duplicate(true) $Gradient.material = $Gradient.material.duplicate(true)
set_value(MMGradient.new()) set_value(MMGradient.new())
func set_value(v): func set_value(v) -> void:
value = v value = v
for c in get_children(): for c in get_children():
if c is GradientCursor: if c is GradientCursor:
@ -61,20 +59,20 @@ func set_value(v):
add_cursor(p.v*(rect_size.x-GradientCursor.WIDTH), p.c) add_cursor(p.v*(rect_size.x-GradientCursor.WIDTH), p.c)
update_shader() update_shader()
func update_value(): func update_value() -> void:
value.clear() value.clear()
for p in get_children(): for p in get_children():
if p != $Gradient && p != $Background: if p != $Gradient && p != $Background:
value.add_point(p.rect_position.x/(rect_size.x-GradientCursor.WIDTH), p.color) value.add_point(p.rect_position.x/(rect_size.x-GradientCursor.WIDTH), p.color)
update_shader() update_shader()
func add_cursor(x, color): func add_cursor(x, color) -> void:
var cursor = GradientCursor.new() var cursor = GradientCursor.new()
add_child(cursor) add_child(cursor)
cursor.rect_position.x = x cursor.rect_position.x = x
cursor.color = color cursor.color = color
func _gui_input(ev): func _gui_input(ev) -> void:
if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick: if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick:
if ev.position.y > 15: if ev.position.y > 15:
var p = max(0, min(ev.position.x, rect_size.x-GradientCursor.WIDTH)) var p = max(0, min(ev.position.x, rect_size.x-GradientCursor.WIDTH))
@ -93,29 +91,29 @@ func _gui_input(ev):
var active_cursor var active_cursor
func select_color(cursor, position): func select_color(cursor, position) -> void:
active_cursor = cursor active_cursor = cursor
$Gradient/Popup/ColorPicker.color = cursor.color $Gradient/Popup/ColorPicker.color = cursor.color
$Gradient/Popup/ColorPicker.connect("color_changed", cursor, "set_color") $Gradient/Popup/ColorPicker.connect("color_changed", cursor, "set_color")
$Gradient/Popup.rect_position = position $Gradient/Popup.rect_position = position
$Gradient/Popup.popup() $Gradient/Popup.popup()
func _on_Popup_popup_hide(): func _on_Popup_popup_hide() -> void:
$Gradient/Popup/ColorPicker.disconnect("color_changed", active_cursor, "set_color") $Gradient/Popup/ColorPicker.disconnect("color_changed", active_cursor, "set_color")
# Calculating a color from the gradient and generating the shader # Calculating a color from the gradient and generating the shader
func get_sorted_cursors(): func get_sorted_cursors() -> Array:
var array = get_children() var array = get_children()
array.erase($Gradient) array.erase($Gradient)
array.erase($Background) array.erase($Background)
array.sort_custom(GradientCursor, "sort") array.sort_custom(GradientCursor, "sort")
return array return array
func get_gradient_color(x): func get_gradient_color(x) -> Color:
return value.get_color(x / (rect_size.x - GradientCursor.WIDTH)) return value.get_color(x / (rect_size.x - GradientCursor.WIDTH))
func update_shader(): func update_shader() -> void:
var shader var shader
shader = "shader_type canvas_item;\n" shader = "shader_type canvas_item;\n"
shader += value.get_shader("gradient") shader += value.get_shader("gradient")

View File

@ -2,14 +2,14 @@ extends Popup
signal updated(value) signal updated(value)
func init(value): func init(value) -> void:
$Panel/Control.set_value(value) $Panel/Control.set_value(value)
func _on_Control_updated(value): func _on_Control_updated(value) -> void:
emit_signal("updated", value) emit_signal("updated", value)
func _on_GradientPopup_popup_hide(): func _on_GradientPopup_popup_hide() -> void:
queue_free() queue_free()

View File

@ -2,14 +2,14 @@ extends Popup
signal item_double_clicked(generator) signal item_double_clicked(generator)
func init(graph_name : String, generator : MMGenGraph): func init(graph_name : String, generator : MMGenGraph) -> void:
$Tree.clear() $Tree.clear()
var root : TreeItem = $Tree.create_item(null) var root : TreeItem = $Tree.create_item(null)
root.set_text(0, graph_name) root.set_text(0, graph_name)
root.set_metadata(0, generator) root.set_metadata(0, generator)
fill_item(root, generator) fill_item(root, generator)
func fill_item(parent : TreeItem, generator : MMGenGraph): func fill_item(parent : TreeItem, generator : MMGenGraph) -> void:
for c in generator.get_children(): for c in generator.get_children():
if c is MMGenGraph: if c is MMGenGraph:
var item : TreeItem = $Tree.create_item(parent) var item : TreeItem = $Tree.create_item(parent)
@ -17,6 +17,6 @@ func fill_item(parent : TreeItem, generator : MMGenGraph):
item.set_metadata(0, c) item.set_metadata(0, c)
fill_item(item, c) fill_item(item, c)
func _on_Tree_item_double_clicked(): func _on_Tree_item_double_clicked() -> void:
emit_signal("item_double_clicked", $Tree.get_selected().get_metadata(0)) emit_signal("item_double_clicked", $Tree.get_selected().get_metadata(0))
queue_free() queue_free()

View File

@ -1,12 +1,12 @@
tool tool
extends HSlider extends HSlider
func _ready(): func _ready() -> void:
update_label(value) update_label(value)
func set_value(v): func set_value(v) -> void:
.set_value(v) .set_value(v)
update_label(v) update_label(v)
func update_label(v): func update_label(v) -> void:
$Label.text = str(v) $Label.text = str(v)

View File

@ -3,18 +3,18 @@ extends WindowDialog
signal ok signal ok
func set_value(v): func set_value(v) -> void:
$VBoxContainer/LineEdit.text = v $VBoxContainer/LineEdit.text = v
func set_texts(title, label): func set_texts(title, label) -> void:
window_title = title window_title = title
$VBoxContainer/Label.text = label $VBoxContainer/Label.text = label
$VBoxContainer/LineEdit.grab_focus() $VBoxContainer/LineEdit.grab_focus()
$VBoxContainer/LineEdit.grab_click_focus() $VBoxContainer/LineEdit.grab_click_focus()
func _on_OK_pressed(): func _on_OK_pressed() -> void:
_on_LineEdit_text_entered($VBoxContainer/LineEdit.text) _on_LineEdit_text_entered($VBoxContainer/LineEdit.text)
func _on_LineEdit_text_entered(new_text): func _on_LineEdit_text_entered(new_text) -> void:
emit_signal("ok", new_text) emit_signal("ok", new_text)
queue_free() queue_free()

View File

@ -5,16 +5,13 @@ var text setget set_text, get_text
signal label_changed(new_label) signal label_changed(new_label)
func _ready(): func get_text() -> String:
pass
func get_text():
return $Label.text return $Label.text
func set_text(t): func set_text(t) -> void:
$Label.text = t $Label.text = t
func _on_gui_input(ev): func _on_gui_input(ev) -> void:
if ev is InputEventMouseButton and ev.pressed and ev.button_index == BUTTON_LEFT: if ev is InputEventMouseButton and ev.pressed and ev.button_index == BUTTON_LEFT:
$Label.visible = false $Label.visible = false
$Editor.text = $Label.text $Editor.text = $Label.text
@ -22,10 +19,10 @@ func _on_gui_input(ev):
$Editor.select() $Editor.select()
$Editor.grab_focus() $Editor.grab_focus()
func _on_Editor_text_entered(__): func _on_Editor_text_entered(__) -> void:
_on_Editor_focus_exited() _on_Editor_focus_exited()
func _on_Editor_focus_exited(): func _on_Editor_focus_exited() -> void:
$Label.text = $Editor.text $Label.text = $Editor.text
$Label.visible = true $Label.visible = true
$Editor.visible = false $Editor.visible = false

View File

@ -10,14 +10,14 @@ var generator = null
var param_index = 0 var param_index = 0
var creating = false var creating = false
func _init(parent): func _init(parent) -> void:
size_flags_horizontal = SIZE_EXPAND_FILL size_flags_horizontal = SIZE_EXPAND_FILL
size_flags_vertical = SIZE_EXPAND_FILL size_flags_vertical = SIZE_EXPAND_FILL
rect_size = parent.rect_size rect_size = parent.rect_size
rect_clip_content = true rect_clip_content = true
parent.add_child(self) parent.add_child(self)
func pick(s, g, i, c = false): func pick(s, g, i, c = 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
@ -25,14 +25,14 @@ func pick(s, g, i, c = false):
creating = c creating = c
set_process_input(true) set_process_input(true)
func show_link(s, t): func show_link(s, t) -> void:
set_process_input(false) set_process_input(false)
mouse_filter = Control.MOUSE_FILTER_IGNORE mouse_filter = Control.MOUSE_FILTER_IGNORE
source = s source = s
target = t target = t
update() update()
func closest(rect, point): func closest(rect, point) -> Vector2:
return Vector2(max(rect.position.x, min(rect.end.x, point.x)), max(rect.position.y, min(rect.end.y, point.y))) return Vector2(max(rect.position.x, min(rect.end.x, point.x)), max(rect.position.y, min(rect.end.y, point.y)))
func find_control(gp): func find_control(gp):
@ -45,7 +45,7 @@ func find_control(gp):
return { node=c, widget=widget } return { node=c, widget=widget }
return null return null
func _draw(): func _draw() -> void:
#draw_rect(Rect2(rect_position, rect_size), Color(1.0, 0.0, 0.0, 0.2)) #draw_rect(Rect2(rect_position, rect_size), Color(1.0, 0.0, 0.0, 0.2))
#draw_rect(Rect2(rect_position, rect_size), Color(1.0, 1.0, 0.0), false) #draw_rect(Rect2(rect_position, rect_size), Color(1.0, 1.0, 0.0), false)
var start = get_global_transform().xform_inv(source.get_global_transform().xform(0.5*source.rect_size)) var start = get_global_transform().xform_inv(source.get_global_transform().xform(0.5*source.rect_size))
@ -61,7 +61,7 @@ func _draw():
start = closest(rect, end) start = closest(rect, end)
draw_line(start, end, color, 1, true) draw_line(start, end, color, 1, true)
func _input(event): func _input(event: InputEvent) -> void:
if event is InputEventKey: if event is InputEventKey:
if event.scancode == KEY_ESCAPE: if event.scancode == KEY_ESCAPE:
set_process_input(false) set_process_input(false)

View File

@ -3,10 +3,10 @@ extends WindowDialog
signal ok signal ok
func set_value(n, v): func set_value(n, v) -> void:
$VBoxContainer/GridContainer/name.text = n $VBoxContainer/GridContainer/name.text = n
$VBoxContainer/GridContainer/value.text = v $VBoxContainer/GridContainer/value.text = v
func _on_OK_pressed(): func _on_OK_pressed() -> void:
emit_signal("ok", $VBoxContainer/GridContainer/name.text, $VBoxContainer/GridContainer/value.text) emit_signal("ok", $VBoxContainer/GridContainer/name.text, $VBoxContainer/GridContainer/value.text)
queue_free() queue_free()

View File

@ -1,10 +1,7 @@
tool tool
extends HBoxContainer extends HBoxContainer
func _ready(): func set_model_data(data) -> void:
pass
func set_model_data(data):
$Name.text = data.name $Name.text = data.name
$Label.text = data.label $Label.text = data.label
if data.type == "rgb": if data.type == "rgb":
@ -15,7 +12,7 @@ func set_model_data(data):
$Type.selected = 0 $Type.selected = 0
$Default.text = data.default $Default.text = data.default
func get_model_data(): func get_model_data() -> Dictionary:
var data = { name=$Name.text, label=$Label.text, default=$Default.text } var data = { name=$Name.text, label=$Label.text, default=$Default.text }
if $Type.selected == 1: if $Type.selected == 1:
data.type = "rgb" data.type = "rgb"
@ -25,5 +22,5 @@ func get_model_data():
data.type = "f" data.type = "f"
return data return data
func _on_Delete_pressed(): func _on_Delete_pressed() -> void:
queue_free() queue_free()

View File

@ -13,18 +13,18 @@ const OutputEditor = preload("res://addons/material_maker/widgets/node_editor/ou
signal node_changed signal node_changed
func _ready(): func _ready() -> void:
main_code_editor.add_color_region("//", "", Color(0, 0.5, 0), true) main_code_editor.add_color_region("//", "", Color(0, 0.5, 0), true)
instance_functions_editor.add_color_region("//", "", Color(0, 0.5, 0), true) instance_functions_editor.add_color_region("//", "", Color(0, 0.5, 0), true)
global_functions_editor.add_color_region("//", "", Color(0, 0.5, 0), true) global_functions_editor.add_color_region("//", "", Color(0, 0.5, 0), true)
func add_item(parent, scene): func add_item(parent, scene) -> Node:
var object = scene.instance() var object = scene.instance()
parent.add_child(object) parent.add_child(object)
parent.move_child(object, parent.get_child_count()-2) parent.move_child(object, parent.get_child_count()-2)
return object return object
func set_model_data(data): func set_model_data(data) -> void:
if data.has("name"): if data.has("name"):
$Sizer/Tabs/General/Name/Name.text = data.name $Sizer/Tabs/General/Name/Name.text = data.name
if data.has("parameters"): if data.has("parameters"):
@ -43,7 +43,7 @@ func set_model_data(data):
if data.has("code"): if data.has("code"):
main_code_editor.text = data.code main_code_editor.text = data.code
func get_model_data(): func get_model_data() -> Dictionary:
var data = { var data = {
name=$Sizer/Tabs/General/Name/Name.text, name=$Sizer/Tabs/General/Name/Name.text,
global=global_functions_editor.text, global=global_functions_editor.text,
@ -64,21 +64,21 @@ func get_model_data():
data.outputs.append(o.get_model_data()) data.outputs.append(o.get_model_data())
return data return data
func _on_AddParameter_pressed(): func _on_AddParameter_pressed() -> void:
add_item($Sizer/Tabs/General/Parameters/Sizer, ParameterEditor) add_item($Sizer/Tabs/General/Parameters/Sizer, ParameterEditor)
func _on_AddInput_pressed(): func _on_AddInput_pressed() -> void:
add_item($Sizer/Tabs/General/Inputs/Sizer, InputEditor) add_item($Sizer/Tabs/General/Inputs/Sizer, InputEditor)
func _on_AddOutput_pressed(): func _on_AddOutput_pressed() -> void:
add_item($Sizer/Tabs/Outputs/Outputs/Sizer, OutputEditor) add_item($Sizer/Tabs/Outputs/Outputs/Sizer, OutputEditor)
func _on_Apply_pressed(): func _on_Apply_pressed() -> void:
emit_signal("node_changed", get_model_data()) emit_signal("node_changed", get_model_data())
func _on_OK_pressed(): func _on_OK_pressed() -> void:
emit_signal("node_changed", get_model_data()) emit_signal("node_changed", get_model_data())
queue_free() queue_free()
func _on_Cancel_pressed(): func _on_Cancel_pressed() -> void:
queue_free() queue_free()

View File

@ -1,10 +1,7 @@
tool tool
extends HBoxContainer extends HBoxContainer
func _ready(): func set_model_data(data) -> void:
pass
func set_model_data(data):
if data.has("rgb"): if data.has("rgb"):
$Type.selected = 1 $Type.selected = 1
$Value.text = data.rgb $Value.text = data.rgb
@ -15,7 +12,7 @@ func set_model_data(data):
$Type.selected = 0 $Type.selected = 0
$Value.text = data.f $Value.text = data.f
func get_model_data(): func get_model_data() -> Dictionary:
if $Type.selected == 1: if $Type.selected == 1:
return { rgb=$Value.text } return { rgb=$Value.text }
elif $Type.selected == 2: elif $Type.selected == 2:
@ -23,5 +20,5 @@ func get_model_data():
else: else:
return { f=$Value.text } return { f=$Value.text }
func _on_Delete_pressed(): func _on_Delete_pressed() -> void:
queue_free() queue_free()

View File

@ -1,13 +1,13 @@
tool tool
extends HBoxContainer extends HBoxContainer
func _ready(): func _ready() -> void:
$Type.clear() $Type.clear()
for t in $Types.get_children(): for t in $Types.get_children():
$Type.add_item(t.name) $Type.add_item(t.name)
_on_Type_item_selected($Type.selected) _on_Type_item_selected($Type.selected)
func set_model_data(data): func set_model_data(data) -> void:
if data.has("name"): if data.has("name"):
$Name.text = data.name $Name.text = data.name
if data.has("label"): if data.has("label"):
@ -20,17 +20,17 @@ func set_model_data(data):
$Type.selected = selected $Type.selected = selected
_on_Type_item_selected(selected) _on_Type_item_selected(selected)
func get_model_data(): func get_model_data() -> Dictionary:
var data = $Types.get_node($Type.get_item_text($Type.selected)).get_model_data() var data = $Types.get_node($Type.get_item_text($Type.selected)).get_model_data()
data.name=$Name.text data.name=$Name.text
data.label=$Label.text data.label=$Label.text
data.type=$Type.get_item_text($Type.selected) data.type=$Type.get_item_text($Type.selected)
return data return data
func _on_Delete_pressed(): func _on_Delete_pressed() -> void:
queue_free() queue_free()
func _on_Type_item_selected(ID): func _on_Type_item_selected(ID) -> void:
for t in $Types.get_children(): for t in $Types.get_children():
t.visible = false t.visible = false
var t = $Types.get_child(ID) var t = $Types.get_child(ID)

View File

@ -1,14 +1,11 @@
tool tool
extends HBoxContainer extends HBoxContainer
func _ready(): func get_model_data() -> Dictionary:
pass return {
default = $Default.pressed,
}
func get_model_data(): func set_model_data(data) -> void:
var data = {}
data.default = $Default.pressed
return data
func set_model_data(data):
if data.has("default"): if data.has("default"):
$Default.pressed = data.default $Default.pressed = data.default

View File

@ -1,15 +1,13 @@
tool tool
extends HBoxContainer extends HBoxContainer
func _ready(): func get_model_data() -> Dictionary:
pass var default_color = $Default.color
func get_model_data(): return {
var data = {} default = { r=default_color.r, g=default_color.g, b=default_color.b, a=default_color.a },
var default = $Default.color }
data.default = { r=default.r, g=default.g, b=default.b, a=default.a}
return data
func set_model_data(data): func set_model_data(data) -> void:
if data.has("default"): if data.has("default"):
$Default.color = Color(data.default.r, data.default.g, data.default.b, data.default.a) $Default.color = Color(data.default.r, data.default.g, data.default.b, data.default.a)

View File

@ -10,16 +10,16 @@ const ENUM_REMOVE = -3
const ENUM_UP = -4 const ENUM_UP = -4
const ENUM_DOWN = -5 const ENUM_DOWN = -5
func _ready(): func _ready() -> void:
update_enum_list() update_enum_list()
func get_model_data(): func get_model_data() -> Dictionary:
var data = {} return {
data.values = enum_values values = enum_values,
data.default = enum_current default = enum_current,
return data }
func set_model_data(data): func set_model_data(data) -> void:
enum_values = data.values.duplicate() enum_values = data.values.duplicate()
if data.has("default"): if data.has("default"):
enum_current = data.default enum_current = data.default
@ -27,7 +27,7 @@ func set_model_data(data):
enum_current = 0 enum_current = 0
update_enum_list() update_enum_list()
func update_enum_list(): func update_enum_list() -> void:
var options = $EnumValues var options = $EnumValues
options.clear() options.clear()
if !enum_values.empty(): if !enum_values.empty():
@ -46,7 +46,7 @@ func update_enum_list():
options.selected = enum_current options.selected = enum_current
options.add_item("Add value", ENUM_ADD) options.add_item("Add value", ENUM_ADD)
func _on_EnumValues_item_selected(id): func _on_EnumValues_item_selected(id) -> void:
id = $EnumValues.get_item_id(id) id = $EnumValues.get_item_id(id)
if id >= 0 and id < enum_values.size(): if id >= 0 and id < enum_values.size():
enum_current = id enum_current = id
@ -77,7 +77,7 @@ func _on_EnumValues_item_selected(id):
enum_current += 1 enum_current += 1
update_enum_list() update_enum_list()
func update_enum_value(n, v, i): func update_enum_value(n, v, i) -> void:
if i == -1: if i == -1:
enum_values.append({ name=n, value=v }) enum_values.append({ name=n, value=v })
enum_current = enum_values.size()-1 enum_current = enum_values.size()-1

View File

@ -1,20 +1,20 @@
tool tool
extends HBoxContainer extends HBoxContainer
func _ready(): func get_model_data() -> Dictionary:
pass var data = {
min = $Min.value,
max = $Max.value,
step = $Step.value,
default = $Default.value,
}
func get_model_data():
var data = {}
data.min = $Min.value
data.max = $Max.value
data.step = $Step.value
data.default = $Default.value
if $SpinBox.pressed: if $SpinBox.pressed:
data.widget = "spinbox" data.widget = "spinbox"
return data return data
func set_model_data(data): func set_model_data(data) -> void:
if data.has("min"): if data.has("min"):
$Min.value = data.min $Min.value = data.min
if data.has("max"): if data.has("max"):

View File

@ -3,15 +3,12 @@ extends HBoxContainer
onready var default = $Default onready var default = $Default
func _ready(): func get_model_data() -> Dictionary:
pass return {
default = default.value.serialize(),
}
func get_model_data(): func set_model_data(data) -> void:
var data = {}
data.default = default.value.serialize()
return data
func set_model_data(data):
if data.has("default"): if data.has("default"):
var v = MMGradient.new() var v = MMGradient.new()
v.deserialize(data.default) v.deserialize(data.default)

View File

@ -5,17 +5,17 @@ var size_first = 0
var size_last = 12 var size_last = 12
var size_default = 8 var size_default = 8
func _ready(): func _ready() -> void:
update_size_configuration() update_size_configuration()
func get_model_data(): func get_model_data() -> Dictionary:
var data = {} return {
data.first = size_first first = size_first,
data.last = size_last last = size_last,
data.default = size_default default = size_default,
return data }
func set_model_data(data): func set_model_data(data) -> void:
if data.has("first"): if data.has("first"):
size_first = data.first size_first = data.first
if data.has("last"): if data.has("last"):
@ -24,25 +24,25 @@ func set_model_data(data):
size_last = data.default size_last = data.default
update_size_configuration() update_size_configuration()
func update_size_option_button(button, first, last, current): func update_size_option_button(button, first, last, current) -> void:
button.clear() button.clear()
for i in range(first, last+1): for i in range(first, last+1):
var s = pow(2, i) var s = pow(2, i)
button.add_item("%dx%d" % [ s, s ]) button.add_item("%dx%d" % [ s, s ])
button.selected = current - first button.selected = current - first
func update_size_configuration(): func update_size_configuration() -> void:
update_size_option_button($First, 0, size_last, size_first) update_size_option_button($First, 0, size_last, size_first)
update_size_option_button($Last, size_first, 12, size_last) update_size_option_button($Last, size_first, 12, size_last)
update_size_option_button($Default, size_first, size_last, size_default) update_size_option_button($Default, size_first, size_last, size_default)
func _on_First_item_selected(ID): func _on_First_item_selected(ID) -> void:
size_first = ID size_first = ID
update_size_configuration() update_size_configuration()
func _on_Last_item_selected(ID): func _on_Last_item_selected(ID) -> void:
size_last = size_first + ID size_last = size_first + ID
update_size_configuration() update_size_configuration()
func _on_Default_item_selected(ID): func _on_Default_item_selected(ID) -> void:
size_default = size_first + ID size_default = size_first + ID

View File

@ -6,16 +6,13 @@ var current_tab = -1 setget set_current_tab
signal tab_changed signal tab_changed
signal no_more_tabs signal no_more_tabs
func _ready(): func add_child(control, legible_unique_name = false) -> void:
pass
func add_child(control, legible_unique_name = false):
.add_child(control, legible_unique_name) .add_child(control, legible_unique_name)
if !(control is Tabs): if !(control is Tabs):
$Tabs.add_tab(control.name) $Tabs.add_tab(control.name)
move_child(control, $Tabs.get_tab_count()-1) move_child(control, $Tabs.get_tab_count()-1)
func close_tab(tab = null): func close_tab(tab = null) -> void:
if tab == null: if tab == null:
tab = $Tabs.get_current_tab() tab = $Tabs.get_current_tab()
get_child(tab).queue_free() get_child(tab).queue_free()
@ -29,12 +26,12 @@ func close_tab(tab = null):
else: else:
set_current_tab(0) set_current_tab(0)
func move_active_tab_to(idx_to): func move_active_tab_to(idx_to) -> void:
$Tabs.move_tab(current_tab, idx_to) $Tabs.move_tab(current_tab, idx_to)
move_child(get_child(current_tab), idx_to) move_child(get_child(current_tab), idx_to)
set_current_tab(idx_to) set_current_tab(idx_to)
func set_current_tab(t): func set_current_tab(t) -> void:
if t == current_tab or t < 0 or t >= $Tabs.get_tab_count(): if t == current_tab or t < 0 or t >= $Tabs.get_tab_count():
return return
var node var node
@ -49,15 +46,14 @@ func set_current_tab(t):
$Tabs.current_tab = current_tab $Tabs.current_tab = current_tab
emit_signal("tab_changed", current_tab) emit_signal("tab_changed", current_tab)
func set_tab_title(index, title): func set_tab_title(index, title) -> void:
$Tabs.set_tab_title(index, title) $Tabs.set_tab_title(index, title)
func get_current_tab_control(): func get_current_tab_control() -> Node:
return get_child(current_tab) return get_child(current_tab)
func _on_Tabs_tab_changed(tab): func _on_Tabs_tab_changed(tab) -> void:
set_current_tab(tab) set_current_tab(tab)
func _on_Projects_resized(): func _on_Projects_resized() -> void:
$Tabs.rect_size.x = rect_size.x $Tabs.rect_size.x = rect_size.x

View File

@ -3,15 +3,15 @@ extends WindowDialog
signal ok signal ok
func _ready(): func _ready() -> void:
popup() popup()
func set_title(title): func set_title(title) -> void:
window_title = title window_title = title
func set_text(text): func set_text(text) -> void:
$VBoxContainer/TextEdit.text = text $VBoxContainer/TextEdit.text = text
func _on_OK_pressed(): func _on_OK_pressed() -> void:
emit_signal("ok", $VBoxContainer/TextEdit.text) emit_signal("ok", $VBoxContainer/TextEdit.text)
queue_free() queue_free()