summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_node.cpp8
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/editor_resource_picker.cpp2
-rw-r--r--editor/import/resource_importer_scene.cpp36
-rw-r--r--editor/import/resource_importer_scene.h2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp31
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h2
7 files changed, 77 insertions, 6 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 804722299c..8eaddcb7e1 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -3932,7 +3932,7 @@ void EditorNode::edit_foreign_resource(Ref<Resource> p_resource) {
InspectorDock::get_singleton()->call_deferred("edit_resource", p_resource);
}
-bool EditorNode::is_resource_read_only(Ref<Resource> p_resource) {
+bool EditorNode::is_resource_read_only(Ref<Resource> p_resource, bool p_foreign_resources_are_writable) {
ERR_FAIL_COND_V(p_resource.is_null(), false);
String path = p_resource->get_path();
@@ -3944,7 +3944,11 @@ bool EditorNode::is_resource_read_only(Ref<Resource> p_resource) {
// If the base resource is a packed scene, we treat it as read-only if it is not the currently edited scene.
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) {
- return true;
+ // If we have not flagged foreign resources as writable or the base scene the resource is
+ // part was imported, it can be considered read-only.
+ if (!p_foreign_resources_are_writable || FileAccess::exists(base + ".import")) {
+ return true;
+ }
}
} else {
// If a corresponding .import file exists for the base file, we assume it to be imported and should therefore treated as read-only.
diff --git a/editor/editor_node.h b/editor/editor_node.h
index df3d2ae0f8..200d68908c 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -784,7 +784,7 @@ public:
void open_request(const String &p_path);
void edit_foreign_resource(Ref<Resource> p_resource);
- bool is_resource_read_only(Ref<Resource> p_resource);
+ bool is_resource_read_only(Ref<Resource> p_resource, bool p_foreign_resources_are_writable = false);
bool is_changing_scene() const;
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index 5346052f4d..84cb085551 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -186,7 +186,7 @@ void EditorResourcePicker::_update_menu_items() {
// Add options for changing existing value of the resource.
if (edited_resource.is_valid()) {
// Determine if the edited resource is part of another scene (foreign) which was imported
- bool is_edited_resource_foreign_import = EditorNode::get_singleton()->is_resource_read_only(edited_resource);
+ bool is_edited_resource_foreign_import = EditorNode::get_singleton()->is_resource_read_only(edited_resource, true);
// If the resource is determined to be foreign and imported, change the menu entry's description to 'inspect' rather than 'edit'
// since will only be able to view its properties in read-only mode.
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 41061c3fc3..b5798a5784 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -1891,6 +1891,39 @@ void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_
}
}
+Array ResourceImporterScene::_get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node) {
+ Array skin_pose_transform_array;
+
+ const Ref<Skin> skin = p_src_mesh_node->get_skin();
+ if (skin.is_valid()) {
+ NodePath skeleton_path = p_src_mesh_node->get_skeleton_path();
+ const Node *node = p_src_mesh_node->get_node_or_null(skeleton_path);
+ const Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
+ if (skeleton) {
+ int bind_count = skin->get_bind_count();
+
+ for (int i = 0; i < bind_count; i++) {
+ Transform3D bind_pose = skin->get_bind_pose(i);
+ String bind_name = skin->get_bind_name(i);
+
+ int bone_idx = bind_name.is_empty() ? skin->get_bind_bone(i) : skeleton->find_bone(bind_name);
+ ERR_FAIL_COND_V(bone_idx >= skeleton->get_bone_count(), Array());
+
+ Transform3D bp_global_rest;
+ if (bone_idx >= 0) {
+ bp_global_rest = skeleton->get_bone_global_pose(bone_idx);
+ } else {
+ bp_global_rest = skeleton->get_bone_global_pose(i);
+ }
+
+ skin_pose_transform_array.push_back(bp_global_rest * bind_pose);
+ }
+ }
+ }
+
+ return skin_pose_transform_array;
+}
+
void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches) {
ImporterMeshInstance3D *src_mesh_node = Object::cast_to<ImporterMeshInstance3D>(p_node);
if (src_mesh_node) {
@@ -2007,7 +2040,8 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
if (generate_lods) {
- src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle);
+ Array skin_pose_transform_array = _get_skinned_pose_transforms(src_mesh_node);
+ src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle, skin_pose_transform_array);
}
if (create_shadow_meshes) {
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index da37893cc5..77bc06533c 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -34,6 +34,7 @@
#include "core/error/error_macros.h"
#include "core/io/resource_importer.h"
#include "core/variant/dictionary.h"
+#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/animation.h"
#include "scene/resources/mesh.h"
@@ -208,6 +209,7 @@ class ResourceImporterScene : public ResourceImporter {
SHAPE_TYPE_CAPSULE,
};
+ Array _get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node);
void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
void _generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches);
void _add_shapes(Node *p_node, const Vector<Ref<Shape3D>> &p_shapes);
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index ae21aad337..d0a1ddafa1 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -984,11 +984,17 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
}
void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
- if (frames == p_frames) {
+ bool new_read_only_state = false;
+ if (p_frames) {
+ new_read_only_state = EditorNode::get_singleton()->is_resource_read_only(p_frames);
+ }
+
+ if (frames == p_frames && new_read_only_state == read_only) {
return;
}
frames = p_frames;
+ read_only = new_read_only_state;
if (p_frames) {
if (!p_frames->has_animation(edited_anim)) {
@@ -1009,6 +1015,20 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
} else {
hide();
}
+
+ new_anim->set_disabled(read_only);
+ remove_anim->set_disabled(read_only);
+ anim_speed->set_editable(!read_only);
+ anim_loop->set_disabled(read_only);
+ load->set_disabled(read_only);
+ load_sheet->set_disabled(read_only);
+ copy->set_disabled(read_only);
+ paste->set_disabled(read_only);
+ empty->set_disabled(read_only);
+ empty2->set_disabled(read_only);
+ move_up->set_disabled(read_only);
+ move_down->set_disabled(read_only);
+ _delete->set_disabled(read_only);
}
void SpriteFramesEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
@@ -1016,6 +1036,10 @@ void SpriteFramesEditor::set_undo_redo(Ref<EditorUndoRedoManager> p_undo_redo) {
}
Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
+ if (read_only) {
+ return false;
+ }
+
if (!frames->has_animation(edited_anim)) {
return false;
}
@@ -1038,6 +1062,10 @@ Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
}
bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
+ if (read_only) {
+ return false;
+ }
+
Dictionary d = p_data;
if (!d.has("type")) {
@@ -1169,6 +1197,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
remove_anim->set_flat(true);
remove_anim->set_tooltip_text(TTR("Remove Animation"));
hbc_animlist->add_child(remove_anim);
+ remove_anim->set_disabled(true);
remove_anim->connect("pressed", callable_mp(this, &SpriteFramesEditor::_animation_remove));
anim_search_box = memnew(LineEdit);
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index f2530b732f..092f556c63 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -57,6 +57,8 @@ class SpriteFramesEditor : public HSplitContainer {
};
int dominant_param = PARAM_FRAME_COUNT;
+ bool read_only = false;
+
Button *load = nullptr;
Button *load_sheet = nullptr;
Button *_delete = nullptr;