226 lines
7.3 KiB
GDScript
226 lines
7.3 KiB
GDScript
# MIT License
|
|
#
|
|
# Copyright (c) 2023 Mark McKay
|
|
# https://github.com/blackears/cyclopsLevelBuilder
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
@tool
|
|
extends EditorPlugin
|
|
class_name CyclopsLevelBuilder
|
|
|
|
signal active_node_changed
|
|
signal selection_changed
|
|
|
|
const AUTOLOAD_NAME = "CyclopsAutoload"
|
|
|
|
var material_dock:Control
|
|
var uv_editor_dock:Control
|
|
var tool_properties_dock:Control
|
|
#var sticky_toolbar:StickyToolbar
|
|
var editor_toolbar:EditorToolbar
|
|
var activated:bool = false
|
|
|
|
|
|
var block_create_distance:float = 20
|
|
var tool:CyclopsTool = null
|
|
var lock_uvs:bool = false
|
|
var tool_overlay_extrude:float = .01
|
|
|
|
var tool_uv_transform:Transform2D
|
|
var tool_material_path:String
|
|
|
|
var handle_point_radius:float = .05
|
|
var handle_screen_radius:float = 4
|
|
|
|
var drag_start_radius:float = 4
|
|
|
|
enum Mode { OBJECT, EDIT }
|
|
var mode:Mode = Mode.OBJECT
|
|
enum EditMode { VERTEX, EDGE, FACE }
|
|
var edit_mode:EditMode = EditMode.VERTEX
|
|
|
|
var display_mode:DisplayMode.Type = DisplayMode.Type.TEXTURED
|
|
|
|
#var _active_node:GeometryBrush
|
|
var active_node:CyclopsBlocks:
|
|
get:
|
|
return active_node
|
|
set(value):
|
|
if active_node != value:
|
|
active_node = value
|
|
active_node_changed.emit()
|
|
|
|
func get_selected_blocks()->Array[CyclopsConvexBlock]:
|
|
var result:Array[CyclopsConvexBlock]
|
|
|
|
if active_node:
|
|
for child in active_node.get_children():
|
|
if child is CyclopsConvexBlock:
|
|
var block:CyclopsConvexBlock = child
|
|
if child.selected:
|
|
result.append(child)
|
|
|
|
return result
|
|
|
|
func _get_plugin_name()->String:
|
|
return "CyclopsLevelBuilder"
|
|
|
|
func _get_plugin_icon()->Texture2D:
|
|
return preload("res://addons/cyclops_level_builder/art/cyclops.svg")
|
|
|
|
func _enter_tree():
|
|
add_custom_type("CyclopsBlocks", "Node3D", preload("nodes/cyclops_blocks.gd"), preload("nodes/cyclops_blocks_icon.png"))
|
|
add_custom_type("CyclopsConvexBlock", "Node", preload("nodes/cyclops_convex_block.gd"), preload("nodes/cyclops_blocks_icon.png"))
|
|
add_custom_type("CyclopsConvexBlockBody", "Node", preload("nodes/cyclops_convex_block_body.gd"), preload("nodes/cyclops_blocks_icon.png"))
|
|
|
|
add_autoload_singleton(AUTOLOAD_NAME, "res://addons/cyclops_level_builder/cyclops_global_scene.tscn")
|
|
|
|
material_dock = preload("res://addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.tscn").instantiate()
|
|
material_dock.builder = self
|
|
|
|
uv_editor_dock = preload("res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_viewport.tscn").instantiate()
|
|
uv_editor_dock.builder = self
|
|
|
|
tool_properties_dock = preload("res://addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.tscn").instantiate()
|
|
tool_properties_dock.builder = self
|
|
|
|
editor_toolbar = preload("menu/editor_toolbar.tscn").instantiate()
|
|
editor_toolbar.editor_plugin = self
|
|
|
|
# sticky_toolbar = preload("menu/sticky_toolbar.tscn").instantiate()
|
|
# sticky_toolbar.plugin = self
|
|
# add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, sticky_toolbar)
|
|
|
|
var editor:EditorInterface = get_editor_interface()
|
|
var selection:EditorSelection = editor.get_selection()
|
|
selection.selection_changed.connect(on_selection_changed)
|
|
|
|
update_activation()
|
|
|
|
|
|
#Wait until everything is loaded
|
|
await get_tree().process_frame
|
|
var global_scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload")
|
|
global_scene.builder = self
|
|
|
|
switch_to_tool(ToolBlock.new())
|
|
|
|
func find_blocks_root(node:Node)->CyclopsBlocks:
|
|
if node is CyclopsBlocks:
|
|
return node
|
|
if node is CyclopsConvexBlock:
|
|
return find_blocks_root(node.get_parent())
|
|
return null
|
|
|
|
func update_activation():
|
|
var editor:EditorInterface = get_editor_interface()
|
|
var selection:EditorSelection = editor.get_selection()
|
|
var nodes:Array[Node] = selection.get_selected_nodes()
|
|
if !nodes.is_empty():
|
|
var node:Node = nodes[0]
|
|
|
|
var blocks_root:CyclopsBlocks = find_blocks_root(node)
|
|
|
|
if blocks_root:
|
|
active_node = blocks_root
|
|
if !activated:
|
|
add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar)
|
|
add_control_to_dock(DOCK_SLOT_RIGHT_BL, material_dock)
|
|
add_control_to_dock(DOCK_SLOT_RIGHT_BL, uv_editor_dock)
|
|
add_control_to_dock(DOCK_SLOT_RIGHT_BL, tool_properties_dock)
|
|
activated = true
|
|
else:
|
|
if activated:
|
|
remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar)
|
|
remove_control_from_docks(material_dock)
|
|
remove_control_from_docks(uv_editor_dock)
|
|
remove_control_from_docks(tool_properties_dock)
|
|
activated = false
|
|
else:
|
|
active_node = null
|
|
|
|
func on_selection_changed():
|
|
update_activation()
|
|
|
|
func _exit_tree():
|
|
# Clean-up of the plugin goes here.
|
|
remove_autoload_singleton(AUTOLOAD_NAME)
|
|
|
|
remove_custom_type("CyclopsBlocks")
|
|
remove_custom_type("CyclopsConvexBlock")
|
|
remove_custom_type("CyclopsConvexBlockBody")
|
|
|
|
# remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, sticky_toolbar)
|
|
|
|
if activated:
|
|
remove_control_from_docks(material_dock)
|
|
remove_control_from_docks(uv_editor_dock)
|
|
remove_control_from_docks(tool_properties_dock)
|
|
remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, editor_toolbar)
|
|
|
|
material_dock.queue_free()
|
|
uv_editor_dock.queue_free()
|
|
tool_properties_dock.queue_free()
|
|
editor_toolbar.queue_free()
|
|
|
|
func _handles(object:Object):
|
|
return object is CyclopsBlocks or object is CyclopsConvexBlock
|
|
|
|
func _forward_3d_draw_over_viewport(viewport_control:Control):
|
|
#Draw on top of viweport here
|
|
pass
|
|
|
|
func _forward_3d_gui_input(viewport_camera:Camera3D, event:InputEvent):
|
|
#print("plugin: " + event.as_text())
|
|
|
|
if tool:
|
|
var result:bool = tool._gui_input(viewport_camera, event)
|
|
tool._draw_tool(viewport_camera)
|
|
return EditorPlugin.AFTER_GUI_INPUT_STOP if result else EditorPlugin.AFTER_GUI_INPUT_PASS
|
|
|
|
return EditorPlugin.AFTER_GUI_INPUT_PASS
|
|
|
|
func _get_state()->Dictionary:
|
|
var state:Dictionary = {}
|
|
material_dock.save_state(state)
|
|
uv_editor_dock.save_state(state)
|
|
tool_properties_dock.save_state(state)
|
|
return state
|
|
|
|
func _set_state(state):
|
|
material_dock.load_state(state)
|
|
uv_editor_dock.load_state(state)
|
|
tool_properties_dock.load_state(state)
|
|
|
|
func switch_to_tool(_tool:CyclopsTool):
|
|
if tool:
|
|
tool._deactivate()
|
|
|
|
tool = _tool
|
|
|
|
if tool:
|
|
tool._activate(self)
|
|
var control:Control = tool._get_tool_properties_editor()
|
|
tool_properties_dock.set_editor(control)
|
|
|
|
func get_global_scene()->CyclopsGlobalScene:
|
|
var scene:CyclopsGlobalScene = get_node("/root/CyclopsAutoload")
|
|
return scene
|