material-maker/addons/procedural_material/main_window.gd
Rodolphe Suescun 26720e74e9 Updated Transform, added Decompose and minor changes
Updated Transform so it accepts a greyscale input per parameter. For each pixel, the parameter is multiplied by 2*v-1 (v being the value of the input's pixel) which makes it possible to affect the strength of each transform using an input image. New effects such as whirl and color guided offsets are now possible.

Added Decompose node (does the opposite of combine).

Used another color for inputs/outputs that expect/generate a greyscale image.
2018-08-25 08:07:22 +02:00

225 lines
7.9 KiB
GDScript

tool
extends Panel
var current_tab = -1
const MENU = [
{ menu="File", command="new_material", description="New material" },
{ menu="File", command="load_material", shortcut="Control+O", description="Load material" },
{ menu="File" },
{ menu="File", command="save_material", shortcut="Control+S", description="Save material" },
{ menu="File", command="save_material_as", shortcut="Control+Shift+S", description="Save material as..." },
{ menu="File", command="save_all_materials", description="Save all materials..." },
{ menu="File" },
{ menu="File", command="export_material", shortcut="Control+E", description="Export material" },
{ menu="File" },
{ menu="File", command="close_material", description="Close material" },
{ menu="File", command="quit", shortcut="Control+Q", description="Quit" },
{ menu="Edit", command="edit_cut", shortcut="Control+X", description="Cut" },
{ menu="Edit", command="edit_copy", shortcut="Control+C", description="Copy" },
{ menu="Edit", command="edit_paste", shortcut="Control+V", description="Paste" },
{ menu="Tools", command="add_to_user_library", description="Add selected node to user library" },
{ menu="Tools", command="save_user_library", description="Save user library" },
{ menu="Help", command="show_doc", description="User manual" },
{ menu="Help", command="bug_report", description="Report a bug" },
{ menu="Help" },
{ menu="Help", command="about", description="About" }
]
func _ready():
OS.set_window_title(ProjectSettings.get_setting("application/config/name")+" v"+ProjectSettings.get_setting("application/config/release"))
for m in $VBoxContainer/Menu.get_children():
create_menu(m.get_popup(), m.name)
new_material()
func create_menu(menu, menu_name):
menu.clear()
menu.connect("id_pressed", self, "_on_PopupMenu_id_pressed")
for i in MENU.size():
if MENU[i].menu != menu_name:
continue
if MENU[i].has("submenu"):
var submenu = PopupMenu.new()
create_menu(submenu, MENU[i].submenu)
menu.add_child(submenu)
menu.add_submenu_item(MENU[i].description, submenu.get_name())
elif MENU[i].has("description"):
var shortcut = 0
if MENU[i].has("shortcut"):
for s in MENU[i].shortcut.split("+"):
if s == "Alt":
shortcut |= KEY_MASK_ALT
elif s == "Control":
shortcut |= KEY_MASK_CTRL
elif s == "Shift":
shortcut |= KEY_MASK_SHIFT
else:
shortcut |= OS.find_scancode_from_string(s)
menu.add_item(MENU[i].description, i, shortcut)
else:
menu.add_separator()
return menu
func new_pane():
var graph_edit = preload("res://addons/procedural_material/graph_edit.tscn").instance()
$VBoxContainer/HBoxContainer/Projects.add_child(graph_edit)
$VBoxContainer/HBoxContainer/Projects.current_tab = graph_edit.get_index()
return graph_edit
func new_material():
var graph_edit = new_pane()
graph_edit.update_tab_title()
func load_material():
var dialog = FileDialog.new()
add_child(dialog)
dialog.rect_min_size = Vector2(500, 500)
dialog.access = FileDialog.ACCESS_FILESYSTEM
dialog.mode = FileDialog.MODE_OPEN_FILE
dialog.add_filter("*.ptex;Procedural textures file")
dialog.connect("file_selected", self, "do_load_material")
dialog.popup_centered()
func do_load_material(filename):
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
var node_count = 0
if graph_edit == null:
node_count = 123 # So test below succeeds...
else:
for c in graph_edit.get_children():
if c is GraphNode:
node_count += 1
if node_count > 1:
break
if node_count > 1:
graph_edit = new_pane()
graph_edit.do_load_file(filename)
func save_material():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null:
graph_edit.save_file()
func save_material_as():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null:
graph_edit.save_file_as()
func close_material():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null:
graph_edit.queue_free()
func export_material():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null:
graph_edit.export_textures(256)
func quit():
if Engine.editor_hint:
get_parent().hide()
get_parent().queue_free()
else:
get_tree().quit()
func edit_cut():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null:
graph_edit.cut()
func edit_copy():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null:
graph_edit.copy()
func edit_paste():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null:
graph_edit.paste()
func add_to_user_library():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
if graph_edit != null and graph_edit is GraphEdit:
var selected_nodes = []
for n in graph_edit.get_children():
if n is GraphNode and n.selected:
selected_nodes.append(n)
if !selected_nodes.empty():
var dialog = preload("res://addons/procedural_material/widgets/line_dialog.tscn").instance()
add_child(dialog)
dialog.connect("ok", self, "do_add_to_user_library", [ selected_nodes ])
dialog.popup_centered()
func do_add_to_user_library(name, nodes):
var data
if nodes.size() == 1:
data = nodes[0].serialize()
data.erase("node_position")
else:
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
data = graph_edit.serialize_selection()
var dir = Directory.new()
dir.make_dir("user://library")
dir.make_dir("user://library/user")
data.library = "user://library/user.json"
data.icon = name.right(name.rfind("/")+1).to_lower()
$VBoxContainer/HBoxContainer/VBoxContainer/Library.add_item(data, name)
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
graph_edit.export_texture(nodes[0], "user://library/user/"+data.icon+".png", 64)
func save_user_library():
print("Saving user library")
$VBoxContainer/HBoxContainer/VBoxContainer/Library.save_library("user://library/user.json")
func show_doc():
var doc_path = OS.get_executable_path()
doc_path = doc_path.replace("\\", "/")
doc_path = doc_path.left(doc_path.rfind("/")+1)+"doc/index.html"
var file = File.new()
if file.exists(doc_path):
OS.shell_open(doc_path)
func bug_report():
OS.shell_open("https://github.com/RodZill4/godot-procedural-textures/issues")
func about():
var about_box = preload("res://addons/procedural_material/widgets/about.tscn").instance()
add_child(about_box)
about_box.popup_centered()
func _on_PopupMenu_id_pressed(id):
var node_type = null
if MENU[id].has("command"):
var command = MENU[id].command
if has_method(command):
call(command)
# Preview
func update_preview():
var material_node = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control().get_node("Material")
if material_node != null:
material_node.update_materials($VBoxContainer/HBoxContainer/VBoxContainer/Preview.get_materials())
update_preview_2d()
func update_preview_2d(node = null):
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
var preview = $VBoxContainer/HBoxContainer/VBoxContainer/Preview
if node == null:
for n in graph_edit.get_children():
if n is GraphNode and n.selected:
node = n
break
if node != null:
graph_edit.setup_material(preview.get_2d_material(), node.get_textures(), node.generate_shader())
func _on_Projects_tab_changed(tab):
if tab != current_tab:
for c in get_incoming_connections():
if c.method_name == "update_preview" or c.method_name == "update_preview_2d":
c.source.disconnect(c.signal_name, self, c.method_name)
$VBoxContainer/HBoxContainer/Projects.get_current_tab_control().connect("graph_changed", self, "update_preview")
$VBoxContainer/HBoxContainer/Projects.get_current_tab_control().connect("node_selected", self, "update_preview_2d")
current_tab = tab
update_preview()