diff options
35 files changed, 451 insertions, 204 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a8e4650710..04e42d14b6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,7 +59,8 @@ by drag and dropping the file in the GitHub edition field. If you want to add new engine functionalities, please make sure that: -* This functionality is desired. +* This functionality is desired, which means that it solves a common use case + that several users will need in their real-life projects. * You talked to other developers on how to implement it best (on either communication channel, and maybe in a GitHub issue first before making your PR). @@ -70,10 +71,18 @@ Similar rules can be applied when contributing bug fixes - it's always best to discuss the implementation in the bug report first if you are not 100% about what would be the best fix. +[This blog post](https://godotengine.org/article/will-your-contribution-be-merged-heres-how-tell) +outlines the process used by core developers when assessing PRs. We strongly +recommend that you have a look at it to know what's important to take into +account for a PR to be considered for merging. + In addition to the following tips, also take a look at the [Engine development guide](https://docs.godotengine.org/en/latest/development/cpp/) for an introduction to developing on Godot. +The [Contributing docs](http://docs.godotengine.org/en/latest/community/contributing/index.html) +also have important information on the PR workflow and the code style we use. + #### Be nice to the git history Try to make simple PRs that handle one specific topic. Just like for reporting @@ -93,6 +102,9 @@ Internet). This git style guide has some good practices to have in mind: [Git Style Guide](https://github.com/agis-/git-style-guide) +See our [PR workflow](http://docs.godotengine.org/en/latest/community/contributing/pr_workflow.html) +documentation for tips on using Git, amending commits and rebasing branches. + #### Format your commit logs with readability in mind The way you format your commit logs is quite important to ensure that the @@ -138,6 +150,10 @@ Weblate](https://hosted.weblate.org/projects/godot-engine/godot), an open source and web-based translation platform. Please refer to the [translation readme](editor/translations/README.md) for more information. +You can also help translate [Godot's +documentation](https://hosted.weblate.org/projects/godot-engine/godot-docs/) +on Weblate. + ## Communicating with developers The Godot Engine community has [many communication diff --git a/doc/classes/DynamicFontData.xml b/doc/classes/DynamicFontData.xml index 7b34d02316..5fcccf7db9 100644 --- a/doc/classes/DynamicFontData.xml +++ b/doc/classes/DynamicFontData.xml @@ -13,6 +13,9 @@ <methods> </methods> <members> + <member name="antialiased" type="bool" setter="set_antialiased" getter="is_antialiased"> + Controls whether the font should be rendered with anti-aliasing. + </member> <member name="font_path" type="String" setter="set_font_path" getter="get_font_path"> The path to the vector font file. </member> diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index d4079c4b4f..45802ad3b5 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1585,24 +1585,24 @@ void main() { float alpha = 1.0; -#if defined(DO_SIDE_CHECK) - float side = gl_FrontFacing ? 1.0 : -1.0; -#else - float side = 1.0; -#endif - #if defined(ALPHA_SCISSOR_USED) float alpha_scissor = 0.5; #endif #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) - vec3 binormal = normalize(binormal_interp) * side; - vec3 tangent = normalize(tangent_interp) * side; + vec3 binormal = normalize(binormal_interp);// * side; + vec3 tangent = normalize(tangent_interp);// * side; #else vec3 binormal = vec3(0.0); vec3 tangent = vec3(0.0); #endif - vec3 normal = normalize(normal_interp) * side; + vec3 normal = normalize(normal_interp); + +#if defined(DO_SIDE_CHECK) + if (!gl_FrontFacing) { + normal = -normal; + } +#endif #if defined(ENABLE_UV_INTERP) vec2 uv = uv_interp; @@ -1658,7 +1658,7 @@ FRAGMENT_SHADER_CODE normalmap.xy = normalmap.xy * 2.0 - 1.0; normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. - normal = normalize(mix(normal_interp, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth)) * side; + normal = normalize(mix(normal, tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z, normaldepth)); #endif diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index a99c9656ba..94eb1a3399 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -466,6 +466,7 @@ bool EditorFileSystem::_update_scan_actions() { bool fs_changed = false; Vector<String> reimports; + Vector<String> reloads; for (List<ItemAction>::Element *E = scan_actions.front(); E; E = E->next()) { @@ -545,12 +546,25 @@ bool EditorFileSystem::_update_scan_actions() { fs_changed = true; } break; + case ItemAction::ACTION_FILE_RELOAD: { + + int idx = ia.dir->find_file_index(ia.file); + ERR_CONTINUE(idx == -1); + String full_path = ia.dir->get_file_path(idx); + + reloads.push_back(full_path); + + } break; } } if (reimports.size()) { reimport_files(reimports); } + + if (reloads.size()) { + emit_signal("resources_reload", reloads); + } scan_actions.clear(); return fs_changed; @@ -905,11 +919,11 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const continue; } + String path = cd.plus_file(p_dir->files[i]->file); + if (import_extensions.has(p_dir->files[i]->file.get_extension().to_lower())) { //check here if file must be imported or not - String path = cd.plus_file(p_dir->files[i]->file); - uint64_t mt = FileAccess::get_modified_time(path); bool reimport = false; @@ -936,6 +950,20 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const ia.file = p_dir->files[i]->file; scan_actions.push_back(ia); } + } else if (ResourceCache::has(path)) { //test for potential reload + + uint64_t mt = FileAccess::get_modified_time(path); + + if (mt != p_dir->files[i]->modified_time) { + + p_dir->files[i]->modified_time = mt; //save new time, but test for reload + + ItemAction ia; + ia.action = ItemAction::ACTION_FILE_RELOAD; + ia.dir = p_dir; + ia.file = p_dir->files[i]->file; + scan_actions.push_back(ia); + } } } @@ -1726,6 +1754,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"))); + ADD_SIGNAL(MethodInfo("resources_reload", PropertyInfo(Variant::POOL_STRING_ARRAY, "resources"))); } void EditorFileSystem::_update_extensions() { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index f6eef2a152..51b3fd38f0 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -116,7 +116,8 @@ class EditorFileSystem : public Node { ACTION_DIR_REMOVE, ACTION_FILE_ADD, ACTION_FILE_REMOVE, - ACTION_FILE_TEST_REIMPORT + ACTION_FILE_TEST_REIMPORT, + ACTION_FILE_RELOAD }; Action action; diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 8b1818b595..a54ad7894a 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -93,12 +93,14 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Custom font */ + bool font_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/main_font_antialiased"); DynamicFontData::Hinting font_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/main_font_hinting"); String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font"); Ref<DynamicFontData> CustomFont; if (custom_font_path.length() > 0 && dir->file_exists(custom_font_path)) { CustomFont.instance(); + CustomFont->set_antialiased(font_antialiased); CustomFont->set_hinting(font_hinting); CustomFont->set_font_path(custom_font_path); CustomFont->set_force_autohinter(true); //just looks better..i think? @@ -112,6 +114,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { Ref<DynamicFontData> CustomFontBold; if (custom_font_path_bold.length() > 0 && dir->file_exists(custom_font_path_bold)) { CustomFontBold.instance(); + CustomFontBold->set_antialiased(font_antialiased); CustomFontBold->set_hinting(font_hinting); CustomFontBold->set_font_path(custom_font_path_bold); CustomFontBold->set_force_autohinter(true); //just looks better..i think? @@ -122,10 +125,12 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Custom source code font */ String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); + bool font_source_antialiased = (bool)EditorSettings::get_singleton()->get("interface/editor/code_font_antialiased"); DynamicFontData::Hinting font_source_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/code_font_hinting"); Ref<DynamicFontData> CustomFontSource; if (custom_font_path_source.length() > 0 && dir->file_exists(custom_font_path_source)) { CustomFontSource.instance(); + CustomFontSource->set_antialiased(font_source_antialiased); CustomFontSource->set_hinting(font_source_hinting); CustomFontSource->set_font_path(custom_font_path_source); } else { @@ -138,48 +143,56 @@ void editor_register_fonts(Ref<Theme> p_theme) { Ref<DynamicFontData> DefaultFont; DefaultFont.instance(); + DefaultFont->set_antialiased(font_antialiased); DefaultFont->set_hinting(font_hinting); DefaultFont->set_font_ptr(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size); DefaultFont->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> DefaultFontBold; DefaultFontBold.instance(); - DefaultFont->set_hinting(font_hinting); + DefaultFontBold->set_antialiased(font_antialiased); + DefaultFontBold->set_hinting(font_hinting); DefaultFontBold->set_font_ptr(_font_NotoSansUI_Bold, _font_NotoSansUI_Bold_size); DefaultFontBold->set_force_autohinter(true); // just looks better..i think? Ref<DynamicFontData> FontFallback; FontFallback.instance(); + FontFallback->set_antialiased(font_antialiased); FontFallback->set_hinting(font_hinting); FontFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size); FontFallback->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontJapanese; FontJapanese.instance(); + FontJapanese->set_antialiased(font_antialiased); FontJapanese->set_hinting(font_hinting); FontJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size); FontJapanese->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontArabic; FontArabic.instance(); + FontArabic->set_antialiased(font_antialiased); FontArabic->set_hinting(font_hinting); FontArabic->set_font_ptr(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size); FontArabic->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontHebrew; FontHebrew.instance(); + FontHebrew->set_antialiased(font_antialiased); FontHebrew->set_hinting(font_hinting); FontHebrew->set_font_ptr(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size); FontHebrew->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontThai; FontThai.instance(); + FontThai->set_antialiased(font_antialiased); FontThai->set_hinting(font_hinting); FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); FontThai->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontHindi; FontHindi.instance(); + FontHindi->set_antialiased(font_antialiased); FontHindi->set_hinting(font_hinting); FontHindi->set_font_ptr(_font_NotoSansDevanagariUI_Regular, _font_NotoSansDevanagariUI_Regular_size); FontHindi->set_force_autohinter(true); //just looks better..i think? @@ -188,6 +201,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { Ref<DynamicFontData> dfmono; dfmono.instance(); + dfmono->set_antialiased(font_source_antialiased); dfmono->set_hinting(font_source_hinting); dfmono->set_font_ptr(_font_Hack_Regular, _font_Hack_Regular_size); //dfd->set_force_autohinter(true); //just looks better..i think? diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index d3ae5d6601..5d29acff75 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -410,51 +410,50 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam push_item(script.operator->()); } -void EditorNode::_fs_changed() { +void EditorNode::_resources_changed(const PoolVector<String> &p_resources) { - for (Set<FileDialog *>::Element *E = file_dialogs.front(); E; E = E->next()) { + List<Ref<Resource> > changed; - E->get()->invalidate(); - } + int rc = p_resources.size(); + for (int i = 0; i < rc; i++) { - for (Set<EditorFileDialog *>::Element *E = editor_file_dialogs.front(); E; E = E->next()) { + Ref<Resource> res(ResourceCache::get(p_resources.get(i))); + if (res.is_null()) { + continue; + } - E->get()->invalidate(); - } + if (!res->editor_can_reload_from_file()) + continue; + if (!res->get_path().is_resource_file() && !res->get_path().is_abs_path()) + continue; + if (!FileAccess::exists(res->get_path())) + continue; - { - //reload changed resources - List<Ref<Resource> > changed; + if (res->get_import_path() != String()) { + //this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback + continue; + } - List<Ref<Resource> > cached; - ResourceCache::get_cached_resources(&cached); - // FIXME: This should be done in a thread. - for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { + changed.push_back(res); + } - if (!E->get()->editor_can_reload_from_file()) - 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; + if (changed.size()) { + for (List<Ref<Resource> >::Element *E = changed.front(); E; E = E->next()) { + E->get()->reload_from_file(); + } + } +} - if (E->get()->get_import_path() != String()) { - //this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback - continue; - } +void EditorNode::_fs_changed() { - uint64_t mt = FileAccess::get_modified_time(E->get()->get_path()); + for (Set<FileDialog *>::Element *E = file_dialogs.front(); E; E = E->next()) { - if (mt != E->get()->get_last_modified_time()) { - changed.push_back(E->get()); - } - } + E->get()->invalidate(); + } - if (changed.size()) { - for (List<Ref<Resource> >::Element *E = changed.front(); E; E = E->next()) { - E->get()->reload_from_file(); - } - } + for (Set<EditorFileDialog *>::Element *E = editor_file_dialogs.front(); E; E = E->next()) { + + E->get()->invalidate(); } _mark_unsaved_scenes(); @@ -637,6 +636,7 @@ void EditorNode::save_resource(const Ref<Resource> &p_resource) { void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String &p_at_path) { file->set_mode(EditorFileDialog::MODE_SAVE_FILE); + saving_resource = p_resource; current_option = RESOURCE_SAVE_AS; List<String> extensions; @@ -1263,15 +1263,13 @@ void EditorNode::_dialog_action(String p_file) { case RESOURCE_SAVE: case RESOURCE_SAVE_AS: { - uint32_t current = editor_history.get_current(); + ERR_FAIL_COND(saving_resource.is_null()) + save_resource_in_path(saving_resource, p_file); + saving_resource = Ref<Resource>(); + ObjectID current = editor_history.get_current(); Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL; - - ERR_FAIL_COND(!Object::cast_to<Resource>(current_obj)) - - RES current_res = RES(Object::cast_to<Resource>(current_obj)); - - save_resource_in_path(current_res, p_file); - + ERR_FAIL_COND(!current_obj); + current_obj->_change_notify(); } break; case SETTINGS_LAYOUT_SAVE: { @@ -2570,6 +2568,12 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled) return; } + //errors in the script cause the base_type to be "" + if (String(script->get_instance_base_type()) == "") { + show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), path)); + return; + } + //could check inheritance.. if (String(script->get_instance_base_type()) != "EditorPlugin") { show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), path)); @@ -4651,6 +4655,8 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_video_driver_selected"), &EditorNode::_video_driver_selected); + ClassDB::bind_method(D_METHOD("_resources_changed"), &EditorNode::_resources_changed); + ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("pause_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); @@ -5777,6 +5783,7 @@ EditorNode::EditorNode() { _edit_current(); current = NULL; + saving_resource = Ref<Resource>(); reference_resource_mem = true; save_external_resources_mem = true; @@ -5819,6 +5826,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"); + EditorFileSystem::get_singleton()->connect("resources_reload", this, "_resources_changed"); _build_icon_type_cache(); diff --git a/editor/editor_node.h b/editor/editor_node.h index b828a4d7d5..eda7ebcf53 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -356,6 +356,7 @@ private: EditorExport *editor_export; Object *current; + Ref<Resource> saving_resource; bool _playing_edited; String run_custom_filename; @@ -605,6 +606,8 @@ private: static void _resource_saved(RES p_resource, const String &p_path); static void _resource_loaded(RES p_resource, const String &p_path); + void _resources_changed(const PoolVector<String> &p_resources); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 3730807243..57c6fa3547 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1802,14 +1802,26 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) { NodePath path = p_path; Node *base_node = Object::cast_to<Node>(get_edited_object()); - if (base_node == NULL) { - if (Object::cast_to<Resource>(get_edited_object())) { - Node *to_node = get_node(p_path); - path = get_tree()->get_edited_scene_root()->get_path_to(to_node); - } else if (get_edited_object()->has_method("get_root_path")) { - base_node = get_edited_object()->call("get_root_path"); + if (!base_node) { + //try a base node within history + if (EditorNode::get_singleton()->get_editor_history()->get_path_size() > 0) { + Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(0)); + if (base) { + base_node = Object::cast_to<Node>(base); + } } } + + if (!base_node && get_edited_object()->has_method("get_root_path")) { + base_node = get_edited_object()->call("get_root_path"); + } + + if (!base_node && Object::cast_to<Reference>(get_edited_object())) { + Node *to_node = get_node(p_path); + ERR_FAIL_COND(!to_node); + path = get_tree()->get_edited_scene_root()->get_path_to(to_node); + } + if (base_node) { // for AnimationTrackKeyEdit path = base_node->get_path().rel_path_to(p_path); } @@ -2016,6 +2028,13 @@ void EditorPropertyResource::_menu_option(int p_which) { } break; + case OBJ_MENU_SAVE: { + RES res = get_edited_object()->get(get_edited_property()); + if (res.is_null()) + return; + EditorNode::get_singleton()->save_resource(res); + } break; + case OBJ_MENU_COPY: { RES res = get_edited_object()->get(get_edited_property()); @@ -2233,6 +2252,7 @@ void EditorPropertyResource::_update_menu_items() { menu->add_icon_item(get_icon("Edit", "EditorIcons"), TTR("Edit"), OBJ_MENU_EDIT); menu->add_icon_item(get_icon("Clear", "EditorIcons"), TTR("Clear"), OBJ_MENU_CLEAR); menu->add_icon_item(get_icon("Duplicate", "EditorIcons"), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE); + menu->add_icon_item(get_icon("Save", "EditorIcons"), TTR("Save"), OBJ_MENU_SAVE); RES r = res; if (r.is_valid() && r->get_path().is_resource_file()) { menu->add_separator(); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 541abb1f22..b82ef977ef 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -522,10 +522,11 @@ class EditorPropertyResource : public EditorProperty { OBJ_MENU_EDIT = 1, OBJ_MENU_CLEAR = 2, OBJ_MENU_MAKE_UNIQUE = 3, - OBJ_MENU_COPY = 4, - OBJ_MENU_PASTE = 5, - OBJ_MENU_NEW_SCRIPT = 6, - OBJ_MENU_SHOW_IN_FILE_SYSTEM = 7, + OBJ_MENU_SAVE = 4, + OBJ_MENU_COPY = 5, + OBJ_MENU_PASTE = 6, + OBJ_MENU_NEW_SCRIPT = 7, + OBJ_MENU_SHOW_IN_FILE_SYSTEM = 8, TYPE_BASE_ID = 100, CONVERT_BASE_ID = 1000 diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index c0b441bbd5..fdfa094ba2 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -300,6 +300,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "10,40,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/code_font_size", 14); hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT); + _initial_set("interface/editor/main_font_antialiased", true); + _initial_set("interface/editor/code_font_antialiased", true); _initial_set("interface/editor/main_font_hinting", 2); hints["interface/editor/main_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/main_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT); _initial_set("interface/editor/code_font_hinting", 2); diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index e8bb772a64..b133efead7 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -771,7 +771,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me int binormal_pos = (binormal_src->stride ? binormal_src->stride : 3) * p.indices[src + binormal_ofs]; ERR_FAIL_INDEX_V(binormal_pos, binormal_src->array.size(), ERR_INVALID_DATA); - Vector3 binormal = Vector3(binormal_src->array[binormal_pos + 0], binormal_src->array[binormal_pos + 1], binormal_src->array[binormal_pos + 2]); + Vector3 binormal = Vector3(-binormal_src->array[binormal_pos + 0], -binormal_src->array[binormal_pos + 1], -binormal_src->array[binormal_pos + 2]); // Due to Godots face order it seems we need to flip our binormal! int tangent_pos = (tangent_src->stride ? tangent_src->stride : 3) * p.indices[src + tangent_ofs]; ERR_FAIL_INDEX_V(tangent_pos, tangent_src->array.size(), ERR_INVALID_DATA); diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index cb15be35f2..f47252d388 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -899,7 +899,16 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { array[Mesh::ARRAY_NORMAL] = _decode_accessor_as_vec3(state, a["NORMAL"], true); } if (a.has("TANGENT")) { - array[Mesh::ARRAY_TANGENT] = _decode_accessor_as_floats(state, a["TANGENT"], true); + PoolVector<float> tans = _decode_accessor_as_floats(state, a["TANGENT"], true); + { // we need our binormals inversed, so flip our w component. + int ts = tans.size(); + PoolVector<float>::Write w = tans.write(); + + for (int j = 3; j < ts; j += 4) { + w[j] *= -1.0; + } + } + array[Mesh::ARRAY_TANGENT] = tans; } if (a.has("TEXCOORD_0")) { array[Mesh::ARRAY_TEX_UV] = _decode_accessor_as_vec2(state, a["TEXCOORD_0"], true); diff --git a/methods.py b/methods.py index a6310fe850..5fcbc94298 100644 --- a/methods.py +++ b/methods.py @@ -628,3 +628,27 @@ def CommandNoCache(env, target, sources, command, **args): result = env.Command(target, sources, command, **args) env.NoCache(result) return result + +def detect_darwin_sdk_path(platform, env): + sdk_name = '' + if platform == 'osx': + sdk_name = 'macosx' + var_name = 'MACOS_SDK_PATH' + elif platform == 'iphone': + sdk_name = 'iphoneos' + var_name = 'IPHONESDK' + elif platform == 'iphonesimulator': + sdk_name = 'iphonesimulator' + var_name = 'IPHONESDK' + else: + raise Exception("Invalid platform argument passed to detect_darwin_sdk_path") + + if not env[var_name]: + try: + sdk_path = subprocess.check_output(['xcrun', '--sdk', sdk_name, '--show-sdk-path']).strip() + if sdk_path: + env[var_name] = sdk_path + except (subprocess.CalledProcessError, OSError) as e: + print("Failed to find SDK path while running xcrun --sdk {} --show-sdk-path.".format(sdk_name)) + raise + diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 23d879e1cd..a4c34e7583 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -201,10 +201,9 @@ void CSGShape::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const flo int i = (iFace * 3 + iVert) * 4; - // Godot seems to want the tangent flipped because our handedness is reversed.. - surface.tansw[i++] = -fvTangent[0]; - surface.tansw[i++] = -fvTangent[1]; - surface.tansw[i++] = -fvTangent[2]; + surface.tansw[i++] = fvTangent[0]; + surface.tansw[i++] = fvTangent[1]; + surface.tansw[i++] = fvTangent[2]; surface.tansw[i++] = fSign; } @@ -219,11 +218,10 @@ void CSGShape::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const f Vector3 bitangent = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]); float d = bitangent.dot(normal.cross(tangent)); - // Godot seems to want the tangent flipped because our handedness is reversed.. i *= 4; - surface.tansw[i++] = -tangent.x; - surface.tansw[i++] = -tangent.y; - surface.tansw[i++] = -tangent.z; + surface.tansw[i++] = tangent.x; + surface.tansw[i++] = tangent.y; + surface.tansw[i++] = tangent.z; surface.tansw[i++] = d < 0 ? -1 : 1; } @@ -1666,6 +1664,24 @@ CSGBrush *CSGPolygon::_build_brush() { Path *path = NULL; Ref<Curve3D> curve; + // get bounds for our polygon + Vector2 final_polygon_min; + Vector2 final_polygon_max; + for (int i = 0; i < final_polygon.size(); i++) { + Vector2 p = final_polygon[i]; + if (i == 0) { + final_polygon_min = p; + final_polygon_max = final_polygon_min; + } else { + if (p.x < final_polygon_min.x) final_polygon_min.x = p.x; + if (p.y < final_polygon_min.y) final_polygon_min.y = p.y; + + if (p.x > final_polygon_max.x) final_polygon_max.x = p.x; + if (p.y > final_polygon_max.y) final_polygon_max.y = p.y; + } + } + Vector2 final_polygon_size = final_polygon_max - final_polygon_min; + if (mode == MODE_PATH) { if (!has_node(path_node)) return NULL; @@ -1757,6 +1773,10 @@ CSGBrush *CSGPolygon::_build_brush() { v.z -= depth; } facesw[face * 3 + k] = v; + uvsw[face * 3 + k] = (p - final_polygon_min) / final_polygon_size; + if (i == 0) { + uvsw[face * 3 + k].x = 1.0 - uvsw[face * 3 + k].x; /* flip x */ + } } smoothw[face] = false; @@ -1888,6 +1908,7 @@ CSGBrush *CSGPolygon::_build_brush() { Vector2 p = final_polygon[triangles[j + src[k]]]; Vector3 v = Vector3(p.x, p.y, 0); facesw[face * 3 + k] = v; + uvsw[face * 3 + k] = (p - final_polygon_min) / final_polygon_size; } smoothw[face] = false; @@ -1905,6 +1926,8 @@ CSGBrush *CSGPolygon::_build_brush() { Vector2 p = final_polygon[triangles[j + src[k]]]; Vector3 v = Vector3(normali_n.x * p.x, p.y, normali_n.z * p.x); facesw[face * 3 + k] = v; + uvsw[face * 3 + k] = (p - final_polygon_min) / final_polygon_size; + uvsw[face * 3 + k].x = 1.0 - uvsw[face * 3 + k].x; /* flip x */ } smoothw[face] = false; @@ -1990,10 +2013,10 @@ CSGBrush *CSGPolygon::_build_brush() { }; Vector2 u[4] = { - Vector2(u1, 0), Vector2(u1, 1), - Vector2(u2, 1), - Vector2(u2, 0) + Vector2(u1, 0), + Vector2(u2, 0), + Vector2(u2, 1) }; // face 1 @@ -2036,6 +2059,7 @@ CSGBrush *CSGPolygon::_build_brush() { Vector2 p = final_polygon[triangles[j + src[k]]]; Vector3 v = Vector3(p.x, p.y, 0); facesw[face * 3 + k] = xf.xform(v); + uvsw[face * 3 + k] = (p - final_polygon_min) / final_polygon_size; } smoothw[face] = false; @@ -2053,6 +2077,8 @@ CSGBrush *CSGPolygon::_build_brush() { Vector2 p = final_polygon[triangles[j + src[k]]]; Vector3 v = Vector3(p.x, p.y, 0); facesw[face * 3 + k] = xf.xform(v); + uvsw[face * 3 + k] = (p - final_polygon_min) / final_polygon_size; + uvsw[face * 3 + k].x = 1.0 - uvsw[face * 3 + k].x; /* flip x */ } smoothw[face] = false; @@ -2077,6 +2103,9 @@ CSGBrush *CSGPolygon::_build_brush() { } else { aabb.expand_to(facesw[i]); } + + // invert UVs on the Y-axis OpenGL = upside down + uvsw[i].y = 1.0 - uvsw[i].y; } } diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs index 54d2813abf..b318d96bb9 100644 --- a/modules/mono/glue/Managed/Files/Basis.cs +++ b/modules/mono/glue/Managed/Files/Basis.cs @@ -13,9 +13,9 @@ namespace Godot { private static readonly Basis identity = new Basis ( - new Vector3(1f, 0f, 0f), - new Vector3(0f, 1f, 0f), - new Vector3(0f, 0f, 1f) + 1f, 0f, 0f, + 0f, 1f, 0f, + 0f, 0f, 1f ); private static readonly Basis[] orthoBases = { @@ -159,9 +159,9 @@ namespace Godot { return new Basis ( - new Vector3(xAxis.x, yAxis.x, zAxis.x), - new Vector3(xAxis.y, yAxis.y, zAxis.y), - new Vector3(xAxis.z, yAxis.z, zAxis.z) + xAxis.x, yAxis.x, zAxis.x, + xAxis.y, yAxis.y, zAxis.y, + xAxis.z, yAxis.z, zAxis.z ); } @@ -535,12 +535,17 @@ namespace Godot public Basis(Vector3 xAxis, Vector3 yAxis, Vector3 zAxis) { - x = xAxis; - y = yAxis; - z = zAxis; + _x = new Vector3(xAxis.x, yAxis.x, zAxis.x); + _y = new Vector3(xAxis.y, yAxis.y, zAxis.y); + _z = new Vector3(xAxis.z, yAxis.z, zAxis.z); + // Same as: + // SetAxis(0, xAxis); + // SetAxis(1, yAxis); + // SetAxis(2, zAxis); + // We need to assign the struct fields so we can't do that... } - public Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) + internal Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) { _x = new Vector3(xx, xy, xz); _y = new Vector3(yx, yy, yz); diff --git a/modules/mono/glue/Managed/Files/Transform.cs b/modules/mono/glue/Managed/Files/Transform.cs index 687ed8f011..fa85855edd 100644 --- a/modules/mono/glue/Managed/Files/Transform.cs +++ b/modules/mono/glue/Managed/Files/Transform.cs @@ -124,9 +124,9 @@ namespace Godot // Constants private static readonly Transform _identity = new Transform(Basis.Identity, Vector3.Zero); - private static readonly Transform _flipX = new Transform(new Basis(new Vector3(-1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1)), Vector3.Zero); - private static readonly Transform _flipY = new Transform(new Basis(new Vector3(1, 0, 0), new Vector3(0, -1, 0), new Vector3(0, 0, 1)), Vector3.Zero); - private static readonly Transform _flipZ = new Transform(new Basis(new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, -1)), Vector3.Zero); + private static readonly Transform _flipX = new Transform(new Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1), Vector3.Zero); + private static readonly Transform _flipY = new Transform(new Basis(1, 0, 0, 0, -1, 0, 0, 0, 1), Vector3.Zero); + private static readonly Transform _flipZ = new Transform(new Basis(1, 0, 0, 0, 1, 0, 0, 0, -1), Vector3.Zero); public static Transform Identity { get { return _identity; } } public static Transform FlipX { get { return _flipX; } } diff --git a/modules/mono/glue/Managed/Files/Vector3.cs b/modules/mono/glue/Managed/Files/Vector3.cs index 8e62ec778d..f6ff27989d 100644 --- a/modules/mono/glue/Managed/Files/Vector3.cs +++ b/modules/mono/glue/Managed/Files/Vector3.cs @@ -204,9 +204,9 @@ namespace Godot public Basis Outer(Vector3 b) { return new Basis( - new Vector3(x * b.x, x * b.y, x * b.z), - new Vector3(y * b.x, y * b.y, y * b.z), - new Vector3(z * b.x, z * b.y, z * b.z) + x * b.x, x * b.y, x * b.z, + y * b.x, y * b.y, y * b.z, + z * b.x, z * b.y, z * b.z ); } diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index c5f2070963..afaa6a9b95 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1923,7 +1923,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } } -void VisualScriptEditor::_selected_method(const String &p_method, const String &p_type) { +void VisualScriptEditor::_selected_method(const String &p_method, const String &p_type, const bool p_connecting) { Ref<VisualScriptFunctionCall> vsfc = script->get_node(edited_func, selecting_method_id); if (!vsfc.is_valid()) diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index ce3245bc28..5f707c9e4c 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -234,7 +234,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _comment_node_resized(const Vector2 &p_new_size, int p_node); int selecting_method_id; - void _selected_method(const String &p_method, const String &p_type); + void _selected_method(const String &p_method, const String &p_type, const bool p_connecting); void _draw_color_over_button(Object *obj, Color p_color); void _button_resource_previewed(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, Variant p_ud); diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 07e4048c12..43bd841baf 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -268,11 +268,11 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { return ret; }; - if (name == "java.lang.Integer") { + if (name == "java.lang.Integer" || name == "java.lang.Long") { jclass nclass = env->FindClass("java/lang/Number"); - jmethodID intValue = env->GetMethodID(nclass, "intValue", "()I"); - int ret = env->CallIntMethod(obj, intValue); + jmethodID longValue = env->GetMethodID(nclass, "longValue", "()J"); + jlong ret = env->CallLongMethod(obj, longValue); return ret; }; diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index 417571f6f3..c9f37931b0 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -1,7 +1,7 @@ import os import string import sys - +from methods import detect_darwin_sdk_path def is_active(): return True @@ -22,9 +22,8 @@ def can_build(): def get_opts(): from SCons.Variables import BoolVariable return [ - ('IPHONEPLATFORM', 'Name of the iPhone platform', 'iPhoneOS'), ('IPHONEPATH', 'Path to iPhone toolchain', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'), - ('IPHONESDK', 'Path to the iPhone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/${IPHONEPLATFORM}.platform/Developer/SDKs/${IPHONEPLATFORM}.sdk/'), + ('IPHONESDK', 'Path to the iPhone SDK', ''), BoolVariable('game_center', 'Support for game center', True), BoolVariable('store_kit', 'Support for in-app store', True), BoolVariable('icloud', 'Support for iCloud', True), @@ -103,13 +102,15 @@ def configure(env): ## Compile flags if (env["arch"] == "x86" or env["arch"] == "x86_64"): - env['IPHONEPLATFORM'] = 'iPhoneSimulator' + detect_darwin_sdk_path('iphonesimulator', env) env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.9' arch_flag = "i386" if env["arch"] == "x86" else env["arch"] env.Append(CCFLAGS=('-arch ' + arch_flag + ' -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=9.0 -DCUSTOM_MATRIX_TRANSFORM_H=\\\"build/iphone/matrix4_iphone.h\\\" -DCUSTOM_VECTOR3_TRANSFORM_H=\\\"build/iphone/vector3_iphone.h\\\"').split()) elif (env["arch"] == "arm"): + detect_darwin_sdk_path('iphone', env) env.Append(CCFLAGS='-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=9.0 -MMD -MT dependencies'.split()) elif (env["arch"] == "arm64"): + detect_darwin_sdk_path('iphone', env) env.Append(CCFLAGS='-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=9.0 -isysroot $IPHONESDK'.split()) env.Append(CPPFLAGS=['-DNEED_LONG_INT']) env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON']) diff --git a/platform/osx/detect.py b/platform/osx/detect.py index c5bd64b15c..051836b66d 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -1,5 +1,6 @@ import os import sys +from methods import detect_darwin_sdk_path def is_active(): @@ -23,6 +24,7 @@ def get_opts(): return [ ('osxcross_sdk', 'OSXCross SDK version', 'darwin14'), + ('MACOS_SDK_PATH', 'Path to the macOS SDK', ''), EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')), BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False), ] @@ -84,6 +86,10 @@ def configure(env): env['AS'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as" env.Append(CCFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define + detect_darwin_sdk_path('osx', env) + env.Append(CPPFLAGS=['-isysroot', '$MACOS_SDK_PATH']) + env.Append(LINKFLAGS=['-isysroot', '$MACOS_SDK_PATH']) + else: # osxcross build root = os.environ.get("OSXCROSS_ROOT", 0) basecmd = root + "/target/bin/x86_64-apple-" + env["osxcross_sdk"] + "-" diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 8123aaa427..e7b3e35381 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -76,6 +76,13 @@ #define NSWindowStyleMaskBorderless NSBorderlessWindowMask #endif +#ifndef NSAppKitVersionNumber10_12 +#define NSAppKitVersionNumber10_12 1504 +#endif +#ifndef NSAppKitVersionNumber10_14 +#define NSAppKitVersionNumber10_14 1671 +#endif + static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> state) { state->set_shift((p_osx_state & NSEventModifierFlagShift)); @@ -1237,7 +1244,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a ERR_FAIL_COND_V(window_object == nil, ERR_UNAVAILABLE); window_view = [[GodotContentView alloc] init]; - if (@available(macOS 10.14, *)) { + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_14) { [window_view setWantsLayer:TRUE]; } @@ -1472,7 +1479,7 @@ public: switch (p_type) { case ERR_WARNING: - if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_info(OS_LOG_DEFAULT, "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line); @@ -1482,7 +1489,7 @@ public: logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line); break; case ERR_SCRIPT: - if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_error(OS_LOG_DEFAULT, "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line); @@ -1492,7 +1499,7 @@ public: logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line); break; case ERR_SHADER: - if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_error(OS_LOG_DEFAULT, "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line); @@ -1503,7 +1510,7 @@ public: break; case ERR_ERROR: default: - if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_error(OS_LOG_DEFAULT, "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line); @@ -2174,11 +2181,7 @@ void OS_OSX::set_window_size(const Size2 p_size) { if (menuBarHeight != 0.f) { size.y += menuBarHeight; } else { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 if (floor(NSAppKitVersionNumber) < NSAppKitVersionNumber10_12) { -#else - { -#endif size.y += [[NSStatusBar systemStatusBar] thickness]; } } diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 8e00fbe735..5bde224ce3 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -461,6 +461,13 @@ void Sprite3D::_draw() { int axis = get_axis(); normal[axis] = 1.0; + Plane tangent; + if (axis == Vector3::AXIS_X) { + tangent = Plane(0, 0, -1, -1); + } else { + tangent = Plane(1, 0, 0, -1); + } + RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS); VS::get_singleton()->immediate_set_material(immediate, mat); @@ -487,6 +494,7 @@ void Sprite3D::_draw() { for (int i = 0; i < 4; i++) { VS::get_singleton()->immediate_normal(immediate, normal); + VS::get_singleton()->immediate_tangent(immediate, tangent); VS::get_singleton()->immediate_color(immediate, color); VS::get_singleton()->immediate_uv(immediate, uvs[i]); @@ -761,6 +769,13 @@ void AnimatedSprite3D::_draw() { int axis = get_axis(); normal[axis] = 1.0; + Plane tangent; + if (axis == Vector3::AXIS_X) { + tangent = Plane(0, 0, -1, -1); + } else { + tangent = Plane(1, 0, 0, -1); + } + RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS); VS::get_singleton()->immediate_set_material(immediate, mat); @@ -788,6 +803,7 @@ void AnimatedSprite3D::_draw() { for (int i = 0; i < 4; i++) { VS::get_singleton()->immediate_normal(immediate, normal); + VS::get_singleton()->immediate_tangent(immediate, tangent); VS::get_singleton()->immediate_color(immediate, color); VS::get_singleton()->immediate_uv(immediate, uvs[i]); diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp index 83f45afac8..3119e29586 100644 --- a/scene/animation/skeleton_ik.cpp +++ b/scene/animation/skeleton_ik.cpp @@ -280,7 +280,7 @@ void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_ } } -void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool p_use_magnet, const Vector3 &p_magnet_position) { +void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) { if (blending_delta <= 0.01f) { return; // Skip solving @@ -314,7 +314,10 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool p_u } } else { // Set target orientation to tip - new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis; + if (override_tip_basis) + new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis; + else + new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis; } p_task->skeleton->set_bone_global_pose(ci->bone, new_bone_pose); @@ -366,6 +369,9 @@ void SkeletonIK::_bind_methods() { ClassDB::bind_method(D_METHOD("set_target_node", "node"), &SkeletonIK::set_target_node); ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonIK::get_target_node); + ClassDB::bind_method(D_METHOD("set_override_tip_basis", "override"), &SkeletonIK::set_override_tip_basis); + ClassDB::bind_method(D_METHOD("is_override_tip_basis"), &SkeletonIK::is_override_tip_basis); + ClassDB::bind_method(D_METHOD("set_use_magnet", "use"), &SkeletonIK::set_use_magnet); ClassDB::bind_method(D_METHOD("is_using_magnet"), &SkeletonIK::is_using_magnet); @@ -388,6 +394,7 @@ void SkeletonIK::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "tip_bone"), "set_tip_bone", "get_tip_bone"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "target"), "set_target_transform", "get_target_transform"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_tip_basis"), "set_override_tip_basis", "is_override_tip_basis"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "magnet"), "set_magnet_position", "get_magnet_position"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node"), "set_target_node", "get_target_node"); @@ -418,6 +425,7 @@ void SkeletonIK::_notification(int p_what) { SkeletonIK::SkeletonIK() : Node(), interpolation(1), + override_tip_basis(true), use_magnet(false), min_distance(0.01), max_iterations(10), @@ -478,6 +486,14 @@ NodePath SkeletonIK::get_target_node() { return target_node_path_override; } +void SkeletonIK::set_override_tip_basis(bool p_override) { + override_tip_basis = p_override; +} + +bool SkeletonIK::is_override_tip_basis() const { + return override_tip_basis; +} + void SkeletonIK::set_use_magnet(bool p_use) { use_magnet = p_use; } @@ -555,7 +571,7 @@ void SkeletonIK::reload_goal() { void SkeletonIK::_solve_chain() { if (!task) return; - FabrikInverseKinematic::solve(task, interpolation, use_magnet, magnet_position); + FabrikInverseKinematic::solve(task, interpolation, override_tip_basis, use_magnet, magnet_position); } #endif // _3D_DISABLED diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h index 202d6959bb..b9628c479c 100644 --- a/scene/animation/skeleton_ik.h +++ b/scene/animation/skeleton_ik.h @@ -138,7 +138,7 @@ public: // The goal of chain should be always in local space static void set_goal(Task *p_task, const Transform &p_goal); static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta); - static void solve(Task *p_task, real_t blending_delta, bool p_use_magnet, const Vector3 &p_magnet_position); + static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position); }; class SkeletonIK : public Node { @@ -149,6 +149,7 @@ class SkeletonIK : public Node { real_t interpolation; Transform target; NodePath target_node_path_override; + bool override_tip_basis; bool use_magnet; Vector3 magnet_position; @@ -185,6 +186,9 @@ public: void set_target_node(const NodePath &p_node); NodePath get_target_node(); + void set_override_tip_basis(bool p_override); + bool is_override_tip_basis() const; + void set_use_magnet(bool p_use); bool is_using_magnet() const; diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index c38c411333..3554f04cc0 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -62,39 +62,28 @@ void SplitContainer::_resort() { // If we have only one element if (!first || !second) { if (first) { - fit_child_in_rect(_getch(0), Rect2(Point2(), get_size())); + fit_child_in_rect(first, Rect2(Point2(), get_size())); } else if (second) { - fit_child_in_rect(_getch(1), Rect2(Point2(), get_size())); + fit_child_in_rect(second, Rect2(Point2(), get_size())); } return; } // Determine expanded children - bool first_expanded = false; - bool second_expanded = false; - if (vertical) { - first_expanded = first->get_v_size_flags() & SIZE_EXPAND; - second_expanded = second->get_v_size_flags() & SIZE_EXPAND; - } else { - first_expanded = first->get_h_size_flags() & SIZE_EXPAND; - second_expanded = second->get_h_size_flags() & SIZE_EXPAND; - } + bool first_expanded = (vertical ? first->get_v_size_flags() : first->get_h_size_flags()) & SIZE_EXPAND; + bool second_expanded = (vertical ? second->get_v_size_flags() : second->get_h_size_flags()) & SIZE_EXPAND; // Determine the separation between items Ref<Texture> g = get_icon("grabber"); int sep = get_constant("separation"); - if (dragger_visibility == DRAGGER_HIDDEN_COLLAPSED) { - sep = 0; - } else { - sep = MAX(sep, vertical ? g->get_height() : g->get_width()); - } + sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; // Compute the minimum size Size2 ms_first = first->get_combined_minimum_size(); Size2 ms_second = second->get_combined_minimum_size(); + // Compute the separator position without the split offset float ratio = first->get_stretch_ratio() / (first->get_stretch_ratio() + second->get_stretch_ratio()); - int no_offset_middle_sep = 0; if (first_expanded && second_expanded) { no_offset_middle_sep = get_size()[axis] * ratio - sep / 2; @@ -104,12 +93,13 @@ void SplitContainer::_resort() { no_offset_middle_sep = ms_first[axis]; } - middle_sep = no_offset_middle_sep; - middle_sep += (collapsed) ? 0 : split_offset; - middle_sep = MIN(middle_sep, get_size()[axis] - ms_second[axis] - sep); - middle_sep = MAX(middle_sep, ms_first[axis]); - if (!collapsed) { - split_offset = middle_sep - no_offset_middle_sep; + // Compute the final middle separation + int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, (get_size()[axis] - ms_second[axis] - sep) - no_offset_middle_sep); + middle_sep = no_offset_middle_sep + clamped_split_offset; + if (!collapsed && should_clamp_split_offset) { + split_offset = clamped_split_offset; + _change_notify("split_offset"); + should_clamp_split_offset = false; } if (vertical) { @@ -123,7 +113,6 @@ void SplitContainer::_resort() { } update(); - _change_notify("split_offset"); } Size2 SplitContainer::get_minimum_size() const { @@ -131,8 +120,8 @@ Size2 SplitContainer::get_minimum_size() const { /* Calculate MINIMUM SIZE */ Size2i minimum; - int sep = get_constant("separation"); Ref<Texture> g = get_icon("grabber"); + int sep = get_constant("separation"); sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; for (int i = 0; i < 2; i++) { @@ -248,6 +237,7 @@ void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid() && dragging) { split_offset = drag_ofs + ((vertical ? mm->get_position().y : mm->get_position().x) - drag_from); + should_clamp_split_offset = true; queue_sort(); emit_signal("dragged", get_split_offset()); } @@ -282,6 +272,7 @@ void SplitContainer::set_split_offset(int p_offset) { return; split_offset = p_offset; + queue_sort(); } @@ -290,6 +281,12 @@ int SplitContainer::get_split_offset() const { return split_offset; } +void SplitContainer::clamp_split_offset() { + should_clamp_split_offset = true; + + queue_sort(); +} + void SplitContainer::set_collapsed(bool p_collapsed) { if (collapsed == p_collapsed) @@ -319,8 +316,10 @@ bool SplitContainer::is_collapsed() const { void SplitContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &SplitContainer::_gui_input); + ClassDB::bind_method(D_METHOD("set_split_offset", "offset"), &SplitContainer::set_split_offset); ClassDB::bind_method(D_METHOD("get_split_offset"), &SplitContainer::get_split_offset); + ClassDB::bind_method(D_METHOD("clamp_split_offset"), &SplitContainer::clamp_split_offset); ClassDB::bind_method(D_METHOD("set_collapsed", "collapsed"), &SplitContainer::set_collapsed); ClassDB::bind_method(D_METHOD("is_collapsed"), &SplitContainer::is_collapsed); @@ -343,6 +342,7 @@ SplitContainer::SplitContainer(bool p_vertical) { mouse_inside = false; split_offset = 0; + should_clamp_split_offset = false; middle_sep = 0; vertical = p_vertical; dragging = false; diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 321f7fd3b7..f8b3343aa8 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -45,9 +45,10 @@ public: }; private: - bool vertical; + bool should_clamp_split_offset; int split_offset; int middle_sep; + bool vertical; bool dragging; int drag_from; int drag_ofs; @@ -67,6 +68,7 @@ protected: public: void set_split_offset(int p_offset); int get_split_offset() const; + void clamp_split_offset(); void set_collapsed(bool p_collapsed); bool is_collapsed() const; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index d6b40766a2..ad22d6530c 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -82,11 +82,14 @@ void DynamicFontData::set_force_autohinter(bool p_force) { } void DynamicFontData::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &DynamicFontData::set_antialiased); + ClassDB::bind_method(D_METHOD("is_antialiased"), &DynamicFontData::is_antialiased); ClassDB::bind_method(D_METHOD("set_font_path", "path"), &DynamicFontData::set_font_path); ClassDB::bind_method(D_METHOD("get_font_path"), &DynamicFontData::get_font_path); ClassDB::bind_method(D_METHOD("set_hinting", "mode"), &DynamicFontData::set_hinting); ClassDB::bind_method(D_METHOD("get_hinting"), &DynamicFontData::get_hinting); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "is_antialiased"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); BIND_ENUM_CONSTANT(HINTING_NONE); @@ -98,6 +101,7 @@ void DynamicFontData::_bind_methods() { DynamicFontData::DynamicFontData() { + antialiased = true; force_autohinter = false; hinting = DynamicFontData::HINTING_NORMAL; font_mem = NULL; @@ -632,7 +636,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) { if (id.outline_size > 0) { character = _make_outline_char(p_char); } else { - error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); + error = FT_Render_Glyph(face->glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); if (!error) character = _bitmap_to_character(slot->bitmap, slot->bitmap_top, slot->bitmap_left, slot->advance.x / 64.0); } @@ -785,6 +789,18 @@ void DynamicFont::set_use_filter(bool p_enable) { _reload_cache(); } +bool DynamicFontData::is_antialiased() const { + + return antialiased; +} + +void DynamicFontData::set_antialiased(bool p_antialiased) { + + if (antialiased == p_antialiased) + return; + antialiased = p_antialiased; +} + DynamicFontData::Hinting DynamicFontData::get_hinting() const { return hinting; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index bd3f84d62c..96437e8982 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -71,12 +71,15 @@ public: HINTING_NORMAL }; + bool is_antialiased() const; + void set_antialiased(bool p_antialiased); Hinting get_hinting() const; void set_hinting(Hinting p_hinting); private: const uint8_t *font_mem; int font_mem_size; + bool antialiased; bool force_autohinter; Hinting hinting; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 8ff08f91f2..5327ed318f 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -699,7 +699,7 @@ void SpatialMaterial::_update_shader() { if (features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar code += "\t{\n"; - code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,BINORMAL*depth_flip.y,NORMAL));\n"; //binormal is negative due to mikktpsace + code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,BINORMAL*depth_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace if (deep_parallax) { code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n"; @@ -2277,7 +2277,7 @@ SpatialMaterial::SpatialMaterial() : deep_parallax = false; depth_parallax_flip_tangent = false; - depth_parallax_flip_binormal = true; + depth_parallax_flip_binormal = false; set_depth_deep_parallax_min_layers(8); set_depth_deep_parallax_max_layers(32); set_depth_deep_parallax_flip_tangent(false); //also sets binormal diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 4906ceb2eb..dafdddd990 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -306,7 +306,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * radius * w, y * radius * w, z); points.push_back(p + Vector3(0.0, 0.0, 0.5 * mid_height)); normals.push_back(p.normalized()); - ADD_TANGENT(y, -x, 0.0, -1.0) + ADD_TANGENT(-y, x, 0.0, -1.0) uvs.push_back(Vector2(u, v * onethird)); point++; @@ -345,7 +345,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * radius, y * radius, z); points.push_back(p); normals.push_back(Vector3(x, y, 0.0)); - ADD_TANGENT(y, -x, 0.0, -1.0) + ADD_TANGENT(-y, x, 0.0, -1.0) uvs.push_back(Vector2(u, onethird + (v * onethird))); point++; @@ -385,7 +385,7 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * radius * w, y * radius * w, z); points.push_back(p + Vector3(0.0, 0.0, -0.5 * mid_height)); normals.push_back(p.normalized()); - ADD_TANGENT(y, -x, 0.0, -1.0) + ADD_TANGENT(-y, x, 0.0, -1.0) uvs.push_back(Vector2(u, twothirds + ((v - 1.0) * onethird))); point++; @@ -514,14 +514,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { // front points.push_back(Vector3(x, -y, -start_pos.z)); // double negative on the Z! normals.push_back(Vector3(0.0, 0.0, 1.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(u, v)); point++; // back points.push_back(Vector3(-x, -y, start_pos.z)); normals.push_back(Vector3(0.0, 0.0, -1.0)); - ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(twothirds + u, v)); point++; @@ -568,14 +568,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { // right points.push_back(Vector3(-start_pos.x, -y, -z)); normals.push_back(Vector3(1.0, 0.0, 0.0)); - ADD_TANGENT(0.0, 0.0, 1.0, -1.0); + ADD_TANGENT(0.0, 0.0, -1.0, -1.0); uvs.push_back(Vector2(onethird + u, v)); point++; // left points.push_back(Vector3(start_pos.x, -y, z)); normals.push_back(Vector3(-1.0, 0.0, 0.0)); - ADD_TANGENT(0.0, 0.0, -1.0, -1.0); + ADD_TANGENT(0.0, 0.0, 1.0, -1.0); uvs.push_back(Vector2(u, 0.5 + v)); point++; @@ -622,14 +622,14 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { // top points.push_back(Vector3(-x, -start_pos.y, -z)); normals.push_back(Vector3(0.0, 1.0, 0.0)); - ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(onethird + u, 0.5 + v)); point++; // bottom points.push_back(Vector3(x, start_pos.y, -z)); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(twothirds + u, 0.5 + v)); point++; @@ -773,7 +773,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * radius, y, z * radius); points.push_back(p); normals.push_back(Vector3(x, 0.0, z)); - ADD_TANGENT(-z, 0.0, x, -1.0) + ADD_TANGENT(z, 0.0, -x, -1.0) uvs.push_back(Vector2(u, v * 0.5)); point++; @@ -799,7 +799,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { thisrow = point; points.push_back(Vector3(0.0, y, 0.0)); normals.push_back(Vector3(0.0, 1.0, 0.0)); - ADD_TANGENT(1.0, 0.0, 0.0, 1.0) + ADD_TANGENT(1.0, 0.0, 0.0, -1.0) uvs.push_back(Vector2(0.25, 0.75)); point++; @@ -816,7 +816,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * top_radius, y, z * top_radius); points.push_back(p); normals.push_back(Vector3(0.0, 1.0, 0.0)); - ADD_TANGENT(1.0, 0.0, 0.0, 1.0) + ADD_TANGENT(1.0, 0.0, 0.0, -1.0) uvs.push_back(Vector2(u, v)); point++; @@ -835,7 +835,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { thisrow = point; points.push_back(Vector3(0.0, y, 0.0)); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) + ADD_TANGENT(1.0, 0.0, 0.0, -1.0) uvs.push_back(Vector2(0.75, 0.75)); point++; @@ -852,7 +852,7 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { Vector3 p = Vector3(x * bottom_radius, y, z * bottom_radius); points.push_back(p); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) + ADD_TANGENT(1.0, 0.0, 0.0, -1.0) uvs.push_back(Vector2(u, v)); point++; @@ -983,7 +983,7 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const { points.push_back(Vector3(-x, 0.0, -z)); normals.push_back(Vector3(0.0, 1.0, 0.0)); ADD_TANGENT(1.0, 0.0, 0.0, -1.0); - uvs.push_back(Vector2(u, v)); + uvs.push_back(Vector2(1.0 - u, 1.0 - v)); /* 1.0 - uv to match orientation with Quad */ point++; if (i > 0 && j > 0) { @@ -1108,14 +1108,14 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { /* front */ points.push_back(Vector3(start_x + x, -y, -start_pos.z)); // double negative on the Z! normals.push_back(Vector3(0.0, 0.0, 1.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(offset_front + u, v)); point++; /* back */ points.push_back(Vector3(start_x + scaled_size_x - x, -y, start_pos.z)); normals.push_back(Vector3(0.0, 0.0, -1.0)); - ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(twothirds + offset_back + u, v)); point++; @@ -1187,14 +1187,14 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { /* right */ points.push_back(Vector3(right, -y, -z)); normals.push_back(normal_right); - ADD_TANGENT(0.0, 0.0, 1.0, -1.0); + ADD_TANGENT(0.0, 0.0, -1.0, -1.0); uvs.push_back(Vector2(onethird + u, v)); point++; /* left */ points.push_back(Vector3(left, -y, z)); normals.push_back(normal_left); - ADD_TANGENT(0.0, 0.0, -1.0, -1.0); + ADD_TANGENT(0.0, 0.0, 1.0, -1.0); uvs.push_back(Vector2(u, 0.5 + v)); point++; @@ -1241,7 +1241,7 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { /* bottom */ points.push_back(Vector3(x, start_pos.y, -z)); normals.push_back(Vector3(0.0, -1.0, 0.0)); - ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(twothirds + u, 0.5 + v)); point++; @@ -1382,7 +1382,7 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const { tangents.set(i * 4 + 0, 1.0); tangents.set(i * 4 + 1, 0.0); tangents.set(i * 4 + 2, 0.0); - tangents.set(i * 4 + 3, 1.0); + tangents.set(i * 4 + 3, -1.0); static const Vector2 quad_uv[4] = { Vector2(0, 1), @@ -1468,7 +1468,7 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const { points.push_back(p); normals.push_back(p.normalized()); }; - ADD_TANGENT(-z, 0.0, x, -1.0) + ADD_TANGENT(z, 0.0, -x, -1.0) uvs.push_back(Vector2(u, v)); point++; diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 74a05ce4e4..734c295a72 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -51,7 +51,7 @@ void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Tra } } -void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item **r_items, Transform2D *r_extra_transforms, int &r_index) { +void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item **r_items, int &r_index) { int child_item_count = p_canvas_item->child_items.size(); VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw(); for (int i = 0; i < child_item_count; i++) { @@ -64,7 +64,7 @@ void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2 r_index++; if (child_items[i]->sort_y) - _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, r_items, r_extra_transforms, r_index); + _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, r_items, r_index); } } @@ -100,7 +100,6 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor int child_item_count = ci->child_items.size(); Item **child_items = ci->child_items.ptrw(); - Transform2D *child_extra_transforms = NULL; if (ci->clip) { if (p_canvas_clip != NULL) { @@ -118,14 +117,14 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor if (ci->ysort_children_count == -1) { ci->ysort_children_count = 0; - _collect_ysort_children(ci, Transform2D(), NULL, NULL, ci->ysort_children_count); + _collect_ysort_children(ci, Transform2D(), NULL, ci->ysort_children_count); } child_item_count = ci->ysort_children_count; child_items = (Item **)alloca(child_item_count * sizeof(Item *)); int i = 0; - _collect_ysort_children(ci, Transform2D(), child_items, child_extra_transforms, i); + _collect_ysort_children(ci, Transform2D(), child_items, i); SortArray<Item *, ItemPtrSort> sorter; sorter.sort(child_items, child_item_count); @@ -336,7 +335,12 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { Item *item_owner = canvas_item_owner.get(canvas_item->parent); item_owner->child_items.erase(canvas_item); - item_owner->ysort_children_count = -1; + + Item *ysort_owner = item_owner; + while (ysort_owner && ysort_owner->sort_y) { + item_owner->ysort_children_count = -1; + ysort_owner = canvas_item_owner.getornull(ysort_owner->parent); + } } canvas_item->parent = RID(); @@ -1346,6 +1350,12 @@ bool VisualServerCanvas::free(RID p_rid) { Item *item_owner = canvas_item_owner.get(canvas_item->parent); item_owner->child_items.erase(canvas_item); + + Item *ysort_owner = item_owner; + while (ysort_owner && ysort_owner->sort_y) { + item_owner->ysort_children_count = -1; + ysort_owner = canvas_item_owner.getornull(ysort_owner->parent); + } } } diff --git a/thirdparty/enet/godot.cpp b/thirdparty/enet/godot.cpp index 6ba7cf0000..73a09f9b1d 100644 --- a/thirdparty/enet/godot.cpp +++ b/thirdparty/enet/godot.cpp @@ -33,7 +33,7 @@ */ #include "core/io/ip.h" -#include "core/io/packet_peer_udp.h" +#include "core/io/net_socket.h" #include "core/os/os.h" // This must be last for windows to compile (tested with MinGW) @@ -90,6 +90,16 @@ int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLen return -1; } +ENetSocket enet_socket_create(ENetSocketType type) { + + NetSocket *socket = NetSocket::create(); + IP::Type ip_type = IP::TYPE_ANY; + socket->open(NetSocket::TYPE_UDP, ip_type); + socket->set_blocking_enabled(false); + + return socket; +} + int enet_socket_bind(ENetSocket socket, const ENetAddress *address) { IP_Address ip; @@ -99,23 +109,15 @@ int enet_socket_bind(ENetSocket socket, const ENetAddress *address) { ip.set_ipv6(address->host); } - PacketPeerUDP *sock = (PacketPeerUDP *)socket; - if (sock->listen(address->port, ip) != OK) { + NetSocket *sock = (NetSocket *)socket; + if (sock->bind(ip, address->port) != OK) { return -1; } return 0; } -ENetSocket enet_socket_create(ENetSocketType type) { - - PacketPeerUDP *socket = memnew(PacketPeerUDP); - socket->set_blocking_mode(false); - - return socket; -} - void enet_socket_destroy(ENetSocket socket) { - PacketPeerUDP *sock = (PacketPeerUDP *)socket; + NetSocket *sock = (NetSocket *)socket; sock->close(); memdelete(sock); } @@ -124,13 +126,12 @@ int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBu ERR_FAIL_COND_V(address == NULL, -1); - PacketPeerUDP *sock = (PacketPeerUDP *)socket; + NetSocket *sock = (NetSocket *)socket; IP_Address dest; Error err; size_t i = 0; dest.set_ipv6(address->host); - sock->set_dest_address(dest, address->port); // Create a single packet. PoolVector<uint8_t> out; @@ -148,7 +149,8 @@ int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBu pos += buffers[i].dataLength; } - err = sock->put_packet((const uint8_t *)&w[0], size); + int sent = 0; + err = sock->sendto((const uint8_t *)&w[0], size, sent, dest, address->port); if (err != OK) { if (err == ERR_BUSY) { // Blocking call @@ -159,32 +161,36 @@ int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBu return -1; } - return size; + return sent; } int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) { ERR_FAIL_COND_V(bufferCount != 1, -1); - PacketPeerUDP *sock = (PacketPeerUDP *)socket; + NetSocket *sock = (NetSocket *)socket; - int pc = sock->get_available_packet_count(); - if (pc < 1) { - return pc; - } + Error ret = sock->poll(NetSocket::POLL_TYPE_IN, 0); - const uint8_t *buffer; - int buffer_size; - Error err = sock->get_packet(&buffer, buffer_size); - if (err) + if (ret == ERR_BUSY) + return 0; + + if (ret != OK) return -1; - copymem(buffers[0].data, buffer, buffer_size); + int read; + IP_Address ip; - enet_address_set_ip(address, sock->get_packet_address().get_ipv6(), 16); - address->port = sock->get_packet_port(); + Error err = sock->recvfrom((uint8_t *)buffers[0].data, buffers[0].dataLength, read, ip, address->port); + if (err == ERR_BUSY) + return 0; + + if (err != OK) + return -1; + + enet_address_set_ip(address, ip.get_ipv6(), 16); - return buffer_size; + return read; } // Not implemented |
