Skip to content
Draft
45 changes: 23 additions & 22 deletions project/addons/terrain_3d/src/asset_dock.gd
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ class ListContainer extends Container:

func update_asset_list() -> void:
if plugin.debug:
print("Terrain3DListContainer: ", name, " update_asset_list")
print("Terrain3DListContainer ", name, ": update_asset_list")
clear()

# Grab terrain
Expand Down Expand Up @@ -573,7 +573,7 @@ class ListContainer extends Container:

var res_id: int = p_resource.id if p_resource else entries.size()
entry.hovered.connect(_on_resource_hovered.bind(res_id))
entry.selected.connect(set_selected_id.bind(entries.size()))
entry.clicked.connect(clicked_id.bind(res_id))
entry.inspected.connect(_on_resource_inspected)
entry.changed.connect(_on_resource_changed.bind(res_id))
entry.type = type
Expand All @@ -597,25 +597,26 @@ class ListContainer extends Container:
set_selected_id(clamp(p_new_id, 0, entries.size() - 2))


func clicked_id(p_id: int) -> void:
# Select Tool if clicking an asset
plugin.select_terrain()
if type == Terrain3DAssets.TYPE_TEXTURE and \
not plugin.editor.get_tool() in [ Terrain3DEditor.TEXTURE, Terrain3DEditor.COLOR, Terrain3DEditor.ROUGHNESS ]:
plugin.ui.toolbar.change_tool("PaintTexture")
elif type == Terrain3DAssets.TYPE_MESH and plugin.editor.get_tool() != Terrain3DEditor.INSTANCER:
plugin.ui.toolbar.change_tool("InstanceMeshes")
set_selected_id(p_id)


func set_selected_id(p_id: int) -> void:
# "Add new" is the final entry only when search box is blank
var max_id: int = max(0, entries.size() - (1 if search_text else 2))
if plugin.debug:
print("Terrain3DListContainer: set_selected_id: ", selected_id, " to ", clamp(p_id, 0, max_id))
print("Terrain3DListContainer ", name, ": set_selected_id: ", selected_id, " to ", clamp(p_id, 0, max_id))
selected_id = clamp(p_id, 0, max_id)
for i in entries.size():
var entry: ListEntry = entries[i]
entry.set_selected(i == selected_id)

# Select Paint tool if clicking a texture
plugin.select_terrain()
if type == Terrain3DAssets.TYPE_TEXTURE and \
not plugin.editor.get_tool() in [ Terrain3DEditor.TEXTURE, Terrain3DEditor.COLOR, Terrain3DEditor.ROUGHNESS ]:
plugin.ui.toolbar.change_tool("PaintTexture")
elif type == Terrain3DAssets.TYPE_MESH and plugin.editor.get_tool() != Terrain3DEditor.INSTANCER:
plugin.ui.toolbar.change_tool("InstanceMeshes")

# Update editor with selected brush
plugin.ui._on_setting_changed()


Expand All @@ -624,7 +625,7 @@ class ListContainer extends Container:
var max_id: int = max(0, entries.size() - (1 if search_text else 2))
var id: int = clamp(selected_id, 0, max_id)
if plugin.debug:
print("Terrain3DListContainer: get_selected_asset_id: selected_id: ", selected_id, ", clamped: ", id, ", entries: ", entries.size())
print("Terrain3DListContainer ", name, ": get_selected_asset_id: selected_id: ", selected_id, ", clamped: ", id, ", entries: ", entries.size())
if id >= entries.size():
return 0
var res: Resource = entries[id].resource
Expand All @@ -637,7 +638,7 @@ class ListContainer extends Container:


func _on_resource_inspected(p_resource: Resource) -> void:
await get_tree().create_timer(.01).timeout
await get_tree().process_frame
EditorInterface.edit_resource(p_resource)


Expand All @@ -646,7 +647,7 @@ class ListContainer extends Container:
return
if not p_resource:
if plugin.debug:
print("Terrain3DAssetDock: _on_resource_changed: removing asset ID: ", p_id)
print("Terrain3DListContainer ", name, ": _on_resource_changed: removing asset ID: ", p_id)
_clearing_resource = true
var asset_dock: Control = get_parent().get_parent().get_parent()
if type == Terrain3DAssets.TYPE_TEXTURE:
Expand All @@ -662,7 +663,7 @@ class ListContainer extends Container:

if not plugin.is_terrain_valid():
plugin.select_terrain()
await get_tree().create_timer(.01).timeout
await get_tree().process_frame

