Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions material_maker/panels/graph_edit/graph_edit.gd
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ var need_save_crash_recovery : bool = false
var top_generator = null
var generator = null

var previous_material_generator : Dictionary
var previous_material_connections : Array

const PREVIEW_COUNT = 2
var current_preview : Array = [ null, null ]
var locked_preview : Array = [ null, null ]
Expand Down Expand Up @@ -169,6 +172,8 @@ func _gui_input(event) -> void:
if event.double_click:
if get_nodes_under_mouse().is_empty():
on_ButtonUp_pressed()
elif event.alt_pressed and event.shift_pressed and event.pressed:
handle_material_link()
else:
process_port_click(event.is_pressed())
call_deferred("check_previews")
Expand Down Expand Up @@ -221,6 +226,117 @@ func _gui_input(event) -> void:
if rect.has_point(get_global_mouse_position()):
mm_globals.set_tip_text("Space/#RMB: Nodes menu, Arrow keys: Pan, Mouse wheel: Zoom", 3)

func handle_material_link() -> void:
if get_nodes_under_mouse().is_empty() or subgraph_ui.visible:
return

var target_material_port : int = 0
var target_preview_slot : int = -1
var current_preview_port : int = -1

var existing_connection : Dictionary
var compatible_preview_map : Dictionary

var selected_node : GraphNode
var material_node : GraphNode = get_node("node_Material")

var same_connection : bool = false

var selection := get_nodes_under_mouse()
selection.sort_custom(func(a,b): return a.get_index() > b.get_index())

if not selection.is_empty():
selected_node = selection.front()
if selected_node != material_node:
set_selected(selected_node)

# save current material connections
if not previous_material_connections:
for c in get_connection_list():
if (c.to_node == material_node.name):
previous_material_connections.append(c)

# save material params
if not previous_material_generator:
previous_material_generator = material_node.generator.serialize()

# switch to unlit material
if material_node.generator.model != "material_unlit":
material_node.generator.model = "material_unlit"
material_node.update_shader_generator(
mm_loader.predefined_generators["material_unlit"].shader_model)
material_node.generator.set_parameter("blend", 1)

for slot_type in mm_io_types.types:
var slot_id : int = mm_io_types.types[slot_type]["slot_type"]
compatible_preview_map[str(slot_id)] = []

for slot in selected_node.get_output_port_count():
compatible_preview_map[
str(selected_node.get_output_port_type(slot))].append(slot)

for c in get_connection_list():
if material_node.name == c.to_node:
if (c.from_node == selected_node.name
and c.to_node == material_node.name
and c.to_port == target_material_port):
existing_connection = c
current_preview_port = c.from_port
break

var compat_preview_slots : Array = compatible_preview_map[
str(material_node.get_input_port_type(0))]

# allow previewing "any" slot type (i.e. Switch/Reroute)
if selected_node.get_output_port_type(0) == 42:
compat_preview_slots = compatible_preview_map["42"]

# cycle compatible slots types from previewing node
if compat_preview_slots.size():
target_preview_slot = compat_preview_slots.find(current_preview_port)
target_preview_slot = compat_preview_slots[
wrap(target_preview_slot+1, 0, compat_preview_slots.size())]
else:
return

if existing_connection:
same_connection = (existing_connection.from_node == selected_node.name
and existing_connection.to_node == material_node.name
and existing_connection.from_port == target_preview_slot
and existing_connection.to_port == target_material_port)

if not same_connection:
if existing_connection:
undoredo.start_group()
on_disconnect_node(existing_connection.from_node,
existing_connection.from_port,
existing_connection.to_node,
existing_connection.to_port)
on_connect_node(selected_node.name, target_preview_slot,
material_node.name, target_material_port)
undoredo.end_group()

else:
# restore previous material node/params
if previous_material_generator:
material_node.generator.model = previous_material_generator.type
material_node.update_shader_generator(
mm_loader.predefined_generators[previous_material_generator.type].shader_model)
material_node.generator.deserialize(previous_material_generator)
previous_material_generator.clear()

# restore connections
undoredo.start_group()
for c in get_connection_list():
if c.to_node == material_node.name:
on_disconnect_node(c.from_node, c.from_port, c.to_node, c.to_port)
if previous_material_connections.size():
for c in previous_material_connections:
on_connect_node(c.from_node, c.from_port, c.to_node, c.to_port)
previous_material_connections.clear()
undoredo.end_group()


func get_padded_node_rect(graph_node:GraphNode) -> Rect2:
var rect : Rect2 = graph_node.get_global_rect()
var padding := 8 * graph_node.get_global_transform().get_scale().x
Expand Down
1 change: 1 addition & 0 deletions material_maker/widgets/float_edit/float_edit.gd
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ func _notification(what):


func update() -> void:
await get_tree().process_frame
var is_hovered := Rect2(Vector2(), size).has_point(get_local_mouse_position()) or mode == Modes.SLIDING
$Slider.add_theme_stylebox_override("fill", get_theme_stylebox("fill_hover" if is_hovered else "fill_normal"))
$Slider.add_theme_stylebox_override("background", get_theme_stylebox("hover" if is_hovered else "normal"))
Expand Down
Loading