diff options
53 files changed, 982 insertions, 458 deletions
@@ -16,6 +16,8 @@ if sys.version_info < (3,): return x def iteritems(d): return d.iteritems() + def itervalues(d): + return d.itervalues() def escape_string(s): if isinstance(s, unicode): s = s.encode('ascii') @@ -44,6 +46,8 @@ else: return codecs.utf_8_decode(x)[0] def iteritems(d): return iter(d.items()) + def itervalues(d): + return iter(d.values()) def charcode_to_c_escapes(c): rev_result = [] while c >= 256: diff --git a/core/SCsub b/core/SCsub index 383aaf0e12..c4f1cdbe97 100644 --- a/core/SCsub +++ b/core/SCsub @@ -2,6 +2,8 @@ Import('env') +import methods + env.core_sources = [] @@ -93,6 +95,17 @@ env.add_source_files(env.core_sources, "*.cpp") import make_binders env.Command(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run) +# Authors +env.Depends('#core/authors.gen.h', "../AUTHORS.md") +env.Command('#core/authors.gen.h', "../AUTHORS.md", methods.make_authors_header) + +# Donors +env.Depends('#core/donors.gen.h', "../DONORS.md") +env.Command('#core/donors.gen.h', "../DONORS.md", methods.make_donors_header) + +# License +env.Depends('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]) +env.Command('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], methods.make_license_header) # Chain load SCsubs SConscript('os/SCsub') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 3270b33f1c..14e3804840 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2710,6 +2710,26 @@ Dictionary _Engine::get_version_info() const { return Engine::get_singleton()->get_version_info(); } +Dictionary _Engine::get_author_info() const { + return Engine::get_singleton()->get_author_info(); +} + +Array _Engine::get_copyright_info() const { + return Engine::get_singleton()->get_copyright_info(); +} + +Dictionary _Engine::get_donor_info() const { + return Engine::get_singleton()->get_donor_info(); +} + +Dictionary _Engine::get_license_info() const { + return Engine::get_singleton()->get_license_info(); +} + +String _Engine::get_license_text() const { + return Engine::get_singleton()->get_license_text(); +} + bool _Engine::is_in_physics_frame() const { return Engine::get_singleton()->is_in_physics_frame(); } @@ -2752,6 +2772,11 @@ void _Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("get_main_loop"), &_Engine::get_main_loop); ClassDB::bind_method(D_METHOD("get_version_info"), &_Engine::get_version_info); + ClassDB::bind_method(D_METHOD("get_author_info"), &_Engine::get_author_info); + ClassDB::bind_method(D_METHOD("get_copyright_info"), &_Engine::get_copyright_info); + ClassDB::bind_method(D_METHOD("get_donor_info"), &_Engine::get_donor_info); + ClassDB::bind_method(D_METHOD("get_license_info"), &_Engine::get_license_info); + ClassDB::bind_method(D_METHOD("get_license_text"), &_Engine::get_license_text); ClassDB::bind_method(D_METHOD("is_in_physics_frame"), &_Engine::is_in_physics_frame); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index a363f5970f..1de5e43b27 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -689,6 +689,11 @@ public: MainLoop *get_main_loop() const; Dictionary get_version_info() const; + Dictionary get_author_info() const; + Array get_copyright_info() const; + Dictionary get_donor_info() const; + Dictionary get_license_info() const; + String get_license_text() const; bool is_in_physics_frame() const; diff --git a/core/engine.cpp b/core/engine.cpp index b2c34a853c..7c8024b946 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -30,6 +30,9 @@ #include "engine.h" +#include "authors.gen.h" +#include "donors.gen.h" +#include "license.gen.h" #include "version.h" #include "version_hash.gen.h" @@ -111,6 +114,78 @@ Dictionary Engine::get_version_info() const { return dict; } +static Array array_from_info(const char *const *info_list) { + Array arr; + for (int i = 0; info_list[i] != NULL; i++) { + arr.push_back(info_list[i]); + } + return arr; +} + +static Array array_from_info_count(const char *const *info_list, int info_count) { + Array arr; + for (int i = 0; i < info_count; i++) { + arr.push_back(info_list[i]); + } + return arr; +} + +Dictionary Engine::get_author_info() const { + Dictionary dict; + + dict["lead_developers"] = array_from_info(AUTHORS_LEAD_DEVELOPERS); + dict["project_managers"] = array_from_info(AUTHORS_PROJECT_MANAGERS); + dict["founders"] = array_from_info(AUTHORS_FOUNDERS); + dict["developers"] = array_from_info(AUTHORS_DEVELOPERS); + + return dict; +} + +Array Engine::get_copyright_info() const { + Array components; + for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) { + const ComponentCopyright &cp_info = COPYRIGHT_INFO[component_index]; + Dictionary component_dict; + component_dict["name"] = cp_info.name; + Array parts; + for (int i = 0; i < cp_info.part_count; i++) { + const ComponentCopyrightPart &cp_part = cp_info.parts[i]; + Dictionary part_dict; + part_dict["files"] = array_from_info_count(cp_part.files, cp_part.file_count); + part_dict["copyright"] = array_from_info_count(cp_part.copyright_statements, cp_part.copyright_count); + part_dict["license"] = cp_part.license; + parts.push_back(part_dict); + } + component_dict["parts"] = parts; + + components.push_back(component_dict); + } + return components; +} + +Dictionary Engine::get_donor_info() const { + Dictionary donors; + donors["platinum_sponsors"] = array_from_info(DONORS_SPONSOR_PLAT); + donors["gold_sponsors"] = array_from_info(DONORS_SPONSOR_GOLD); + donors["mini_sponsors"] = array_from_info(DONORS_SPONSOR_MINI); + donors["gold_donors"] = array_from_info(DONORS_GOLD); + donors["silver_donors"] = array_from_info(DONORS_SILVER); + donors["bronze_donors"] = array_from_info(DONORS_BRONZE); + return donors; +} + +Dictionary Engine::get_license_info() const { + Dictionary licenses; + for (int i = 0; i < LICENSE_COUNT; i++) { + licenses[LICENSE_NAMES[i]] = LICENSE_BODIES[i]; + } + return licenses; +} + +String Engine::get_license_text() const { + return String(GODOT_LICENSE_TEXT); +} + void Engine::add_singleton(const Singleton &p_singleton) { singletons.push_back(p_singleton); diff --git a/core/engine.h b/core/engine.h index 665992699a..031ba29cd6 100644 --- a/core/engine.h +++ b/core/engine.h @@ -118,6 +118,11 @@ public: #endif Dictionary get_version_info() const; + Dictionary get_author_info() const; + Array get_copyright_info() const; + Dictionary get_donor_info() const; + Dictionary get_license_info() const; + String get_license_text() const; Engine(); }; diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index e01e2a84c5..16d5e3c282 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -175,7 +175,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S String prop = c.substr(0, p).strip_edges(); String value = c.substr(p + 1, c.length()).strip_edges(); - if (prop == "X-Language") { + if (prop == "X-Language" || prop == "Language") { translation->set_locale(value); } } diff --git a/core/project_settings.cpp b/core/project_settings.cpp index ef485cb3b2..ac4a4b7d15 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -1071,7 +1071,6 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("rendering/quality/intended_usage/framebuffer_mode", 2); GLOBAL_DEF("debug/settings/profiler/max_functions", 16384); - GLOBAL_DEF("debug/settings/performance/update_frequency_msec", 250); //assigning here, because using GLOBAL_GET on every block for compressing can be slow Compression::zstd_long_distance_matching = GLOBAL_DEF("compression/formats/zstd/long_distance_matching", false); diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 7a30a33c67..0473e2cc71 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -567,22 +567,46 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) { if (ScriptInstance *si = obj->get_script_instance()) { if (!si->get_script().is_null()) { - Set<StringName> members; - si->get_script()->get_members(&members); - for (Set<StringName>::Element *E = members.front(); E; E = E->next()) { - - Variant m; - if (si->get(E->get(), m)) { - PropertyInfo pi(m.get_type(), String("Members/") + E->get()); - properties.push_back(PropertyDesc(pi, m)); + typedef Map<const Script *, Set<StringName> > ScriptMemberMap; + typedef Map<const Script *, Map<StringName, Variant> > ScriptConstantsMap; + + ScriptMemberMap members; + members[si->get_script().ptr()] = Set<StringName>(); + si->get_script()->get_members(&(members[si->get_script().ptr()])); + + ScriptConstantsMap constants; + constants[si->get_script().ptr()] = Map<StringName, Variant>(); + si->get_script()->get_constants(&(constants[si->get_script().ptr()])); + + Ref<Script> base = si->get_script()->get_base_script(); + while (base.is_valid()) { + + members[base.ptr()] = Set<StringName>(); + base->get_members(&(members[base.ptr()])); + + constants[base.ptr()] = Map<StringName, Variant>(); + base->get_constants(&(constants[base.ptr()])); + + base = base->get_base_script(); + } + + for (ScriptMemberMap::Element *sm = members.front(); sm; sm = sm->next()) { + for (Set<StringName>::Element *E = sm->get().front(); E; E = E->next()) { + Variant m; + if (si->get(E->get(), m)) { + String script_path = sm->key() == si->get_script().ptr() ? "" : sm->key()->get_path().get_file() + "/"; + PropertyInfo pi(m.get_type(), "Members/" + script_path + E->get()); + properties.push_back(PropertyDesc(pi, m)); + } } } - Map<StringName, Variant> constants; - si->get_script()->get_constants(&constants); - for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { - PropertyInfo pi(E->value().get_type(), (String("Constants/") + E->key())); - properties.push_back(PropertyDesc(pi, E->value())); + for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) { + for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) { + String script_path = sc->key() == si->get_script().ptr() ? "" : sc->key()->get_path().get_file() + "/"; + PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key()); + properties.push_back(PropertyDesc(pi, E->value())); + } } } } @@ -658,8 +682,10 @@ void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String &p_p return; String prop_name = p_property; - if (p_property.begins_with("Members/")) - prop_name = p_property.substr(8, p_property.length()); + if (p_property.begins_with("Members/")) { + Vector<String> ss = p_property.split("/"); + prop_name = ss[ss.size() - 1]; + } obj->set(prop_name, p_value); } @@ -854,7 +880,7 @@ void ScriptDebuggerRemote::idle_poll() { if (performance) { uint64_t pt = OS::get_singleton()->get_ticks_msec(); - if (pt - last_perf_time > update_frequency) { + if (pt - last_perf_time > 1000) { last_perf_time = pt; int max = performance->get("MONITOR_MAX"); @@ -1081,7 +1107,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() : eh.userdata = this; add_error_handler(&eh); - profile_info.resize(CLAMP(int(GLOBAL_GET("debug/settings/profiler/max_functions")), 128, 65535)); + profile_info.resize(CLAMP(int(ProjectSettings::get_singleton()->get("debug/settings/profiler/max_functions")), 128, 65535)); profile_info_ptrs.resize(profile_info.size()); } diff --git a/core/script_language.cpp b/core/script_language.cpp index ce9b138bb2..1dab58e29e 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -29,7 +29,6 @@ /*************************************************************************/ #include "script_language.h" -#include "project_settings.h" ScriptLanguage *ScriptServer::_languages[MAX_LANGUAGES]; int ScriptServer::_language_count = 0; @@ -284,7 +283,6 @@ ScriptDebugger::ScriptDebugger() { lines_left = -1; depth = -1; break_lang = NULL; - update_frequency = GLOBAL_GET("debug/settings/performance/update_frequency_msec"); } bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_value) { diff --git a/core/script_language.h b/core/script_language.h index 64c6f2eb81..b4c55cac9e 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -352,8 +352,6 @@ class ScriptDebugger { public: typedef void (*RequestSceneTreeMessageFunc)(void *); - int update_frequency; - struct LiveEditFuncs { void *udata; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 4158c2a60e..e6f36ecbf1 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -763,6 +763,7 @@ struct _VariantCall { VCALL_PTR1R(Basis, xform_inv); VCALL_PTR0R(Basis, get_orthogonal_index); VCALL_PTR0R(Basis, orthonormalized); + VCALL_PTR2R(Basis, slerp); VCALL_PTR0R(Transform, inverse); VCALL_PTR0R(Transform, affine_inverse); @@ -1803,6 +1804,7 @@ void register_variant_methods() { ADDFUNC1R(BASIS, VECTOR3, Basis, xform, VECTOR3, "v", varray()); ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, VECTOR3, "v", varray()); ADDFUNC0R(BASIS, INT, Basis, get_orthogonal_index, varray()); + ADDFUNC2R(BASIS, BASIS, Basis, slerp, BASIS, "b", REAL, "t", varray()); ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, inverse, varray()); ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, affine_inverse, varray()); diff --git a/doc/classes/AnimationTreePlayer.xml b/doc/classes/AnimationTreePlayer.xml index 49b4c6b43e..8c32d5f6a3 100644 --- a/doc/classes/AnimationTreePlayer.xml +++ b/doc/classes/AnimationTreePlayer.xml @@ -50,6 +50,14 @@ Returns the name of the [member master_player]'s [Animation] bound to this animation node. </description> </method> + <method name="animation_node_get_position" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="id" type="String"> + </argument> + <description> + </description> + </method> <method name="animation_node_set_animation"> <return type="void"> </return> diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml index 656fce587f..9d7df14014 100644 --- a/doc/classes/ColorPickerButton.xml +++ b/doc/classes/ColorPickerButton.xml @@ -11,7 +11,7 @@ <demos> </demos> <methods> - <method name="get_picker" qualifiers="const"> + <method name="get_picker"> <return type="ColorPicker"> </return> <description> diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml new file mode 100644 index 0000000000..381eef5a40 --- /dev/null +++ b/doc/classes/EditorInspector.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorInspector" inherits="ScrollContainer" category="Core" version="3.1"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <signals> + <signal name="object_id_selected"> + <argument index="0" name="id" type="int"> + </argument> + <description> + </description> + </signal> + <signal name="property_keyed"> + <argument index="0" name="property" type="String"> + </argument> + <description> + </description> + </signal> + <signal name="resource_selected"> + <argument index="0" name="res" type="Object"> + </argument> + <argument index="1" name="prop" type="String"> + </argument> + <description> + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorInspectorPlugin.xml b/doc/classes/EditorInspectorPlugin.xml new file mode 100644 index 0000000000..9bda768b14 --- /dev/null +++ b/doc/classes/EditorInspectorPlugin.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorInspectorPlugin" inherits="Reference" category="Core" version="3.1"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="add_custom_control"> + <return type="void"> + </return> + <argument index="0" name="control" type="Control"> + </argument> + <description> + </description> + </method> + <method name="add_property_editor"> + <return type="void"> + </return> + <argument index="0" name="property" type="String"> + </argument> + <argument index="1" name="editor" type="Control"> + </argument> + <description> + </description> + </method> + <method name="add_property_editor_for_multiple_properties"> + <return type="void"> + </return> + <argument index="0" name="label" type="String"> + </argument> + <argument index="1" name="properties" type="PoolStringArray"> + </argument> + <argument index="2" name="editor" type="Control"> + </argument> + <description> + </description> + </method> + <method name="can_handle" qualifiers="virtual"> + <return type="bool"> + </return> + <argument index="0" name="object" type="Object"> + </argument> + <description> + </description> + </method> + <method name="parse_begin" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="object" type="Object"> + </argument> + <description> + </description> + </method> + <method name="parse_category" qualifiers="virtual"> + <return type="void"> + </return> + <argument index="0" name="object" type="Object"> + </argument> + <argument index="1" name="category" type="String"> + </argument> + <description> + </description> + </method> + <method name="parse_end" qualifiers="virtual"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="parse_property" qualifiers="virtual"> + <return type="bool"> + </return> + <argument index="0" name="object" type="Object"> + </argument> + <argument index="1" name="type" type="int"> + </argument> + <argument index="2" name="path" type="String"> + </argument> + <argument index="3" name="hint" type="int"> + </argument> + <argument index="4" name="hint_text" type="String"> + </argument> + <argument index="5" name="usage" type="int"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index e8e2c4fd74..860d98ab62 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -81,7 +81,7 @@ <method name="add_export_plugin"> <return type="void"> </return> - <argument index="0" name="exporter" type="EditorExportPlugin"> + <argument index="0" name="plugin" type="EditorExportPlugin"> </argument> <description> </description> @@ -94,6 +94,14 @@ <description> </description> </method> + <method name="add_inspector_plugin"> + <return type="void"> + </return> + <argument index="0" name="plugin" type="EditorInspectorPlugin"> + </argument> + <description> + </description> + </method> <method name="add_scene_import_plugin"> <return type="void"> </return> @@ -135,6 +143,12 @@ This is used, for example, in shader editors to let the plugin know that it must apply the shader code being written by the user to the object. </description> </method> + <method name="build" qualifiers="virtual"> + <return type="bool"> + </return> + <description> + </description> + </method> <method name="clear" qualifiers="virtual"> <return type="void"> </return> @@ -341,7 +355,7 @@ <method name="remove_export_plugin"> <return type="void"> </return> - <argument index="0" name="exporter" type="EditorExportPlugin"> + <argument index="0" name="plugin" type="EditorExportPlugin"> </argument> <description> </description> @@ -354,6 +368,14 @@ <description> </description> </method> + <method name="remove_inspector_plugin"> + <return type="void"> + </return> + <argument index="0" name="plugin" type="EditorInspectorPlugin"> + </argument> + <description> + </description> + </method> <method name="remove_scene_import_plugin"> <return type="void"> </return> diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml new file mode 100644 index 0000000000..9b5452ec14 --- /dev/null +++ b/doc/classes/EditorProperty.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorProperty" inherits="Container" category="Core" version="3.1"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + <method name="get_edited_object"> + <return type="Object"> + </return> + <description> + </description> + </method> + <method name="get_edited_property"> + <return type="String"> + </return> + <description> + </description> + </method> + <method name="update_property" qualifiers="virtual"> + <return type="void"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="checkable" type="bool" setter="set_checkable" getter="is_checkable"> + </member> + <member name="checked" type="bool" setter="set_checked" getter="is_checked"> + </member> + <member name="draw_red" type="bool" setter="set_draw_red" getter="is_draw_red"> + </member> + <member name="keying" type="bool" setter="set_keying" getter="is_keying"> + </member> + <member name="label" type="String" setter="set_label" getter="get_label"> + </member> + <member name="read_only" type="bool" setter="set_read_only" getter="is_read_only"> + </member> + </members> + <signals> + <signal name="multiple_properties_changed"> + <argument index="0" name="properties" type="PoolStringArray"> + </argument> + <argument index="1" name="value" type="Array"> + </argument> + <description> + </description> + </signal> + <signal name="object_id_selected"> + <argument index="0" name="property" type="String"> + </argument> + <argument index="1" name="id" type="int"> + </argument> + <description> + </description> + </signal> + <signal name="property_changed"> + <argument index="0" name="property" type="String"> + </argument> + <argument index="1" name="value" type="Nil"> + </argument> + <description> + </description> + </signal> + <signal name="property_checked"> + <argument index="0" name="property" type="String"> + </argument> + <argument index="1" name="bool" type="String"> + </argument> + <description> + </description> + </signal> + <signal name="property_keyed"> + <argument index="0" name="property" type="String"> + </argument> + <description> + </description> + </signal> + <signal name="property_keyed_with_value"> + <argument index="0" name="property" type="String"> + </argument> + <argument index="1" name="value" type="Nil"> + </argument> + <description> + </description> + </signal> + <signal name="resource_selected"> + <argument index="0" name="path" type="String"> + </argument> + <argument index="1" name="resource" type="Object"> + </argument> + <description> + </description> + </signal> + <signal name="selected"> + <argument index="0" name="path" type="String"> + </argument> + <argument index="1" name="focusable_idx" type="int"> + </argument> + <description> + </description> + </signal> + </signals> + <constants> + </constants> +</class> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 5325a67de3..bd85075b7e 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -67,7 +67,7 @@ <description> </description> </method> - <method name="get_project_settings_dir"> + <method name="get_project_settings_dir" qualifiers="const"> <return type="String"> </return> <description> @@ -144,6 +144,8 @@ </description> </method> <method name="set_project_metadata"> + <return type="void"> + </return> <argument index="0" name="section" type="String"> </argument> <argument index="1" name="key" type="String"> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index cc2ae4e768..3273005395 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -11,6 +11,36 @@ <demos> </demos> <methods> + <method name="get_author_info" qualifiers="const"> + <return type="Dictionary"> + </return> + <description> + Returns engine author information in a Dictionary. + + "lead_developers" - Array of Strings, lead developer names + "founders" - Array of Strings, founder names + "project_managers" - Array of Strings, project manager names + "developers" - Array of Strings, developer names + </description> + </method> + <method name="get_copyright_info" qualifiers="const"> + <return type="Array"> + </return> + <description> + Returns an Array of copyright information Dictionaries. + + "name" - String, component name + "parts" - Array of Dictionaries {"files", "copyright", "license"} describing subsections of the component + </description> + </method> + <method name="get_donor_info" qualifiers="const"> + <return type="Dictionary"> + </return> + <description> + Returns a Dictionary of Arrays of donor names. + {"platinum_sponsors", "gold_sponsors", "mini_sponsors", "gold_donors", "silver_donors", "bronze_donors"} + </description> + </method> <method name="get_frames_drawn"> <return type="int"> </return> @@ -25,6 +55,20 @@ Returns the frames per second of the running game. </description> </method> + <method name="get_license_info" qualifiers="const"> + <return type="Dictionary"> + </return> + <description> + Returns Dictionary of licenses used by Godot and included third party components. + </description> + </method> + <method name="get_license_text" qualifiers="const"> + <return type="String"> + </return> + <description> + Returns Godot license text. + </description> + </method> <method name="get_main_loop" qualifiers="const"> <return type="MainLoop"> </return> diff --git a/doc/classes/OrientedPathFollow.xml b/doc/classes/OrientedPathFollow.xml index c32e545ff5..85d60936ad 100644 --- a/doc/classes/OrientedPathFollow.xml +++ b/doc/classes/OrientedPathFollow.xml @@ -5,7 +5,7 @@ </brief_description> <description> This node behaves like [PathFollow], except it uses its parent [Path] up vector information to enforce orientation. - Make sure to check if the curve of this node's parent [Path] has up vectors enabled. See [PathFollow] and [Curve3D] for further information. + Make sure to check if the curve of this node's parent [Path] has up vectors enabled. See [PathFollow] and [Curve3D] for further information. </description> <tutorials> </tutorials> diff --git a/doc/classes/PhysicalBone.xml b/doc/classes/PhysicalBone.xml index 80b3c11270..99f551b865 100644 --- a/doc/classes/PhysicalBone.xml +++ b/doc/classes/PhysicalBone.xml @@ -9,12 +9,24 @@ <demos> </demos> <methods> + <method name="get_simulate_physics"> + <return type="bool"> + </return> + <description> + </description> + </method> <method name="is_simulating_physics"> <return type="bool"> </return> <description> </description> </method> + <method name="is_static_body"> + <return type="bool"> + </return> + <description> + </description> + </method> </methods> <members> <member name="body_offset" type="Transform" setter="set_body_offset" getter="get_body_offset"> @@ -31,10 +43,6 @@ </member> <member name="mass" type="float" setter="set_mass" getter="get_mass"> </member> - <member name="simulate_physics" type="bool" setter="set_simulate_physics" getter="get_simulate_physics"> - </member> - <member name="static_body" type="bool" setter="set_static_body" getter="is_static_body"> - </member> <member name="weight" type="float" setter="set_weight" getter="get_weight"> </member> </members> diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml index 4a678d9f6b..c302797704 100644 --- a/doc/classes/Physics2DServer.xml +++ b/doc/classes/Physics2DServer.xml @@ -140,6 +140,18 @@ Removes a shape from an area. It does not delete the shape, so it can be reassigned later. </description> </method> + <method name="area_set_area_monitor_callback"> + <return type="void"> + </return> + <argument index="0" name="area" type="RID"> + </argument> + <argument index="1" name="receiver" type="Object"> + </argument> + <argument index="2" name="method" type="String"> + </argument> + <description> + </description> + </method> <method name="area_set_collision_layer"> <return type="void"> </return> @@ -180,6 +192,16 @@ 5: The shape index of the area where the object entered/exited. </description> </method> + <method name="area_set_monitorable"> + <return type="void"> + </return> + <argument index="0" name="area" type="RID"> + </argument> + <argument index="1" name="monitorable" type="bool"> + </argument> + <description> + </description> + </method> <method name="area_set_param"> <return type="void"> </return> diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index f5311974f2..6efbfdb519 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -149,6 +149,18 @@ Removes a shape from an area. It does not delete the shape, so it can be reassigned later. </description> </method> + <method name="area_set_area_monitor_callback"> + <return type="void"> + </return> + <argument index="0" name="area" type="RID"> + </argument> + <argument index="1" name="receiver" type="Object"> + </argument> + <argument index="2" name="method" type="String"> + </argument> + <description> + </description> + </method> <method name="area_set_collision_layer"> <return type="void"> </return> @@ -189,6 +201,16 @@ 5: The shape index of the area where the object entered/exited. </description> </method> + <method name="area_set_monitorable"> + <return type="void"> + </return> + <argument index="0" name="area" type="RID"> + </argument> + <argument index="1" name="monitorable" type="bool"> + </argument> + <description> + </description> + </method> <method name="area_set_param"> <return type="void"> </return> diff --git a/doc/classes/ProceduralSky.xml b/doc/classes/ProceduralSky.xml index 664c80be5e..df0519b2ad 100644 --- a/doc/classes/ProceduralSky.xml +++ b/doc/classes/ProceduralSky.xml @@ -54,7 +54,7 @@ Amount of energy contribution from the sun. </member> <member name="sun_latitude" type="float" setter="set_sun_latitude" getter="get_sun_latitude"> - The suns height using polar coordinates. + The suns height using polar coordinates. </member> <member name="sun_longitude" type="float" setter="set_sun_longitude" getter="get_sun_longitude"> The direction of the sun using polar coordinates. diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml index 4121790881..589f7d00c6 100644 --- a/doc/classes/Quat.xml +++ b/doc/classes/Quat.xml @@ -19,45 +19,45 @@ <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="x" type="float"> - </argument> - <argument index="1" name="y" type="float"> - </argument> - <argument index="2" name="z" type="float"> - </argument> - <argument index="3" name="w" type="float"> + <argument index="0" name="from" type="Basis"> </argument> <description> - Returns a quaternion defined by these values. + Returns the rotation matrix corresponding to the given quaternion. </description> </method> <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="axis" type="Vector3"> - </argument> - <argument index="1" name="angle" type="float"> + <argument index="0" name="euler" type="Vector3"> </argument> <description> - Returns a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector. + Returns a quaternion that will perform a rotation specified by Euler angles (in the YXZ convention: first Z, then X, and Y last), given in the vector format as (X-angle, Y-angle, Z-angle). </description> </method> <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="euler" type="Vector3"> + <argument index="0" name="axis" type="Vector3"> + </argument> + <argument index="1" name="angle" type="float"> </argument> <description> - Returns a quaternion that will perform a rotation specified by Euler angles (in the YXZ convention: first Z, then X, and Y last), given in the vector format as (X-angle, Y-angle, Z-angle). + Returns a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector. </description> </method> <method name="Quat"> <return type="Quat"> </return> - <argument index="0" name="from" type="Basis"> + <argument index="0" name="x" type="float"> + </argument> + <argument index="1" name="y" type="float"> + </argument> + <argument index="2" name="z" type="float"> + </argument> + <argument index="3" name="w" type="float"> </argument> <description> - Returns the rotation matrix corresponding to the given quaternion. + Returns a quaternion defined by these values. </description> </method> <method name="cubic_slerp"> @@ -129,7 +129,7 @@ <method name="set_axis_angle"> <argument index="0" name="axis" type="Vector3"> </argument> - <argument index="1" name="phi" type="float"> + <argument index="1" name="angle" type="float"> </argument> <description> Set the quaternion to a rotation which rotates around axis by the specified angle, in radians. The axis must be a normalized vector. diff --git a/doc/classes/Range.xml b/doc/classes/Range.xml index 545f5cc83b..fa7e20eff6 100644 --- a/doc/classes/Range.xml +++ b/doc/classes/Range.xml @@ -29,6 +29,10 @@ </method> </methods> <members> + <member name="allow_greater" type="bool" setter="set_allow_greater" getter="is_greater_allowed"> + </member> + <member name="allow_lesser" type="bool" setter="set_allow_lesser" getter="is_lesser_allowed"> + </member> <member name="exp_edit" type="bool" setter="set_exp_ratio" getter="is_ratio_exp"> If [code]true[/code] and [code]min_value[/code] is greater than 0, [code]value[/code] will be represented exponentially rather than linearly. </member> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index 55063bbe24..b2cde861c8 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -34,7 +34,7 @@ <argument index="2" name="method" type="String"> </argument> <description> - Calls [code]method[/code] on each member of the given group, respecting the given [enum GROUP_CALL] flags. + Calls [code]method[/code] on each member of the given group, respecting the given [enum GroupCallFlags]. </description> </method> <method name="change_scene"> @@ -160,7 +160,7 @@ <argument index="2" name="notification" type="int"> </argument> <description> - Sends the given notification to all members of the [code]group[/code], respecting the given [enum GROUP_CALL] flags. + Sends the given notification to all members of the [code]group[/code], respecting the given [enum GroupCallFlags]. </description> </method> <method name="queue_delete"> @@ -220,7 +220,7 @@ <argument index="3" name="value" type="Variant"> </argument> <description> - Sets the given [code]property[/code] to [code]value[/code] on all members of the given group, respecting the given [enum GROUP_CALL] flags. + Sets the given [code]property[/code] to [code]value[/code] on all members of the given group, respecting the given [enum GroupCallFlags]. </description> </method> <method name="set_input_as_handled"> diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml index f16b3920c2..3a99a203ae 100644 --- a/doc/classes/ScrollContainer.xml +++ b/doc/classes/ScrollContainer.xml @@ -42,4 +42,8 @@ </signals> <constants> </constants> + <theme_items> + <theme_item name="bg" type="StyleBox"> + </theme_item> + </theme_items> </class> diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml index 058e00e46c..5abba9fba9 100644 --- a/doc/classes/ShaderMaterial.xml +++ b/doc/classes/ShaderMaterial.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ShaderMaterial" inherits="Material" category="Core" version="3.1"> <brief_description> - A material that uses a custom [Shader] program + A material that uses a custom [Shader] program. </brief_description> <description> A material that uses a custom [Shader] program to render either items to screen or process particles. You can create multiple materials for the same shader but configure different values for the uniforms defined in the shader. @@ -17,7 +17,7 @@ <argument index="0" name="param" type="String"> </argument> <description> - Returns the current value set for this material of a uniform in the shader + Returns the current value set for this material of a uniform in the shader. </description> </method> <method name="set_shader_param"> @@ -28,13 +28,13 @@ <argument index="1" name="value" type="Variant"> </argument> <description> - Changes the value set for this material of a uniform in the shader + Changes the value set for this material of a uniform in the shader. </description> </method> </methods> <members> <member name="shader" type="Shader" setter="set_shader" getter="get_shader"> - The [Shader] program used to render this material + The [Shader] program used to render this material. </member> </members> <constants> diff --git a/doc/classes/Skeleton.xml b/doc/classes/Skeleton.xml index 67e10e8f0a..0f96ee01ff 100644 --- a/doc/classes/Skeleton.xml +++ b/doc/classes/Skeleton.xml @@ -147,14 +147,20 @@ <description> </description> </method> - <method name="physical_bones_simulation"> + <method name="physical_bones_start_simulation"> <return type="void"> </return> - <argument index="0" name="start" type="bool"> + <argument index="0" name="bones" type="Array" default="[ ]"> </argument> <description> </description> </method> + <method name="physical_bones_stop_simulation"> + <return type="void"> + </return> + <description> + </description> + </method> <method name="set_bone_custom_pose"> <return type="void"> </return> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index a55e184474..0ba1066dfd 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -643,6 +643,20 @@ Returns the right side of the string from a given position. </description> </method> + <method name="rsplit"> + <return type="PoolStringArray"> + </return> + <argument index="0" name="divisor" type="String"> + </argument> + <argument index="1" name="allow_empty" type="bool" default="True"> + </argument> + <argument index="2" name="maxsplit" type="int" default="0"> + </argument> + <description> + Splits the string by a [code]divisor[/code] string and returns an array of the substrings, starting from right. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". + If [code]maxsplit[/code] is specified, then it is number of splits to do, default is 0 which splits all the items. + </description> + </method> <method name="rstrip"> <return type="String"> </return> @@ -688,20 +702,6 @@ If [code]maxsplit[/code] is given, at most maxsplit number of splits occur, and the remainder of the string is returned as the final element of the list (thus, the list will have at most maxsplit+1 elements) </description> </method> - <method name="rsplit"> - <return type="PoolStringArray"> - </return> - <argument index="0" name="divisor" type="String"> - </argument> - <argument index="1" name="allow_empty" type="bool" default="True"> - </argument> - <argument index="2" name="maxsplit" type="int" default="0"> - </argument> - <description> - Splits the string by a [code]divisor[/code] string and returns an array of the substrings, starting from right. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". - If [code]maxsplit[/code] is specified, then it is number of splits to do, default is 0 which splits all the items. - </description> - </method> <method name="split_floats"> <return type="PoolRealArray"> </return> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 11fc00d129..ee9b7383e5 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -386,7 +386,7 @@ <member name="v_scroll_speed" type="float" setter="set_v_scroll_speed" getter="get_v_scroll_speed"> If [code]true[/code], enables text wrapping when it goes beyond he edge of what is visible. </member> - <member name="wrap_lines" type="bool" setter="set_wrap" getter="is_wrapping"> + <member name="wrap_enabled" type="bool" setter="set_wrap_enabled" getter="is_wrap_enabled"> </member> </members> <signals> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 775fef4fb7..5af29d96cd 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -52,7 +52,7 @@ <argument index="0" name="bit" type="int"> </argument> <description> - Returns [code]true[/code] if the given collision layer bit is set. + Returns [code]true[/code] if the given collision layer bit is set. </description> </method> <method name="get_collision_mask_bit" qualifiers="const"> @@ -61,7 +61,7 @@ <argument index="0" name="bit" type="int"> </argument> <description> - Returns [code]true[/code] if the given collision mask bit is set. + Returns [code]true[/code] if the given collision mask bit is set. </description> </method> <method name="get_used_cells" qualifiers="const"> @@ -77,14 +77,14 @@ <argument index="0" name="id" type="int"> </argument> <description> - Returns an array of all cells with the given tile id. + Returns an array of all cells with the given tile id. </description> </method> <method name="get_used_rect"> <return type="Rect2"> </return> <description> - Returns a rectangle enclosing the used (non-empty) tiles of the map. + Returns a rectangle enclosing the used (non-empty) tiles of the map. </description> </method> <method name="is_cell_transposed" qualifiers="const"> @@ -128,7 +128,7 @@ <argument index="1" name="ignore_half_ofs" type="bool" default="false"> </argument> <description> - Returns the global position corresponding to the given tilemap (grid-based) coordinates. + Returns the global position corresponding to the given tilemap (grid-based) coordinates. Optionally, the tilemap's half offset can be ignored. </description> </method> @@ -193,7 +193,7 @@ <argument index="1" name="value" type="bool"> </argument> <description> - Sets the given collision mask bit. + Sets the given collision mask bit. </description> </method> <method name="update_bitmask_area"> @@ -223,7 +223,7 @@ <argument index="0" name="world_position" type="Vector2"> </argument> <description> - Returns the tilemap (grid-based) coordinatescorresponding to the given global position. + Returns the tilemap (grid-based) coordinatescorresponding to the given global position. </description> </method> </methods> diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 8f7969505e..bdf8634a6c 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -450,7 +450,9 @@ <constants> <constant name="BITMASK_2X2" value="0" enum="BitmaskMode"> </constant> - <constant name="BITMASK_3X3" value="1" enum="BitmaskMode"> + <constant name="BITMASK_3X3_MINIMAL" value="1" enum="BitmaskMode"> + </constant> + <constant name="BITMASK_3X3" value="2" enum="BitmaskMode"> </constant> <constant name="BIND_TOPLEFT" value="1" enum="AutotileBindings"> </constant> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index e3fbaff62d..923be94db9 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -34,7 +34,7 @@ <return type="float"> </return> <description> - Returns the vector's angle in radians with respect to the x-axis, or [code](1, 0)[/code] vector. + Returns the vector's angle in radians with respect to the x-axis, or [code](1, 0)[/code] vector. Equivalent to the result of atan2 when called with the vector's x and y as parameters: [code]atan2(x, y)[/code]. </description> </method> @@ -190,7 +190,7 @@ <argument index="0" name="n" type="Vector2"> </argument> <description> - Returns the vector reflected from a plane defined by the given normal. + Returns the vector reflected from a plane defined by the given normal. </description> </method> <method name="rotated"> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 84c16c9fc5..edd0965b64 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -151,7 +151,7 @@ <argument index="1" name="t" type="float"> </argument> <description> - Returns the result of the linear interpolation between this vector and [code]b[/code] by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], a percentage of how far along the interpolation is. + Returns the result of the linear interpolation between this vector and [code]b[/code] by amount [code]t[/code]. [code]t[/code] is in the range of [code]0.0 - 1.0[/code], a percentage of how far along the interpolation is. </description> </method> <method name="max_axis"> diff --git a/editor/SCsub b/editor/SCsub index 4ca6b9e3fd..c29da8dd8a 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -7,7 +7,6 @@ import os import os.path from compat import encode_utf8, byte_to_str, open_utf8, escape_string - def make_certs_header(target, source, env): src = source[0].srcnode().abspath @@ -147,268 +146,6 @@ def make_translations_header(target, source, env): g.close() - -def make_authors_header(target, source, env): - - sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"] - sections_id = ["dev_founders", "dev_lead", "dev_manager", "dev_names"] - - src = source[0].srcnode().abspath - dst = target[0].srcnode().abspath - f = open_utf8(src, "r") - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_AUTHORS_H\n") - g.write("#define _EDITOR_AUTHORS_H\n") - - current_section = "" - reading = False - - def close_section(): - g.write("\t0\n") - g.write("};\n") - - for line in f: - if reading: - if line.startswith(" "): - g.write("\t\"" + escape_string(line.strip()) + "\",\n") - continue - if line.startswith("## "): - if reading: - close_section() - reading = False - for i in range(len(sections)): - if line.strip().endswith(sections[i]): - current_section = escape_string(sections_id[i]) - reading = True - g.write("static const char *" + current_section + "[] = {\n") - break - - if reading: - close_section() - - g.write("#endif\n") - - g.close() - f.close() - -def make_donors_header(target, source, env): - - sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"] - sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"] - - src = source[0].srcnode().abspath - dst = target[0].srcnode().abspath - f = open_utf8(src, "r") - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_DONORS_H\n") - g.write("#define _EDITOR_DONORS_H\n") - - current_section = "" - reading = False - - def close_section(): - g.write("\t0\n") - g.write("};\n") - - for line in f: - if reading >= 0: - if line.startswith(" "): - g.write("\t\"" + escape_string(line.strip()) + "\",\n") - continue - if line.startswith("## "): - if reading: - close_section() - reading = False - for i in range(len(sections)): - if line.strip().endswith(sections[i]): - current_section = escape_string(sections_id[i]) - reading = True - g.write("static const char *" + current_section + "[] = {\n") - break - - if reading: - close_section() - - g.write("#endif\n") - - g.close() - f.close() - - -def make_license_header(target, source, env): - - src_copyright = source[0].srcnode().abspath - src_license = source[1].srcnode().abspath - dst = target[0].srcnode().abspath - f = open_utf8(src_license, "r") - fc = open_utf8(src_copyright, "r") - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_LICENSE_H\n") - g.write("#define _EDITOR_LICENSE_H\n") - g.write("static const char *about_license =") - - for line in f: - escaped_string = escape_string(line.strip()) - g.write("\n\t\"" + escaped_string + "\\n\"") - - g.write(";\n") - - tp_current = 0 - tp_file = "" - tp_comment = "" - tp_copyright = "" - tp_license = "" - - tp_licensename = "" - tp_licensebody = "" - - tp = [] - tp_licensetext = [] - for line in fc: - if line.startswith("#"): - continue - - if line.startswith("Files:"): - tp_file = line[6:].strip() - tp_current = 1 - elif line.startswith("Comment:"): - tp_comment = line[8:].strip() - tp_current = 2 - elif line.startswith("Copyright:"): - tp_copyright = line[10:].strip() - tp_current = 3 - elif line.startswith("License:"): - if tp_current != 0: - tp_license = line[8:].strip() - tp_current = 4 - else: - tp_licensename = line[8:].strip() - tp_current = 5 - elif line.startswith(" "): - if tp_current == 1: - tp_file += "\n" + line.strip() - elif tp_current == 3: - tp_copyright += "\n" + line.strip() - elif tp_current == 5: - if line.strip() == ".": - tp_licensebody += "\n" - else: - tp_licensebody += line[1:] - else: - if tp_current != 0: - if tp_current == 5: - tp_licensetext.append([tp_licensename, tp_licensebody]) - - tp_licensename = "" - tp_licensebody = "" - else: - added = False - for i in tp: - if i[0] == tp_comment: - i[1].append([tp_file, tp_copyright, tp_license]) - added = True - break - if not added: - tp.append([tp_comment,[[tp_file, tp_copyright, tp_license]]]) - - tp_file = [] - tp_comment = "" - tp_copyright = [] - tp_license = "" - tp_current = 0 - - tp_licensetext.append([tp_licensename, tp_licensebody]) - - about_thirdparty = "" - about_tp_copyright_count = "" - about_tp_license = "" - about_tp_copyright = "" - about_tp_file = "" - - for i in tp: - about_thirdparty += "\t\"" + i[0] + "\",\n" - about_tp_copyright_count += str(len(i[1])) + ", " - for j in i[1]: - file_body = "" - copyright_body = "" - for k in j[0].split("\n"): - if file_body != "": - file_body += "\\n\"\n" - escaped_string = escape_string(k.strip()) - file_body += "\t\"" + escaped_string - for k in j[1].split("\n"): - if copyright_body != "": - copyright_body += "\\n\"\n" - escaped_string = escape_string(k.strip()) - copyright_body += "\t\"" + escaped_string - - about_tp_file += "\t" + file_body + "\",\n" - about_tp_copyright += "\t" + copyright_body + "\",\n" - about_tp_license += "\t\"" + j[2] + "\",\n" - - about_license_name = "" - about_license_body = "" - - for i in tp_licensetext: - body = "" - for j in i[1].split("\n"): - if body != "": - body += "\\n\"\n" - escaped_string = escape_string(j.strip()) - body += "\t\"" + escaped_string - - about_license_name += "\t\"" + i[0] + "\",\n" - about_license_body += "\t" + body + "\",\n" - - g.write("static const char *about_thirdparty[] = {\n") - g.write(about_thirdparty) - g.write("\t0\n") - g.write("};\n") - g.write("#define THIRDPARTY_COUNT " + str(len(tp)) + "\n") - - g.write("static const int about_tp_copyright_count[] = {\n\t") - g.write(about_tp_copyright_count) - g.write("0\n};\n") - - g.write("static const char *about_tp_file[] = {\n") - g.write(about_tp_file) - g.write("\t0\n") - g.write("};\n") - - g.write("static const char *about_tp_copyright[] = {\n") - g.write(about_tp_copyright) - g.write("\t0\n") - g.write("};\n") - - g.write("static const char *about_tp_license[] = {\n") - g.write(about_tp_license) - g.write("\t0\n") - g.write("};\n") - - g.write("static const char *about_license_name[] = {\n") - g.write(about_license_name) - g.write("\t0\n") - g.write("};\n") - g.write("#define LICENSE_COUNT " + str(len(tp_licensetext)) + "\n") - - g.write("static const char *about_license_body[] = {\n") - g.write(about_license_body) - g.write("\t0\n") - g.write("};\n") - - g.write("#endif\n") - - g.close() - fc.close() - f.close() - - def _make_doc_data_class_path(to_path): g = open_utf8(os.path.join(to_path,"doc_data_class_path.gen.h"), "w") g.write("static const int _doc_data_class_path_count = " + str(len(env.doc_class_path)) + ";\n") @@ -474,19 +211,6 @@ if env['tools']: env.Depends('#editor/builtin_fonts.gen.h', flist) env.Command('#editor/builtin_fonts.gen.h', flist, make_fonts_header) - # Authors - env.Depends('#editor/authors.gen.h', "../AUTHORS.md") - env.Command('#editor/authors.gen.h', "../AUTHORS.md", make_authors_header) - - # Donors - env.Depends('#editor/donors.gen.h', "../DONORS.md") - env.Command('#editor/donors.gen.h', "../DONORS.md", make_donors_header) - - # License - env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]) - env.Command('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], make_license_header) - - env.add_source_files(env.editor_sources, "*.cpp") env.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"]) diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 360ed620f6..11adcd4661 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -31,11 +31,11 @@ #include "editor_about.h" #include "editor_node.h" -#include "authors.gen.h" -#include "donors.gen.h" -#include "license.gen.h" -#include "version.h" -#include "version_hash.gen.h" +#include "core/authors.gen.h" +#include "core/donors.gen.h" +#include "core/license.gen.h" +#include "core/version.h" +#include "core/version_hash.gen.h" void EditorAbout::_notification(int p_what) { @@ -69,7 +69,7 @@ TextureRect *EditorAbout::get_logo() const { return _logo; } -ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[], const int p_flag_single_column) { +ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<String> &p_sections, const char *const *const p_src[], const int p_flag_single_column) { ScrollContainer *sc = memnew(ScrollContainer); sc->set_name(p_name); @@ -82,7 +82,7 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St for (int i = 0; i < p_sections.size(); i++) { bool single_column = p_flag_single_column & 1 << i; - const char **names_ptr = p_src[i]; + const char *const *names_ptr = p_src[i]; if (*names_ptr) { Label *lbl = memnew(Label); @@ -151,7 +151,8 @@ EditorAbout::EditorAbout() { dev_sections.push_back(TTR("Lead Developer")); dev_sections.push_back(TTR("Project Manager ")); // " " appended to distinguish between 'project supervisor' and 'project list' dev_sections.push_back(TTR("Developers")); - const char **dev_src[] = { dev_founders, dev_lead, dev_manager, dev_names }; + const char *const *dev_src[] = { AUTHORS_FOUNDERS, AUTHORS_LEAD_DEVELOPERS, + AUTHORS_PROJECT_MANAGERS, AUTHORS_DEVELOPERS }; tc->add_child(_populate_list(TTR("Authors"), dev_sections, dev_src, 1)); // Donors @@ -163,7 +164,8 @@ EditorAbout::EditorAbout() { donor_sections.push_back(TTR("Gold Donors")); donor_sections.push_back(TTR("Silver Donors")); donor_sections.push_back(TTR("Bronze Donors")); - const char **donor_src[] = { donor_s_plat, donor_s_gold, donor_s_mini, donor_gold, donor_silver, donor_bronze }; + const char *const *donor_src[] = { DONORS_SPONSOR_PLAT, DONORS_SPONSOR_GOLD, + DONORS_SPONSOR_MINI, DONORS_GOLD, DONORS_SILVER, DONORS_BRONZE }; tc->add_child(_populate_list(TTR("Donors"), donor_sections, donor_src, 3)); // License @@ -172,7 +174,7 @@ EditorAbout::EditorAbout() { _license_text->set_name(TTR("License")); _license_text->set_h_size_flags(Control::SIZE_EXPAND_FILL); _license_text->set_v_size_flags(Control::SIZE_EXPAND_FILL); - _license_text->set_text(String::utf8(about_license)); + _license_text->set_text(String::utf8(GODOT_LICENSE_TEXT)); tc->add_child(_license_text); // Thirdparty License @@ -207,20 +209,27 @@ EditorAbout::EditorAbout() { tpl_ti_lc->set_selectable(0, false); int read_idx = 0; String long_text = ""; - for (int i = 0; i < THIRDPARTY_COUNT; i++) { + for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) { + const ComponentCopyright &component = COPYRIGHT_INFO[component_index]; TreeItem *ti = _tpl_tree->create_item(tpl_ti_tp); - String thirdparty = String(about_thirdparty[i]); - ti->set_text(0, thirdparty); - String text = thirdparty + "\n"; - long_text += "- " + thirdparty + "\n\n"; - for (int j = 0; j < about_tp_copyright_count[i]; j++) { - - text += "\n Files:\n " + String(about_tp_file[read_idx]).replace("\n", "\n ") + "\n"; - String copyright = String::utf8(" \xc2\xa9 ") + String::utf8(about_tp_copyright[read_idx]).replace("\n", String::utf8("\n \xc2\xa9 ")); + String component_name = component.name; + ti->set_text(0, component_name); + String text = component_name + "\n"; + long_text += "- " + component_name + "\n"; + for (int part_index = 0; part_index < component.part_count; part_index++) { + const ComponentCopyrightPart &part = component.parts[part_index]; + text += "\n Files:"; + for (int file_num = 0; file_num < part.file_count; file_num++) { + text += "\n " + String(part.files[file_num]); + } + String copyright; + for (int copyright_index = 0; copyright_index < part.copyright_count; copyright_index++) { + copyright += String::utf8("\n \xc2\xa9 ") + String::utf8(part.copyright_statements[copyright_index]); + } text += copyright; long_text += copyright; - String license = "\n License: " + String(about_tp_license[read_idx]) + "\n"; + String license = "\n License: " + String(part.license) + "\n"; text += license; long_text += license + "\n"; read_idx++; @@ -230,10 +239,10 @@ EditorAbout::EditorAbout() { for (int i = 0; i < LICENSE_COUNT; i++) { TreeItem *ti = _tpl_tree->create_item(tpl_ti_lc); - String licensename = String(about_license_name[i]); + String licensename = String(LICENSE_NAMES[i]); ti->set_text(0, licensename); long_text += "- " + licensename + "\n\n"; - String licensebody = String(about_license_body[i]); + String licensebody = String(LICENSE_BODIES[i]); ti->set_metadata(0, licensebody); long_text += " " + licensebody.replace("\n", "\n ") + "\n\n"; } diff --git a/editor/editor_about.h b/editor/editor_about.h index b32fdf6567..71d1c95188 100644 --- a/editor/editor_about.h +++ b/editor/editor_about.h @@ -53,7 +53,7 @@ class EditorAbout : public AcceptDialog { private: void _license_tree_selected(); - ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[], const int p_flag_single_column = 0); + ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char *const *const p_src[], const int p_flag_single_column = 0); Tree *_tpl_tree; RichTextLabel *_license_text; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index f94b7cd6ee..531aa2f9dc 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -842,9 +842,11 @@ void EditorInspectorPlugin::_bind_methods() { MethodInfo vm; vm.name = "can_handle"; + vm.return_val.type = Variant::BOOL; vm.arguments.push_back(PropertyInfo(Variant::OBJECT, "object")); BIND_VMETHOD(vm); vm.name = "parse_begin"; + vm.return_val.type = Variant::NIL; BIND_VMETHOD(vm); vm.name = "parse_category"; vm.arguments.push_back(PropertyInfo(Variant::STRING, "category")); @@ -859,8 +861,8 @@ void EditorInspectorPlugin::_bind_methods() { vm.arguments.push_back(PropertyInfo(Variant::INT, "usage")); BIND_VMETHOD(vm); vm.arguments.clear(); - vm.return_val.type = Variant::NIL; vm.name = "parse_end"; + vm.return_val.type = Variant::NIL; BIND_VMETHOD(vm); } diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index ac4166bb98..d065a756b4 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -97,6 +97,7 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) { if (img.is_null() || img->empty()) return Ref<Texture>(); + img = img->duplicate(); img->clear_mipmaps(); int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); diff --git a/main/main.cpp b/main/main.cpp index ad49e1f5bd..70713e2dd8 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1706,7 +1706,7 @@ bool Main::start() { uint64_t Main::last_ticks = 0; uint64_t Main::target_ticks = 0; -Array Main::frame_times = Array(); +uint32_t Main::frames = 0; uint32_t Main::frame = 0; bool Main::force_redraw_requested = false; @@ -1825,19 +1825,10 @@ bool Main::iteration() { script_debugger->idle_poll(); } + frames++; Engine::get_singleton()->_idle_frames++; - // FPS counter - frame_times.push_back(ticks); - int frames = frame_times.size(); - - while (frame_times.size() > 0 && (int)frame_times.get(0) <= ticks - 1000000) { - frame_times.pop_front(); - } - - int update_frequency = MAX(1, (int)GLOBAL_GET("debug/settings/performance/update_frequency_msec")); - - if (frame > update_frequency * 1000) { + if (frame > 1000000) { if (editor || project_manager) { if (print_fps) { @@ -1853,7 +1844,8 @@ bool Main::iteration() { idle_process_max = 0; physics_process_max = 0; - frame %= update_frequency * 1000; + frame %= 1000000; + frames = 0; } if (fixed_fps != -1) diff --git a/main/main.h b/main/main.h index 8f264d7720..c20592bf3b 100644 --- a/main/main.h +++ b/main/main.h @@ -44,7 +44,7 @@ class Main { static void print_help(const char *p_binary); static uint64_t last_ticks; static uint64_t target_ticks; - static Array frame_times; + static uint32_t frames; static uint32_t frame; static bool force_redraw_requested; diff --git a/methods.py b/methods.py index 7cdc160075..6dca826b2b 100644 --- a/methods.py +++ b/methods.py @@ -1,5 +1,5 @@ import os -from compat import iteritems +from compat import iteritems, itervalues, open_utf8, escape_string def add_source_files(self, sources, filetype, lib_env=None, shared=False): @@ -515,6 +515,232 @@ def build_gles2_headers(target, source, env): for x in source: build_legacygl_header(str(x), include="drivers/gles2/shader_gles2.h", class_suffix="GLES2", output_attribs=True, gles2=True) +def make_authors_header(target, source, env): + + sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"] + sections_id = ["AUTHORS_FOUNDERS", "AUTHORS_LEAD_DEVELOPERS", "AUTHORS_PROJECT_MANAGERS", "AUTHORS_DEVELOPERS"] + + src = source[0].srcnode().abspath + dst = target[0].srcnode().abspath + f = open_utf8(src, "r") + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_AUTHORS_H\n") + g.write("#define _EDITOR_AUTHORS_H\n") + + current_section = "" + reading = False + + def close_section(): + g.write("\t0\n") + g.write("};\n") + + for line in f: + if reading: + if line.startswith(" "): + g.write("\t\"" + escape_string(line.strip()) + "\",\n") + continue + if line.startswith("## "): + if reading: + close_section() + reading = False + for i in range(len(sections)): + if line.strip().endswith(sections[i]): + current_section = escape_string(sections_id[i]) + reading = True + g.write("const char *const " + current_section + "[] = {\n") + break + + if reading: + close_section() + + g.write("#endif\n") + + g.close() + f.close() + +def make_donors_header(target, source, env): + + sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", + "Gold donors", "Silver donors", "Bronze donors"] + sections_id = ["DONORS_SPONSOR_PLAT", "DONORS_SPONSOR_GOLD", "DONORS_SPONSOR_MINI", + "DONORS_GOLD", "DONORS_SILVER", "DONORS_BRONZE"] + + src = source[0].srcnode().abspath + dst = target[0].srcnode().abspath + f = open_utf8(src, "r") + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_DONORS_H\n") + g.write("#define _EDITOR_DONORS_H\n") + + current_section = "" + reading = False + + def close_section(): + g.write("\t0\n") + g.write("};\n") + + for line in f: + if reading >= 0: + if line.startswith(" "): + g.write("\t\"" + escape_string(line.strip()) + "\",\n") + continue + if line.startswith("## "): + if reading: + close_section() + reading = False + for i in range(len(sections)): + if line.strip().endswith(sections[i]): + current_section = escape_string(sections_id[i]) + reading = True + g.write("const char *const " + current_section + "[] = {\n") + break + + if reading: + close_section() + + g.write("#endif\n") + + g.close() + f.close() + + +def make_license_header(target, source, env): + src_copyright = source[0].srcnode().abspath + src_license = source[1].srcnode().abspath + dst = target[0].srcnode().abspath + + class LicenseReader: + def __init__(self, license_file): + self._license_file = license_file + self.line_num = 0 + self.current = self.next_line() + + def next_line(self): + line = self._license_file.readline() + self.line_num += 1 + while line.startswith("#"): + line = self._license_file.readline() + self.line_num += 1 + self.current = line + return line + + def next_tag(self): + if not ':' in self.current: + return ('',[]) + tag, line = self.current.split(":", 1) + lines = [line.strip()] + while self.next_line() and self.current.startswith(" "): + lines.append(self.current.strip()) + return (tag, lines) + + from collections import OrderedDict + projects = OrderedDict() + license_list = [] + + with open_utf8(src_copyright, "r") as copyright_file: + reader = LicenseReader(copyright_file) + part = {} + while reader.current: + tag, content = reader.next_tag() + if tag in ("Files", "Copyright", "License"): + part[tag] = content[:] + elif tag == "Comment": + # attach part to named project + projects[content[0]] = projects.get(content[0], []) + [part] + + if not tag or not reader.current: + # end of a paragraph start a new part + if "License" in part and not "Files" in part: + # no Files tag in this one, so assume standalone license + license_list.append(part["License"]) + part = {} + reader.next_line() + + data_list = [] + for project in itervalues(projects): + for part in project: + part["file_index"] = len(data_list) + data_list += part["Files"] + part["copyright_index"] = len(data_list) + data_list += part["Copyright"] + + with open_utf8(dst, "w") as f: + + f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + f.write("#ifndef _EDITOR_LICENSE_H\n") + f.write("#define _EDITOR_LICENSE_H\n") + f.write("const char *const GODOT_LICENSE_TEXT =") + + with open_utf8(src_license, "r") as license_file: + for line in license_file: + escaped_string = escape_string(line.strip()) + f.write("\n\t\t\"" + escaped_string + "\\n\"") + f.write(";\n\n") + + f.write("struct ComponentCopyrightPart {\n" + "\tconst char *license;\n" + "\tconst char *const *files;\n" + "\tconst char *const *copyright_statements;\n" + "\tint file_count;\n" + "\tint copyright_count;\n" + "};\n\n") + + f.write("struct ComponentCopyright {\n" + "\tconst char *name;\n" + "\tconst ComponentCopyrightPart *parts;\n" + "\tint part_count;\n" + "};\n\n") + + f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n") + for line in data_list: + f.write("\t\"" + escape_string(line) + "\",\n") + f.write("};\n\n") + + f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n") + part_index = 0 + part_indexes = {} + for project_name, project in iteritems(projects): + part_indexes[project_name] = part_index + for part in project: + f.write("\t{ \"" + escape_string(part["License"][0]) + "\", " + + "©RIGHT_INFO_DATA[" + str(part["file_index"]) + "], " + + "©RIGHT_INFO_DATA[" + str(part["copyright_index"]) + "], " + + str(len(part["Files"])) + ", " + + str(len(part["Copyright"])) + " },\n") + part_index += 1 + f.write("};\n\n") + + f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n") + + f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n") + for project_name, project in iteritems(projects): + f.write("\t{ \"" + escape_string(project_name) + "\", " + + "©RIGHT_PROJECT_PARTS[" + str(part_indexes[project_name]) + "], " + + str(len(project)) + " },\n") + f.write("};\n\n") + + f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n") + + f.write("const char *const LICENSE_NAMES[] = {\n") + for l in license_list: + f.write("\t\"" + escape_string(l[0]) + "\",\n") + f.write("};\n\n") + + f.write("const char *const LICENSE_BODIES[] = {\n\n") + for l in license_list: + for line in l[1:]: + if line == ".": + f.write("\t\"\\n\"\n") + else: + f.write("\t\"" + escape_string(line) + "\\n\"\n") + f.write("\t\"\",\n\n") + f.write("};\n\n") + + f.write("#endif\n") def add_module_version_string(self,s): self.module_version_string += "." + s diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 3a1f5d78dd..971fd39509 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -841,20 +841,19 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f } #endif - btTransform body_safe_position; - G_TO_B(p_from, body_safe_position); - UNSCALE_BT_BASIS(body_safe_position); + btTransform body_transform; + G_TO_B(p_from, body_transform); + UNSCALE_BT_BASIS(body_transform); - btVector3 recover_initial_position(0, 0, 0); + btVector3 initial_recover_motion(0, 0, 0); { /// Phase one - multi shapes depenetration using margin for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - if (!recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, recover_initial_position)) { + if (!recover_from_penetration(p_body, body_transform, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, initial_recover_motion)) { break; } } - // Add recover movement in order to make it safe - body_safe_position.getOrigin() += recover_initial_position; + body_transform.getOrigin() += initial_recover_motion; } btVector3 motion; @@ -885,7 +884,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f } btConvexShape *convex_shape_test(static_cast<btConvexShape *>(p_body->get_bt_shape(shIndex))); - btTransform shape_world_from = body_safe_position * p_body->get_kinematic_utilities()->shapes[shIndex].transform; + btTransform shape_world_from = body_transform * p_body->get_kinematic_utilities()->shapes[shIndex].transform; btTransform shape_world_to(shape_world_from); shape_world_to.getOrigin() += motion; @@ -903,62 +902,49 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f } } - body_safe_position.getOrigin() += motion; + body_transform.getOrigin() += motion; } bool has_penetration = false; - { /// Phase three - Recover + contact test with margin + { /// Phase three - contact test with margin - btVector3 delta_recover_movement(0, 0, 0); + btVector3 __rec(0, 0, 0); RecoverResult r_recover_result; - bool l_has_penetration; - real_t l_penetration_distance = 1e20; - for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { - l_has_penetration = recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, delta_recover_movement, &r_recover_result); + has_penetration = recover_from_penetration(p_body, body_transform, 0, p_infinite_inertia, __rec, &r_recover_result); - if (r_result) { - B_TO_G(motion + delta_recover_movement + recover_initial_position, r_result->motion); + // Parse results + if (r_result) { + B_TO_G(motion + initial_recover_motion, r_result->motion); - if (l_has_penetration) { - has_penetration = true; - if (l_penetration_distance <= r_recover_result.penetration_distance) { - continue; - } + if (has_penetration) { - l_penetration_distance = r_recover_result.penetration_distance; + const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object); + CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer()); - const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object); - CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer()); + B_TO_G(motion, r_result->remainder); // is the remaining movements + r_result->remainder = p_motion - r_result->remainder; - B_TO_G(motion, r_result->remainder); // is the remaining movements - r_result->remainder = p_motion - r_result->remainder; - B_TO_G(r_recover_result.pointWorld, r_result->collision_point); - B_TO_G(r_recover_result.normal, r_result->collision_normal); - B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot - r_result->collider = collisionObject->get_self(); - r_result->collider_id = collisionObject->get_instance_id(); - r_result->collider_shape = r_recover_result.other_compound_shape_index; - r_result->collision_local_shape = r_recover_result.local_shape_most_recovered; + B_TO_G(r_recover_result.pointWorld, r_result->collision_point); + B_TO_G(r_recover_result.normal, r_result->collision_normal); + B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot + r_result->collider = collisionObject->get_self(); + r_result->collider_id = collisionObject->get_instance_id(); + r_result->collider_shape = r_recover_result.other_compound_shape_index; + r_result->collision_local_shape = r_recover_result.local_shape_most_recovered; #if debug_test_motion - Vector3 sup_line2; - B_TO_G(motion, sup_line2); - normalLine->clear(); - normalLine->begin(Mesh::PRIMITIVE_LINES, NULL); - normalLine->add_vertex(r_result->collision_point); - normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10); - normalLine->end(); + Vector3 sup_line2; + B_TO_G(motion, sup_line2); + normalLine->clear(); + normalLine->begin(Mesh::PRIMITIVE_LINES, NULL); + normalLine->add_vertex(r_result->collision_point); + normalLine->add_vertex(r_result->collision_point + r_result->collision_normal * 10); + normalLine->end(); #endif - } else { - r_result->remainder = Vector3(); - } } else { - if (!l_has_penetration) - break; - else - has_penetration = true; + r_result->remainder = Vector3(); } } } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e7b0700e76..5e93b377d2 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -716,6 +716,14 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s expr = constant; bfn = true; } + + if (!bfn && GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) { + //check from singletons + ConstantNode *constant = alloc_node<ConstantNode>(); + constant->value = GDScriptLanguage::get_singleton()->get_named_globals_map()[identifier]; + expr = constant; + bfn = true; + } } if (!bfn) { diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index d062d56dcf..9d3bee2176 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -33,9 +33,10 @@ #include <mono/metadata/mono-debug.h> #include <mono/metadata/tokentype.h> -#include "list.h" -#include "os/file_access.h" -#include "os/os.h" +#include "core/list.h" +#include "core/os/file_access.h" +#include "core/os/os.h" +#include "core/project_settings.h" #include "../godotsharp_dirs.h" #include "gd_mono_class.h" @@ -210,7 +211,7 @@ Error GDMonoAssembly::load(bool p_refonly) { Vector<uint8_t> data = FileAccess::get_file_as_array(path); ERR_FAIL_COND_V(data.empty(), ERR_FILE_CANT_READ); - String image_filename(path); + String image_filename = ProjectSettings::get_singleton()->globalize_path(path); MonoImageOpenStatus status = MONO_IMAGE_OK; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 6fe137a386..9e6377f4fe 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1023,7 +1023,7 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "apk"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,65535,1"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name"), "org.godotengine.$genname")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name"), "")); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 5589f93a5d..a49ae1a2f3 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1546,7 +1546,9 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c image = texture->get_data(); - NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc] + ERR_FAIL_COND(!image.is_valid()); + + NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:int(texture_size.width) pixelsHigh:int(texture_size.height) @@ -1556,7 +1558,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:int(texture_size.width) * 4 - bitsPerPixel:32] autorelease]; + bitsPerPixel:32]; ERR_FAIL_COND(imgrep == nil); uint8_t *pixels = [imgrep bitmapData]; @@ -1588,16 +1590,20 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c image->unlock(); - NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)] autorelease]; + NSImage *nsimage = [[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)]; [nsimage addRepresentation:imgrep]; NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)]; + [cursors[p_shape] release]; cursors[p_shape] = cursor; if (p_shape == CURSOR_ARROW) { [cursor set]; } + + [imgrep release]; + [nsimage release]; } else { // Reset to default system cursor cursors[p_shape] = NULL; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 8d664b5832..aef1b8a595 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2077,11 +2077,13 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap image = texture->get_data(); + ERR_FAIL_COND(!image.is_valid()); + UINT image_size = texture_size.width * texture_size.height; UINT size = sizeof(UINT) * image_size; // Create the BITMAP with alpha channel - COLORREF *buffer = (COLORREF *)malloc(sizeof(COLORREF) * image_size); + COLORREF *buffer = (COLORREF *)memalloc(sizeof(COLORREF) * image_size); image->lock(); for (UINT index = 0; index < image_size; index++) { @@ -2108,6 +2110,8 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap GetMaskBitmaps(bitmap, clrTransparent, hAndMask, hXorMask); if (NULL == hAndMask || NULL == hXorMask) { + memfree(buffer); + DeleteObject(bitmap); return; } @@ -2132,6 +2136,9 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap if (hXorMask != NULL) { DeleteObject(hXorMask); } + + memfree(buffer); + DeleteObject(bitmap); } else { // Reset to default system cursor cursors[p_shape] = NULL; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 7b514d0f90..1fa6993306 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2452,6 +2452,8 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c image = texture->get_data(); + ERR_FAIL_COND(!image.is_valid()); + // Create the cursor structure XcursorImage *cursor_image = XcursorImageCreate(texture_size.width, texture_size.height); XcursorUInt image_size = texture_size.width * texture_size.height; @@ -2463,7 +2465,7 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c cursor_image->yhot = p_hotspot.y; // allocate memory to contain the whole file - cursor_image->pixels = (XcursorPixel *)malloc(size); + cursor_image->pixels = (XcursorPixel *)memalloc(size); image->lock(); @@ -2489,6 +2491,9 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c if (p_shape == CURSOR_ARROW) { XDefineCursor(x11_display, x11_window, cursors[p_shape]); } + + memfree(cursor_image->pixels); + XcursorImageDestroy(cursor_image); } else { // Reset to default system cursor if (img[p_shape]) { diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 232855c978..d833e6a8bb 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -366,6 +366,16 @@ void Sprite3D::_draw() { final_rect.position * pixel_size, }; + + Vector2 src_tsize = Vector2(texture->get_width(), texture->get_height()); + + // Properly setup UVs for impostor textures (AtlasTexture). + Ref<AtlasTexture> atlas_tex = texture; + if (atlas_tex != NULL) { + src_tsize[0] = atlas_tex->get_atlas()->get_width(); + src_tsize[1] = atlas_tex->get_atlas()->get_height(); + } + Vector2 uvs[4] = { final_src_rect.position / tsize, (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / tsize, @@ -656,6 +666,16 @@ void AnimatedSprite3D::_draw() { final_rect.position * pixel_size, }; + + Vector2 src_tsize = Vector2(texture->get_width(), texture->get_height()); + + // Properly setup UVs for impostor textures (AtlasTexture). + Ref<AtlasTexture> atlas_tex = texture; + if (atlas_tex != NULL) { + src_tsize[0] = atlas_tex->get_atlas()->get_width(); + src_tsize[1] = atlas_tex->get_atlas()->get_height(); + } + Vector2 uvs[4] = { final_src_rect.position / tsize, (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / tsize, |