if plugin.is_terrain_valid():
if type == Terrain3DAssets.TYPE_TEXTURE:
Expand Down Expand Up @@ -723,7 +724,7 @@ class ListContainer extends Container:

class ListEntry extends MarginContainer:
signal hovered()
signal selected()
signal clicked()
signal changed(resource: Resource)
signal inspected(resource: Resource)

Expand Down Expand Up @@ -986,7 +987,7 @@ class ListEntry extends MarginContainer:
set_edited_resource(Terrain3DMeshAsset.new(), false)
_on_edit()
else:
emit_signal("selected")
emit_signal("clicked")
MOUSE_BUTTON_RIGHT:
if resource:
_on_edit()
Expand Down Expand Up @@ -1029,7 +1030,7 @@ class ListEntry extends MarginContainer:
if resource is Terrain3DMeshAsset:
res.id = resource.id
set_edited_resource(res, false)
emit_signal("selected")
emit_signal("clicked")
emit_signal("inspected", resource)


Expand Down Expand Up @@ -1059,7 +1060,7 @@ class ListEntry extends MarginContainer:
is_selected = value
if is_selected:
# Handle scrolling to show the selected item
await RenderingServer.frame_pre_draw
await get_tree().process_frame
if is_inside_tree():
get_parent().get_parent().get_v_scroll_bar().ratio = position.y / get_parent().size.y
queue_redraw()
Expand All @@ -1073,7 +1074,7 @@ class ListEntry extends MarginContainer:


func _on_edit() -> void:
emit_signal("selected")
emit_signal("clicked")
emit_signal("inspected", resource)


