Skip to content

Commit 7df7886

Browse files
committed
Merge pull request godotengine#119408 from smix8/canvas_mesh_dragndrop
Add CanvasItemEditor drag and drop for Mesh resources
2 parents 9957353 + 96b2b1d commit 7df7886

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

editor/scene/canvas_item_editor_plugin.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#include "editor/translations/editor_translation_preview_button.h"
5959
#include "editor/translations/editor_translation_preview_menu.h"
6060
#include "scene/2d/audio_stream_player_2d.h"
61+
#include "scene/2d/mesh_instance_2d.h"
6162
#include "scene/2d/physics/touch_screen_button.h"
6263
#include "scene/2d/polygon_2d.h"
6364
#include "scene/2d/skeleton_2d.h"
@@ -6243,6 +6244,14 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons
62436244
add_preview = true;
62446245
}
62456246

6247+
Ref<Mesh> mesh = res;
6248+
if (mesh.is_valid()) {
6249+
MeshInstance2D *mesh_instance = memnew(MeshInstance2D);
6250+
mesh_instance->set_mesh(mesh);
6251+
preview_node->add_child(mesh_instance);
6252+
add_preview = true;
6253+
}
6254+
62466255
Ref<AudioStream> audio = res;
62476256
if (audio.is_valid()) {
62486257
Sprite2D *sprite = memnew(Sprite2D);
@@ -6377,6 +6386,56 @@ void CanvasItemEditorViewport::_create_audio_node(Node *p_parent, const String &
63776386
undo_redo->add_do_property(child, "stream", ResourceCache::get_ref(p_path));
63786387
}
63796388

6389+
void CanvasItemEditorViewport::_create_mesh_node(Node *p_parent, const String &p_path, const Point2 &p_point) {
6390+
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
6391+
6392+
Ref<Mesh> mesh = ResourceCache::get_ref(p_path);
6393+
6394+
MeshInstance2D *child = memnew(MeshInstance2D);
6395+
6396+
// Adjust casing according to project setting. The file name is expected to be in snake_case, but will work for others.
6397+
const String &node_name = Node::adjust_name_casing(p_path.get_file().get_basename());
6398+
if (!node_name.is_empty()) {
6399+
child->set_name(node_name);
6400+
}
6401+
6402+
if (p_parent) {
6403+
undo_redo->add_do_method(p_parent, "add_child", child, true);
6404+
undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
6405+
undo_redo->add_do_reference(child);
6406+
undo_redo->add_undo_method(p_parent, "remove_child", child);
6407+
} else { // If no parent is selected, set as root node of the scene.
6408+
undo_redo->add_do_method(EditorNode::get_singleton(), "set_edited_scene", child);
6409+
undo_redo->add_do_method(child, "set_owner", EditorNode::get_singleton()->get_edited_scene());
6410+
undo_redo->add_do_reference(child);
6411+
undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
6412+
}
6413+
6414+
if (p_parent) {
6415+
String new_name = p_parent->validate_child_name(child);
6416+
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
6417+
undo_redo->add_do_method(ed, "live_debug_create_node", EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent), child->get_class(), new_name);
6418+
undo_redo->add_undo_method(ed, "live_debug_remove_node", NodePath(String(EditorNode::get_singleton()->get_edited_scene()->get_path_to(p_parent)) + "/" + new_name));
6419+
}
6420+
6421+
undo_redo->add_do_property(child, "mesh", mesh);
6422+
6423+
// Compute the global position
6424+
Transform2D xform = canvas_item_editor->get_canvas_transform();
6425+
Point2 target_position = xform.affine_inverse().xform(p_point);
6426+
6427+
// There's nothing to be used as source position, so snapping will work as absolute if enabled.
6428+
target_position = canvas_item_editor->snap_point(target_position);
6429+
6430+
CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_parent);
6431+
Point2 local_target_pos = parent_ci ? parent_ci->get_global_transform().affine_inverse().xform(target_position) : target_position;
6432+
6433+
undo_redo->add_do_method(child, "set_position", local_target_pos);
6434+
6435+
EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
6436+
undo_redo->add_do_method(editor_selection, "add_node", child);
6437+
}
6438+
63806439
bool CanvasItemEditorViewport::_create_instance(Node *p_parent, const String &p_path, const Point2 &p_point) {
63816440
Ref<PackedScene> sdata = ResourceLoader::load(p_path);
63826441
if (sdata.is_null()) { // invalid scene
@@ -6490,6 +6549,11 @@ void CanvasItemEditorViewport::_perform_drop_data() {
64906549
if (audio.is_valid()) {
64916550
_create_audio_node(target_node, path, drop_pos);
64926551
}
6552+
6553+
Ref<Mesh> mesh = res;
6554+
if (mesh.is_valid()) {
6555+
_create_mesh_node(target_node, path, drop_pos);
6556+
}
64936557
}
64946558

64956559
undo_redo->commit_action();
@@ -6533,6 +6597,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
65336597
SCENE = 1 << 0,
65346598
TEXTURE = 1 << 1,
65356599
AUDIO = 1 << 2,
6600+
MESH = 1 << 3,
65366601
};
65376602
int instantiate_type = 0;
65386603

@@ -6558,6 +6623,8 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
65586623
instantiate_type |= TEXTURE;
65596624
} else if (ClassDB::is_parent_class(res_type, SNAME("AudioStream"))) {
65606625
instantiate_type |= AUDIO;
6626+
} else if (ClassDB::is_parent_class(res_type, "Mesh")) {
6627+
instantiate_type |= MESH;
65616628
}
65626629
}
65636630

@@ -6616,6 +6683,8 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
66166683
} else if (instantiate_type & TEXTURE) {
66176684
// TRANSLATORS: The placeholders are the types of nodes being instantiated.
66186685
title = vformat(TTR("Dropping a Texture file as a %s node..."), default_texture_node_type);
6686+
} else if (instantiate_type & MESH) {
6687+
title = TTR("Dropping a Mesh file...");
66196688
}
66206689
if (instantiate_type & TEXTURE) {
66216690
desc += "\n" + TTR("[b]Hold Alt + Shift:[/b] Add Texture as a different node type.");

editor/scene/canvas_item_editor_plugin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,7 @@ class CanvasItemEditorViewport : public Control {
689689
void _create_texture_node(Node *p_parent, Node *p_child, const String &p_path, const Point2 &p_point);
690690
void _create_audio_node(Node *p_parent, const String &p_path, const Point2 &p_point);
691691
bool _create_instance(Node *p_parent, const String &p_path, const Point2 &p_point);
692+
void _create_mesh_node(Node *p_parent, const String &p_path, const Point2 &p_point);
692693
void _perform_drop_data();
693694
void _show_texture_node_type_selector();
694695
void _update_theme();

0 commit comments

Comments
 (0)