diff options
author | SaracenOne <SaracenOne@gmail.com> | 2022-04-29 07:06:48 +0100 |
---|---|---|
committer | SaracenOne <SaracenOne@gmail.com> | 2022-05-11 22:03:07 +0100 |
commit | ce99de32b845676c5f589f89b525bd19c9178b50 (patch) | |
tree | 0755fb68747a83ac54d3a23d871131684cb7ce48 | |
parent | 2fd73bd32e0b0d153945bc28576b154af3342627 (diff) |
Fix ownership of nodes created by the MeshInstance3DEditorPlugin
and Skeleton3DEditorPlugin when used on foreign nodes.
Make gizmos visible upon creation rather than having to select
them first.
Make UV2 unwrapping and PhysicalBone creation properly subject
to UndoRedo.
-rw-r--r-- | editor/plugins/mesh_instance_3d_editor_plugin.cpp | 69 | ||||
-rw-r--r-- | editor/plugins/skeleton_3d_editor_plugin.cpp | 63 |
2 files changed, 95 insertions, 37 deletions
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index d33803213a..1c75591b34 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -77,12 +77,14 @@ void MeshInstance3DEditor::_menu_option(int p_option) { StaticBody3D *body = memnew(StaticBody3D); body->add_child(cshape, true); - Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); + Node *owner = get_tree()->get_edited_scene_root(); ur->create_action(TTR("Create Static Trimesh Body")); ur->add_do_method(node, "add_child", body, true); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", body); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); ur->add_do_reference(body); ur->add_undo_method(node, "remove_child", body); ur->commit_action(); @@ -112,11 +114,13 @@ void MeshInstance3DEditor::_menu_option(int p_option) { StaticBody3D *body = memnew(StaticBody3D); body->add_child(cshape, true); - Node *owner = instance == get_tree()->get_edited_scene_root() ? instance : instance->get_owner(); + Node *owner = get_tree()->get_edited_scene_root(); ur->add_do_method(instance, "add_child", body, true); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", body); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); ur->add_do_reference(body); ur->add_undo_method(instance, "remove_child", body); } @@ -141,7 +145,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { cshape->set_shape(shape); cshape->set_transform(node->get_transform()); - Node *owner = node->get_owner(); + Node *owner = get_tree()->get_edited_scene_root(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); @@ -150,6 +154,7 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node->get_parent(), "add_child", cshape, true); ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); ur->add_do_method(cshape, "set_owner", owner); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); ur->commit_action(); @@ -184,11 +189,12 @@ void MeshInstance3DEditor::_menu_option(int p_option) { cshape->set_shape(shape); cshape->set_transform(node->get_transform()); - Node *owner = node->get_owner(); + Node *owner = get_tree()->get_edited_scene_root(); ur->add_do_method(node->get_parent(), "add_child", cshape, true); ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); ur->add_do_method(cshape, "set_owner", owner); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); @@ -217,14 +223,17 @@ void MeshInstance3DEditor::_menu_option(int p_option) { for (int i = 0; i < shapes.size(); i++) { CollisionShape3D *cshape = memnew(CollisionShape3D); + cshape->set_name("CollisionShape3D"); + cshape->set_shape(shapes[i]); cshape->set_transform(node->get_transform()); - Node *owner = node->get_owner(); + Node *owner = get_tree()->get_edited_scene_root(); ur->add_do_method(node->get_parent(), "add_child", cshape); ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); ur->add_do_method(cshape, "set_owner", owner); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", cshape); ur->add_do_reference(cshape); ur->add_undo_method(node->get_parent(), "remove_child", cshape); } @@ -243,13 +252,14 @@ void MeshInstance3DEditor::_menu_option(int p_option) { NavigationRegion3D *nmi = memnew(NavigationRegion3D); nmi->set_navigation_mesh(nmesh); - Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); + Node *owner = get_tree()->get_edited_scene_root(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Create Navigation Mesh")); ur->add_do_method(node, "add_child", nmi, true); ur->add_do_method(nmi, "set_owner", owner); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", nmi); ur->add_do_reference(nmi); ur->add_undo_method(node, "remove_child", nmi); @@ -267,13 +277,52 @@ void MeshInstance3DEditor::_menu_option(int p_option) { return; } - Error err = mesh2->lightmap_unwrap(node->get_global_transform()); + String path = mesh2->get_path(); + int srpos = path.find("::"); + if (srpos != -1) { + String base = path.substr(0, srpos); + if (ResourceLoader::get_resource_type(base) == "PackedScene") { + if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) { + err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it does not belong to the edited scene. Make it unique first.")); + err_dialog->popup_centered(); + return; + } + } else { + if (FileAccess::exists(path + ".import")) { + err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it belongs to another resource which was imported from another file type. Make it unique first.")); + err_dialog->popup_centered(); + return; + } + } + } else { + if (FileAccess::exists(path + ".import")) { + err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it was imported from another file type. Make it unique first.")); + err_dialog->popup_centered(); + return; + } + } + + Ref<ArrayMesh> unwrapped_mesh = mesh2->duplicate(false); + + Error err = unwrapped_mesh->lightmap_unwrap(node->get_global_transform()); if (err != OK) { err_dialog->set_text(TTR("UV Unwrap failed, mesh may not be manifold?")); err_dialog->popup_centered(); return; } + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Unwrap UV2")); + + ur->add_do_method(node, "set_mesh", unwrapped_mesh); + ur->add_do_reference(node); + ur->add_do_reference(mesh2.ptr()); + + ur->add_undo_method(node, "set_mesh", mesh2); + ur->add_undo_reference(unwrapped_mesh.ptr()); + + ur->commit_action(); + } break; case MENU_OPTION_DEBUG_UV1: { Ref<Mesh> mesh2 = node->get_mesh(); @@ -418,10 +467,7 @@ void MeshInstance3DEditor::_create_outline_mesh() { MeshInstance3D *mi = memnew(MeshInstance3D); mi->set_mesh(mesho); - Node *owner = node->get_owner(); - if (get_tree()->get_edited_scene_root() == node) { - owner = node; - } + Node *owner = get_tree()->get_edited_scene_root(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); @@ -429,6 +475,7 @@ void MeshInstance3DEditor::_create_outline_mesh() { ur->add_do_method(node, "add_child", mi, true); ur->add_do_method(mi, "set_owner", owner); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", mi); ur->add_do_reference(mi); ur->add_undo_method(node, "remove_child", mi); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 1b703a097c..26a982a091 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -357,7 +357,7 @@ void Skeleton3DEditor::pose_to_rest(const bool p_all_bones) { void Skeleton3DEditor::create_physical_skeleton() { UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ERR_FAIL_COND(!get_tree()); - Node *owner = skeleton == get_tree()->get_edited_scene_root() ? skeleton : skeleton->get_owner(); + Node *owner = get_tree()->get_edited_scene_root(); const int bc = skeleton->get_bone_count(); @@ -368,37 +368,47 @@ void Skeleton3DEditor::create_physical_skeleton() { Vector<BoneInfo> bones_infos; bones_infos.resize(bc); - for (int bone_id = 0; bc > bone_id; ++bone_id) { - const int parent = skeleton->get_bone_parent(bone_id); + if (bc > 0) { + ur->create_action(TTR("Create physical bones"), UndoRedo::MERGE_ALL); + for (int bone_id = 0; bc > bone_id; ++bone_id) { + const int parent = skeleton->get_bone_parent(bone_id); - if (parent < 0) { - bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id); - - } else { - const int parent_parent = skeleton->get_bone_parent(parent); - - bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id); - - // Create physical bone on parent. - if (!bones_infos[parent].physical_bone) { - bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos); - - ur->create_action(TTR("Create physical bones"), UndoRedo::MERGE_ALL); - ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone); - ur->add_do_reference(bones_infos[parent].physical_bone); - ur->add_undo_method(skeleton, "remove_child", bones_infos[parent].physical_bone); - ur->commit_action(); + if (parent < 0) { + bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id); + } else { + const int parent_parent = skeleton->get_bone_parent(parent); + + bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id); + + // Create physical bone on parent. + if (!bones_infos[parent].physical_bone) { + PhysicalBone3D *physical_bone = create_physical_bone(parent, bone_id, bones_infos); + if (physical_bone && physical_bone->get_child(0)) { + CollisionShape3D *collision_shape = Object::cast_to<CollisionShape3D>(physical_bone->get_child(0)); + if (collision_shape) { + bones_infos.write[parent].physical_bone = physical_bone; + + ur->add_do_method(skeleton, "add_child", physical_bone); + ur->add_do_method(physical_bone, "set_owner", owner); + ur->add_do_method(collision_shape, "set_owner", owner); + ur->add_do_property(physical_bone, "bone_name", skeleton->get_bone_name(parent)); + + // Create joint between parent of parent. + if (parent_parent != -1) { + ur->add_do_method(physical_bone, "set_joint_type", PhysicalBone3D::JOINT_TYPE_PIN); + } - bones_infos[parent].physical_bone->set_bone_name(skeleton->get_bone_name(parent)); - bones_infos[parent].physical_bone->set_owner(owner); - bones_infos[parent].physical_bone->get_child(0)->set_owner(owner); // set shape owner + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", physical_bone); + ur->add_do_method(Node3DEditor::get_singleton(), "_request_gizmo", collision_shape); - // Create joint between parent of parent. - if (-1 != parent_parent) { - bones_infos[parent].physical_bone->set_joint_type(PhysicalBone3D::JOINT_TYPE_PIN); + ur->add_do_reference(physical_bone); + ur->add_undo_method(skeleton, "remove_child", physical_bone); + } + } } } } + ur->commit_action(); } } @@ -414,6 +424,7 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi CollisionShape3D *bone_shape = memnew(CollisionShape3D); bone_shape->set_shape(bone_shape_capsule); + bone_shape->set_name("CollisionShape3D"); Transform3D capsule_transform; capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0)); |