diff options
-rw-r--r-- | core/io/resource_format_binary.cpp | 5 | ||||
-rw-r--r-- | core/io/resource_format_binary.h | 2 | ||||
-rw-r--r-- | core/io/resource_import.cpp | 2 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 82 | ||||
-rw-r--r-- | core/io/resource_loader.h | 6 | ||||
-rw-r--r-- | doc/base/classes.xml | 2 | ||||
-rw-r--r-- | editor/editor_file_system.cpp | 5 | ||||
-rw-r--r-- | editor/editor_node.cpp | 68 | ||||
-rw-r--r-- | editor/editor_node.h | 1 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.cpp | 3 | ||||
-rw-r--r-- | editor/import_dock.cpp | 12 | ||||
-rw-r--r-- | editor/plugins/script_text_editor.cpp | 22 | ||||
-rw-r--r-- | modules/gdnative/godot/string.cpp | 2 | ||||
-rw-r--r-- | modules/gdnative/godot/string.h | 2 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 6 | ||||
-rw-r--r-- | scene/resources/scene_format_text.cpp | 5 | ||||
-rw-r--r-- | scene/resources/scene_format_text.h | 2 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.cpp | 3 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.h | 1 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.cpp | 60 | ||||
-rw-r--r-- | servers/physics_server.cpp | 2 |
21 files changed, 203 insertions, 90 deletions
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 965d11e414..f44492248e 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1005,7 +1005,7 @@ ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() { memdelete(f); } -Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, Error *r_error) { +Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; @@ -1019,7 +1019,8 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(cons } Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary); - ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path); + String path = p_original_path != "" ? p_original_path : p_path; + ria->local_path = ProjectSettings::get_singleton()->localize_path(path); ria->res_path = ria->local_path; //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); ria->open(f); diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 1bd0d333c6..ab77c2c9d3 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -101,7 +101,7 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp index 69ff791a3a..be486a86a3 100644 --- a/core/io/resource_import.cpp +++ b/core/io/resource_import.cpp @@ -119,7 +119,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_ return RES(); } - RES res = ResourceLoader::load(pat.path, pat.type, false, r_error); + RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error); #ifdef TOOLS_ENABLED if (res.is_valid()) { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 30ae9f5681..4f266df43e 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -109,10 +109,10 @@ public: ResourceInteractiveLoaderDefault() {} }; -Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) { +Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { //either this - Ref<Resource> res = load(p_path, p_path, r_error); + Ref<Resource> res = load(p_path, p_original_path, r_error); if (res.is_null()) return Ref<ResourceInteractiveLoader>(); @@ -126,7 +126,7 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa String path = p_path; //or this must be implemented - Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, r_error); + Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, p_original_path, r_error); if (!ril.is_valid()) return RES(); ril->set_local_path(p_original_path); @@ -157,6 +157,34 @@ void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> * /////////////////////////////////// +RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { + + bool found = false; + + // Try all loaders and pick the first match for the type hint + for (int i = 0; i < loader_count; i++) { + + if (!loader[i]->recognize_path(p_path, p_type_hint)) { + continue; + } + found = true; + RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error); + if (res.is_null()) { + continue; + } + + return res; + } + + if (found) { + ERR_EXPLAIN("Failed loading resource: " + p_path); + } else { + ERR_EXPLAIN("No loader found for resource: " + p_path); + } + ERR_FAIL_V(RES()); + return RES(); +} + RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { if (r_error) @@ -183,45 +211,29 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p if (OS::get_singleton()->is_stdout_verbose()) print_line("load resource: " + path); - bool found = false; - // Try all loaders and pick the first match for the type hint - for (int i = 0; i < loader_count; i++) { + RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error); - if (!loader[i]->recognize_path(path, p_type_hint)) { - continue; - } - found = true; - RES res = loader[i]->load(path, path, r_error); - if (res.is_null()) { - continue; - } - if (!p_no_cache) - res->set_path(local_path); + if (res.is_null()) { + return RES(); + } + if (!p_no_cache) + res->set_path(local_path); - if (xl_remapped) - res->set_as_translation_remapped(true); + if (xl_remapped) + res->set_as_translation_remapped(true); #ifdef TOOLS_ENABLED - res->set_edited(false); - if (timestamp_on_load) { - uint64_t mt = FileAccess::get_modified_time(path); - //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt); - res->set_last_modified_time(mt); - } -#endif - - return res; + res->set_edited(false); + if (timestamp_on_load) { + uint64_t mt = FileAccess::get_modified_time(path); + //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt); + res->set_last_modified_time(mt); } +#endif - if (found) { - ERR_EXPLAIN("Failed loading resource: " + path); - } else { - ERR_EXPLAIN("No loader found for resource: " + path); - } - ERR_FAIL_V(RES()); - return RES(); + return res; } Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { @@ -262,7 +274,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ if (!loader[i]->recognize_path(path, p_type_hint)) continue; found = true; - Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, r_error); + Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error); if (ril.is_null()) continue; if (!p_no_cache) diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 91f0c939bf..a71a568569 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -57,7 +57,7 @@ public: class ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const = 0; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; @@ -96,6 +96,10 @@ class ResourceLoader { static SelfList<Resource>::List remapped_list; + friend class ResourceFormatImporter; + //internal load function + static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error); + public: static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 9b424f2ec4..e0b1ea3870 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -32449,7 +32449,7 @@ <description> </description> </method> - <method name="get_principal_inetria_axes" qualifiers="const"> + <method name="get_principal_inertia_axes" qualifiers="const"> <return type="Basis"> </return> <description> diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index c175886d14..6e12a8fd02 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1383,7 +1383,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { } } - if (load_default && ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name())) { + if (load_default && ProjectSettings::get_singleton()->has("importer_defaults/" + importer->get_importer_name())) { //use defaults if exist Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); List<Variant> v; @@ -1509,6 +1509,8 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { if (!is_scanning()) { emit_signal("filesystem_changed"); } + + emit_signal("resources_reimported", p_files); } void EditorFileSystem::_bind_methods() { @@ -1524,6 +1526,7 @@ void EditorFileSystem::_bind_methods() { ADD_SIGNAL(MethodInfo("filesystem_changed")); ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist"))); + ADD_SIGNAL(MethodInfo("resources_reimported", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources"))); } void EditorFileSystem::_update_extensions() { diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 15de8206aa..8575cd164f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -382,20 +382,23 @@ void EditorNode::_fs_changed() { continue; if (E->get()->get_import_path() != String()) { - //imported resource +//this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback +//imported resource +#if 0 uint64_t mt = FileAccess::get_modified_time(E->get()->get_import_path()); if (mt != E->get()->get_import_last_modified_time()) { print_line("success"); changed.push_back(E->get()); } +#endif + continue; + } - } else { - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); + uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - if (mt != E->get()->get_last_modified_time()) { - changed.push_back(E->get()); - } + if (mt != E->get()->get_last_modified_time()) { + changed.push_back(E->get()); } } @@ -410,6 +413,33 @@ void EditorNode::_fs_changed() { _mark_unsaved_scenes(); } +void EditorNode::_resources_reimported(const Vector<String> &p_resources) { + print_line("reimporting"); + List<String> scenes; //will load later + + for (int i = 0; i < p_resources.size(); i++) { + String file_type = ResourceLoader::get_resource_type(p_resources[i]); + if (file_type == "PackedScene") { + scenes.push_back(p_resources[i]); + //reload later if needed, first go with normal resources + continue; + } + + if (!ResourceCache::has(p_resources[i])) { + continue; //not loaded, no need to reload + } + //reload normally + Resource *resource = ResourceCache::get(p_resources[i]); + if (resource) { + resource->reload_from_file(); + } + } + + for (List<String>::Element *E = scenes.front(); E; E = E->next()) { + reload_scene(E->get()); + } +} + void EditorNode::_sources_changed(bool p_exist) { if (waiting_for_first_scan) { @@ -2857,6 +2887,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b dependency_errors.clear(); + print_line("actually loading it"); Error err; Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err); if (!sdata.is_valid()) { @@ -4179,30 +4210,25 @@ void EditorNode::_file_access_close_error_notify(const String &p_str) { void EditorNode::reload_scene(const String &p_path) { - //first of all, reload textures as they might have changed on disk + //first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk + print_line("reloading: " + p_path); List<Ref<Resource> > cached; ResourceCache::get_cached_resources(&cached); List<Ref<Resource> > to_clear; //clear internal resources from previous scene from being used for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { - if (E->get()->get_path().begins_with(p_path + "::")) //subresources of existing scene + if (E->get()->get_path().find("::") != -1) { + print_line(E->get()->get_path()); + } + if (E->get()->get_path().begins_with(p_path + "::")) { //subresources of existing scene to_clear.push_back(E->get()); - - if (!cast_to<Texture>(E->get().ptr())) - continue; - if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path()) - continue; - if (!FileAccess::exists(E->get()->get_path())) - continue; - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); - if (mt != E->get()->get_last_modified_time()) { - E->get()->reload_from_file(); } } //so reload reloads everything, clear subresources of previous scene while (to_clear.front()) { + print_line("bye bye: " + to_clear.front()->get()->get_path()); to_clear.front()->get()->set_path(""); to_clear.pop_front(); } @@ -4234,7 +4260,8 @@ void EditorNode::reload_scene(const String &p_path) { //remove scene _remove_scene(scene_idx); //reload scene - load_scene(p_path); + + load_scene(p_path, true, false, true, true); //adjust index so tab is back a the previous position editor_data.move_edited_scene_to_index(scene_idx); get_undo_redo()->clear_history(); @@ -4426,6 +4453,8 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout); ClassDB::bind_method(D_METHOD("_check_gui_base_size"), &EditorNode::_check_gui_base_size); + ClassDB::bind_method(D_METHOD("_resources_reimported"), &EditorNode::_resources_reimported); + ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("pause_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); @@ -5454,6 +5483,7 @@ EditorNode::EditorNode() { EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed"); EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed"); + EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported"); { List<StringName> tl; diff --git a/editor/editor_node.h b/editor/editor_node.h index 445ef4922e..c3ceee350a 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -422,6 +422,7 @@ private: void _prepare_history(); void _fs_changed(); + void _resources_reimported(const Vector<String> &p_resources); void _sources_changed(bool p_exist); void _node_renamed(); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 7fa76713f3..594728d2e0 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1167,7 +1167,8 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p memdelete(scene); - EditorNode::get_singleton()->reload_scene(p_source_file); + //this is not the time to reimport, wait until import process is done, import file is saved, etc. + //EditorNode::get_singleton()->reload_scene(p_source_file); return OK; } diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp index a60f5d7294..112e3abcb5 100644 --- a/editor/import_dock.cpp +++ b/editor/import_dock.cpp @@ -265,16 +265,14 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { void ImportDock::_preset_selected(int p_idx) { - switch (p_idx) { - case ITEM_SET_AS_DEFAULT: { - List<ResourceImporter::ImportOption> options; - - params->importer->get_import_options(&options, p_idx); + int item_id = preset->get_popup()->get_item_id(p_idx); + switch (item_id) { + case ITEM_SET_AS_DEFAULT: { Dictionary d; - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - d[E->get().option.name] = E->get().default_value; + for (const List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) { + d[E->get().name] = params->values[E->get().name]; } ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), d); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index a8f1b00776..33890d890d 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -120,17 +120,29 @@ void ScriptTextEditor::_load_theme_settings() { //colorize core types Color basetype_color = EDITOR_DEF("text_editor/highlighting/base_type_color", Color(0.3, 0.3, 0.0)); + text_edit->add_keyword_color("String", basetype_color); text_edit->add_keyword_color("Vector2", basetype_color); + text_edit->add_keyword_color("Rect2", basetype_color); + text_edit->add_keyword_color("Transform2D", basetype_color); text_edit->add_keyword_color("Vector3", basetype_color); + text_edit->add_keyword_color("Rect3", basetype_color); + text_edit->add_keyword_color("Basis", basetype_color); text_edit->add_keyword_color("Plane", basetype_color); - text_edit->add_keyword_color("Quat", basetype_color); - text_edit->add_keyword_color("AABB", basetype_color); - text_edit->add_keyword_color("Matrix3", basetype_color); text_edit->add_keyword_color("Transform", basetype_color); + text_edit->add_keyword_color("Quat", basetype_color); text_edit->add_keyword_color("Color", basetype_color); - text_edit->add_keyword_color("Image", basetype_color); - text_edit->add_keyword_color("Rect2", basetype_color); + text_edit->add_keyword_color("Object", basetype_color); text_edit->add_keyword_color("NodePath", basetype_color); + text_edit->add_keyword_color("RID", basetype_color); + text_edit->add_keyword_color("Dictionary", basetype_color); + text_edit->add_keyword_color("Array", basetype_color); + text_edit->add_keyword_color("PoolByteArray", basetype_color); + text_edit->add_keyword_color("PoolIntArray", basetype_color); + text_edit->add_keyword_color("PoolRealArray", basetype_color); + text_edit->add_keyword_color("PoolStringArray", basetype_color); + text_edit->add_keyword_color("PoolVector2Array", basetype_color); + text_edit->add_keyword_color("PoolVector3Array", basetype_color); + text_edit->add_keyword_color("PoolColorArray", basetype_color); //colorize engine types Color type_color = EDITOR_DEF("text_editor/highlighting/engine_type_color", Color(0.0, 0.2, 0.4)); diff --git a/modules/gdnative/godot/string.cpp b/modules/gdnative/godot/string.cpp index 3790b6ea95..1282cf95e5 100644 --- a/modules/gdnative/godot/string.cpp +++ b/modules/gdnative/godot/string.cpp @@ -232,7 +232,7 @@ godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string return self->findn(*what, p_from); } -godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what) { +godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what) { const String *self = (const String *)p_self; String *what = (String *)&p_what; diff --git a/modules/gdnative/godot/string.h b/modules/gdnative/godot/string.h index d691744453..128448e64e 100644 --- a/modules/gdnative/godot/string.h +++ b/modules/gdnative/godot/string.h @@ -82,7 +82,7 @@ godot_int GDAPI godot_string_findmk_from(const godot_string *p_self, const godot godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, const godot_array *p_keys, godot_int p_from, godot_int *r_key); godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what); godot_int GDAPI godot_string_findn_from(const godot_string *p_self, godot_string p_what, godot_int p_from); -godot_int GDAPI find_last(const godot_string *p_self, godot_string p_what); +godot_int GDAPI godot_string_find_last(const godot_string *p_self, godot_string p_what); godot_string GDAPI godot_string_format(const godot_string *p_self, const godot_variant *p_values); godot_string GDAPI godot_string_format_with_custom_placeholder(const godot_string *p_self, const godot_variant *p_values, const char *p_placeholder); godot_string GDAPI godot_string_hex_encode_buffer(const uint8_t *p_buffer, godot_int p_len); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 7a9daea73e..7b93393851 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2113,15 +2113,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { //keep indentation int space_count = 0; - for (int i = 0; i < text[cursor.line].length(); i++) { - if (text[cursor.line][i] == '\t' && cursor.column > 0) { + for (int i = 0; i < cursor.column; i++) { + if (text[cursor.line][i] == '\t') { if (indent_using_spaces) { ins += space_indent; } else { ins += "\t"; } space_count = 0; - } else if (text[cursor.line][i] == ' ' && cursor.column > 0) { + } else if (text[cursor.line][i] == ' ') { space_count++; if (space_count == indent_size) { diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index fea5c11dec..14e2ef83f8 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -891,7 +891,7 @@ String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) { ///////////////////// -Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, Error *r_error) { +Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { if (r_error) *r_error = ERR_CANT_OPEN; @@ -905,7 +905,8 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const } Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); - ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path); + String path = p_original_path != "" ? p_original_path : p_path; + ria->local_path = ProjectSettings::get_singleton()->localize_path(path); ria->res_path = ria->local_path; //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); ria->open(f); diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h index 193bcf7112..a72a62037c 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/scene_format_text.h @@ -108,7 +108,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index 006c5fd7b5..e9e7122af3 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -130,9 +130,12 @@ void Physics2DServerSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & if (cbk->valid_dir != Vector2()) { if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) { + cbk->invalid_by_dir++; return; } if (cbk->valid_dir.dot((p_point_A - p_point_B).normalized()) < 0.7071) { + cbk->invalid_by_dir++; + ; /* print_line("A: "+p_point_A); print_line("B: "+p_point_B); print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B)))); diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 7d3c589fa9..dd310d7a93 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -74,6 +74,7 @@ public: real_t valid_depth; int max; int amount; + int invalid_by_dir; Vector2 *ptr; }; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 9b2e586993..779f0d54ac 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -30,8 +30,8 @@ #include "space_2d_sw.h" #include "collision_solver_2d_sw.h" +#include "pair.h" #include "physics_2d_server_sw.h" - _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) { if ((p_object->get_collision_layer() & p_collision_layer) == 0) @@ -517,6 +517,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb)); body_aabb = body_aabb.grow(p_margin); + static const int max_excluded_shape_pairs = 32; + Pair<Shape2DSW *, Shape2DSW *> excluded_shape_pairs[max_excluded_shape_pairs]; + int excluded_shape_pair_count = 0; + Transform2D body_transform = p_from; { @@ -532,6 +536,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.max = max_results; cbk.amount = 0; cbk.ptr = sr; + cbk.invalid_by_dir = 0; + excluded_shape_pair_count = 0; //last step is the one valid Physics2DServerSW::CollCbkData *cbkptr = &cbk; CollisionSolver2DSW::CallbackResult cbkres = Physics2DServerSW::_shape_col_cbk; @@ -555,14 +561,25 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.valid_dir = body_shape_xform.get_axis(1).normalized(); cbk.valid_depth = p_margin; //only valid depth is the collision margin + cbk.invalid_by_dir = 0; + } else { cbk.valid_dir = Vector2(); cbk.valid_depth = 0; + cbk.invalid_by_dir = 0; } - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) { + Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) { collided = cbk.amount > 0; } + + if (!collided && cbk.invalid_by_dir > 0) { + //this shape must be excluded + if (excluded_shape_pair_count < max_excluded_shape_pairs) { + excluded_shape_pairs[excluded_shape_pair_count++] = Pair<Shape2DSW *, Shape2DSW *>(body_shape, against_shape); + } + } } } @@ -622,15 +639,31 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co const CollisionObject2DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; + Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + + bool excluded = false; + + for (int k = 0; k < excluded_shape_pair_count; k++) { + + if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) { + excluded = true; + break; + } + } + + if (excluded) { + + continue; + } Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? - if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { + if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { continue; } //test initial overlap - if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { + if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) { if (col_obj->is_shape_set_as_one_way_collision(j)) { continue; @@ -650,7 +683,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co real_t ofs = (low + hi) * 0.5; Vector2 sep = mnormal; //important optimization for this to work fast enough - bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, &sep, 0); + bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_xform, Vector2(), NULL, NULL, &sep, 0); if (collided) { @@ -669,7 +702,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co cbk.amount = 0; cbk.ptr = cd; cbk.valid_dir = body_shape_xform.get_axis(1).normalized(); - ; + cbk.valid_depth = 10e20; Vector2 sep = mnormal; //important optimization for this to work fast enough @@ -738,6 +771,19 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co const CollisionObject2DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; + Shape2DSW *against_shape = col_obj->get_shape(shape_idx); + + bool excluded = false; + for (int k = 0; k < excluded_shape_pair_count; k++) { + + if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) { + excluded = true; + break; + } + } + if (excluded) + continue; + if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) { rcd.valid_dir = body_shape_xform.get_axis(1).normalized(); @@ -749,7 +795,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co rcd.object = col_obj; rcd.shape = shape_idx; - bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin); + bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin); if (!sc) continue; } diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 5097e0a5d2..d4e37be882 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -75,7 +75,7 @@ void PhysicsDirectBodyState::_bind_methods() { ClassDB::bind_method(D_METHOD("get_total_angular_damp"), &PhysicsDirectBodyState::get_total_angular_damp); ClassDB::bind_method(D_METHOD("get_center_of_mass"), &PhysicsDirectBodyState::get_center_of_mass); - ClassDB::bind_method(D_METHOD("get_principal_inetria_axes"), &PhysicsDirectBodyState::get_principal_inertia_axes); + ClassDB::bind_method(D_METHOD("get_principal_inertia_axes"), &PhysicsDirectBodyState::get_principal_inertia_axes); ClassDB::bind_method(D_METHOD("get_inverse_mass"), &PhysicsDirectBodyState::get_inverse_mass); ClassDB::bind_method(D_METHOD("get_inverse_inertia"), &PhysicsDirectBodyState::get_inverse_inertia); |