Expand Down
29 changes: 22 additions & 7 deletions project/addons/terrain_3d/src/editor_plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const RegionGizmo: Script = preload("res://addons/terrain_3d/src/region_gizmo.gd
const ASSET_DOCK: String = "res://addons/terrain_3d/src/asset_dock.tscn"

# Editor Plugin
var debug: int = 0 # Set 1 normal, 2 verbose, or = terrain.debug in _edit()
var debug: int = 0 # Set in _edit()
var editor: Terrain3DEditor
var editor_settings: EditorSettings
var ui: Node # Terrain3DUI see Godot #75388
Expand All @@ -19,6 +19,8 @@ var region_gizmo: RegionGizmo
var current_region_position: Vector2
var mouse_global_position: Vector3 = Vector3.ZERO
var godot_editor_window: Window # The Godot Editor window
var viewport: SubViewport # Viewport the mouse was last in
var mouse_in_main: bool = false # Helper to track when mouse is in the editor vp

# Terrain
var terrain: Terrain3D
Expand All @@ -36,15 +38,20 @@ var _use_meta: bool = false


func _init() -> void:
if debug:
print("Terrain3DEditorPlugin: _init")
if OS.get_name() == "macOS":
_use_meta = true

# Get the Godot Editor window. Structure is root:Window/EditorNode/Base Control
godot_editor_window = EditorInterface.get_base_control().get_parent().get_parent()
godot_editor_window.focus_entered.connect(_on_godot_focus_entered)
EditorInterface.get_inspector().mouse_entered.connect(func(): mouse_in_main = false)



func _enter_tree() -> void:
if debug:
print("Terrain3DEditorPlugin: _enter_tree")
editor = Terrain3DEditor.new()
setup_editor_settings()
ui = Terrain3DUI.new()
Expand All @@ -60,6 +67,8 @@ func _enter_tree() -> void:


func _exit_tree() -> void:
if debug:
print("Terrain3DEditorPlugin: _exit_tree")
asset_dock.remove_dock(true)
asset_dock.queue_free()
ui.queue_free()
Expand All @@ -73,7 +82,6 @@ func _on_godot_focus_entered() -> void:
if debug > 1:
print("Terrain3DEditorPlugin: _on_godot_focus_entered")
_read_input()
ui.update_decal()


## EditorPlugin selection function call chain isn't consistent. Here's the map of calls:
Expand Down Expand Up @@ -101,6 +109,8 @@ func _handles(p_object: Object) -> bool:


func _make_visible(p_visible: bool, p_redraw: bool = false) -> void:
if debug:
print("Terrain3DEditorPlugin: _make_visible(%s, %s)" % [ p_visible, p_redraw ])
if p_visible and is_selected():
ui.set_visible(true)
asset_dock.update_dock()
Expand All @@ -119,6 +129,7 @@ func _edit(p_object: Object) -> void:
_last_terrain = terrain
terrain.set_plugin(self)
terrain.set_editor(editor)
debug = terrain.debug_level
editor.set_terrain(terrain)
region_gizmo.set_node_3d(terrain)
terrain.add_gizmo(region_gizmo)
Expand Down Expand Up @@ -159,13 +170,15 @@ func _clear() -> void:


func _forward_3d_gui_input(p_viewport_camera: Camera3D, p_event: InputEvent) -> AfterGUIInput:
mouse_in_main = true
if not is_terrain_valid():
return AFTER_GUI_INPUT_PASS

var continue_input: AfterGUIInput = _read_input(p_event)
if continue_input != AFTER_GUI_INPUT_CUSTOM:
return continue_input
ui.update_decal()
if terrain.dev_mode == Terrain3D.READ_ONLY:
return AFTER_GUI_INPUT_CUSTOM

## Setup active camera & viewport
# Always update this for all inputs, as the mouse position can move without
Expand All @@ -177,16 +190,18 @@ func _forward_3d_gui_input(p_viewport_camera: Camera3D, p_event: InputEvent) ->

# Detect if viewport is set to half_resolution
# Structure is: Node3DEditorViewportContainer/Node3DEditorViewport(4)/SubViewportContainer/SubViewport/Camera3D
var editor_vpc: SubViewportContainer = p_viewport_camera.get_parent().get_parent()
var full_resolution: bool = false if editor_vpc.stretch_shrink == 2 else true
viewport = p_viewport_camera.get_parent()
var full_resolution: bool = false if viewport.get_parent().stretch_shrink == 2 else true

## Get mouse location on terrain
# Project 2D mouse position to 3D position and direction
var vp_mouse_pos: Vector2 = editor_vpc.get_local_mouse_position()
var vp_mouse_pos: Vector2 = viewport.get_mouse_position()
var mouse_pos: Vector2 = vp_mouse_pos if full_resolution else vp_mouse_pos / 2
var camera_pos: Vector3 = p_viewport_camera.project_ray_origin(mouse_pos)
var camera_dir: Vector3 = p_viewport_camera.project_ray_normal(mouse_pos)

ui.update_decal()

# If region tool, grab mouse position without considering height
if editor.get_tool() == Terrain3DEditor.REGION:
var t = -Vector3(0, 1, 0).dot(camera_pos) / Vector3(0, 1, 0).dot(camera_dir)
Expand Down
7 changes: 7 additions & 0 deletions project/addons/terrain_3d/src/tool_settings.gd
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ func _on_brush_hover(p_hovering: bool, p_button: Button) -> void:


func _on_pick(p_type: Terrain3DEditor.Tool) -> void:
if plugin.debug:
print("Terrain3DToolSettings: _on_pick: emitting picking: ", p_type, ", ", _on_picked)
emit_signal("picking", p_type, _on_picked)


Expand Down Expand Up @@ -381,6 +383,8 @@ func _on_picked(p_type: Terrain3DEditor.Tool, p_color: Color, p_global_position:

func _on_point_pick(p_type: Terrain3DEditor.Tool, p_name: String) -> void:
assert(p_type == Terrain3DEditor.SCULPT)
if plugin.debug:
print("Terrain3DToolSettings: _on_pick: emitting picking: ", p_type, ", ", _on_point_picked)
emit_signal("picking", p_type, _on_point_picked.bind(p_name))


Expand Down Expand Up @@ -410,6 +414,7 @@ func add_setting(p_args: Dictionary) -> void:
return

var container: HBoxContainer = HBoxContainer.new()
container.custom_minimum_size.y = 36
container.set_v_size_flags(SIZE_EXPAND_FILL)
var control: Control # Houses the setting to be saved
var pending_children: Array[Control]
Expand Down Expand Up @@ -654,6 +659,8 @@ func _on_setting_changed(p_setting: Variant = null) -> void:
# Hide label
if p_setting.get_child_count() > 0:
p_setting.get_child(0).visible = false
if plugin.debug:
print("Terrain3DToolSettings: _on_setting_changed: emitting setting_changed: ", p_setting)
emit_signal("setting_changed", p_setting)


Expand Down
3 changes: 1 addition & 2 deletions project/addons/terrain_3d/src/toolbar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,5 @@ func change_tool(p_name: String) -> void:
if plugin.debug:
print("Terrain3DToolbar: change_tool: ", p_name, ", pressed: ", btn and btn.button_pressed)
if btn and not btn.button_pressed:
if plugin.debug:
print("Terrain3DToolbar: change_tool: pressing button")
await get_tree().process_frame
btn.set_pressed(true)
Loading