diff options
410 files changed, 12103 insertions, 8796 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 09f9f84728..85e83ff7f2 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -252,15 +252,15 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const { Set<_VCSort> vclist; - for (Map<StringName, VariantContainer>::Element *E = props.front(); E; E = E->next()) { - const VariantContainer *v = &E->get(); + for (const KeyValue<StringName, VariantContainer> &E : props) { + const VariantContainer *v = &E.value; if (v->hide_from_editor) { continue; } _VCSort vc; - vc.name = E->key(); + vc.name = E.key; vc.order = v->order; vc.type = v->variant.get_type(); if (vc.name.begins_with("input/") || vc.name.begins_with("import/") || vc.name.begins_with("export/") || vc.name.begins_with("/remap") || vc.name.begins_with("/locale") || vc.name.begins_with("/autoload")) { @@ -318,14 +318,14 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_f void ProjectSettings::_convert_to_last_version(int p_from_version) { if (p_from_version <= 3) { // Converts the actions from array to dictionary (array of events to dictionary with deadzone + events) - for (Map<StringName, ProjectSettings::VariantContainer>::Element *E = props.front(); E; E = E->next()) { - Variant value = E->get().variant; - if (String(E->key()).begins_with("input/") && value.get_type() == Variant::ARRAY) { + for (KeyValue<StringName, ProjectSettings::VariantContainer> &E : props) { + Variant value = E.value.variant; + if (String(E.key).begins_with("input/") && value.get_type() == Variant::ARRAY) { Array array = value; Dictionary action; action["deadzone"] = Variant(0.5f); action["events"] = array; - E->get().variant = action; + E.value.variant = action; } } } @@ -695,8 +695,8 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str int count = 0; - for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { - count += E->get().size(); + for (const KeyValue<String, List<String>> &E : props) { + count += E.value.size(); } if (p_custom_features != String()) { @@ -788,7 +788,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin } file->store_string("\n"); - for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { + for (const Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) { if (E != props.front()) { file->store_string("\n"); } @@ -831,19 +831,19 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust Set<_VCSort> vclist; if (p_merge_with_current) { - for (Map<StringName, VariantContainer>::Element *G = props.front(); G; G = G->next()) { - const VariantContainer *v = &G->get(); + for (const KeyValue<StringName, VariantContainer> &G : props) { + const VariantContainer *v = &G.value; if (v->hide_from_editor) { continue; } - if (p_custom.has(G->key())) { + if (p_custom.has(G.key)) { continue; } _VCSort vc; - vc.name = G->key(); //*k; + vc.name = G.key; //*k; vc.order = v->order; vc.type = v->variant.get_type(); vc.flags = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE; @@ -855,14 +855,14 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust } } - for (const Map<String, Variant>::Element *E = p_custom.front(); E; E = E->next()) { + for (const KeyValue<String, Variant> &E : p_custom) { // Lookup global prop to store in the same order - Map<StringName, VariantContainer>::Element *global_prop = props.find(E->key()); + Map<StringName, VariantContainer>::Element *global_prop = props.find(E.key); _VCSort vc; - vc.name = E->key(); + vc.name = E.key; vc.order = global_prop ? global_prop->get().order : 0xFFFFFFF; - vc.type = E->get().get_type(); + vc.type = E.value.get_type(); vc.flags = PROPERTY_USAGE_STORAGE; vclist.insert(vc); } diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 540d061eb0..f630adc39e 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -2419,12 +2419,12 @@ Error EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Arra } EngineDebugger::~EngineDebugger() { - for (Map<StringName, Callable>::Element *E = captures.front(); E; E = E->next()) { - ::EngineDebugger::unregister_message_capture(E->key()); + for (const KeyValue<StringName, Callable> &E : captures) { + ::EngineDebugger::unregister_message_capture(E.key); } captures.clear(); - for (Map<StringName, ProfilerCallable>::Element *E = profilers.front(); E; E = E->next()) { - ::EngineDebugger::unregister_profiler(E->key()); + for (const KeyValue<StringName, ProfilerCallable> &E : profilers) { + ::EngineDebugger::unregister_profiler(E.key); } profilers.clear(); } diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 721e5ae622..b2d5a8fdf1 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -613,11 +613,11 @@ void register_global_constants() { // rpc BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_DISABLED", Multiplayer::RPC_MODE_DISABLED); - BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_ANY", Multiplayer::RPC_MODE_ANY); + BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_ANY_PEER", Multiplayer::RPC_MODE_ANY_PEER); BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_AUTH", Multiplayer::RPC_MODE_AUTHORITY); BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE", Multiplayer::TRANSFER_MODE_UNRELIABLE); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_ORDERED", Multiplayer::TRANSFER_MODE_ORDERED); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE_ORDERED", Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED); BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_RELIABLE", Multiplayer::TRANSFER_MODE_RELIABLE); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp index a522b1310f..059025aa8f 100644 --- a/core/debugger/engine_debugger.cpp +++ b/core/debugger/engine_debugger.cpp @@ -123,8 +123,8 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, physics_time = USEC_TO_SEC(p_physics_ticks); physics_frame_time = p_physics_frame_time; // Notify tick to running profilers - for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) { - Profiler &p = E->get(); + for (KeyValue<StringName, Profiler> &E : profilers) { + Profiler &p = E.value; if (!p.active || !p.tick) { continue; } @@ -179,9 +179,9 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve void EngineDebugger::deinitialize() { if (singleton) { // Stop all profilers - for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) { - if (E->get().active) { - singleton->profiler_enable(E->key(), false); + for (const KeyValue<StringName, Profiler> &E : profilers) { + if (E.value.active) { + singleton->profiler_enable(E.key, false); } } diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index b0b3f11424..f7e56351b0 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -166,8 +166,8 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } else if (line.begins_with("set")) { if (line.get_slice_count(" ") == 1) { - for (Map<String, String>::Element *E = options.front(); E; E = E->next()) { - print_line("\t" + E->key() + "=" + E->value()); + for (const KeyValue<String, String> &E : options) { + print_line("\t" + E.key + "=" + E.value); } } else { @@ -249,8 +249,8 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { } print_line("Breakpoint(s): " + itos(breakpoints.size())); - for (Map<int, Set<StringName>>::Element *E = breakpoints.front(); E; E = E->next()) { - print_line("\t" + String(E->value().front()->get()) + ":" + itos(E->key())); + for (const KeyValue<int, Set<StringName>> &E : breakpoints) { + print_line("\t" + String(E.value.front()->get()) + ":" + itos(E.key)); } } else { diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index f865dfe102..032c7d55c0 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -179,8 +179,8 @@ public: if (pt - last_profile_time > 100) { last_profile_time = pt; DebuggerMarshalls::NetworkProfilerFrame frame; - for (Map<ObjectID, NodeInfo>::Element *E = multiplayer_node_data.front(); E; E = E->next()) { - frame.infos.push_back(E->get()); + for (const KeyValue<ObjectID, NodeInfo> &E : multiplayer_node_data) { + frame.infos.push_back(E.value); } multiplayer_node_data.clear(); EngineDebugger::get_singleton()->send_message("network:profile_frame", frame.serialize()); diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index a8547a0090..03b2426370 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -353,11 +353,11 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { api_dump["global_constants"] = constants; Array enums; - for (Map<String, List<Pair<String, int>>>::Element *E = enum_list.front(); E; E = E->next()) { + for (const KeyValue<String, List<Pair<String, int>>> &E : enum_list) { Dictionary d1; - d1["name"] = E->key(); + d1["name"] = E.key; Array values; - for (const Pair<String, int> &F : E->get()) { + for (const Pair<String, int> &F : E.value) { Dictionary d2; d2["name"] = F.first; d2["value"] = F.second; @@ -841,6 +841,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Array native_structures; + // AudioStream structures { Dictionary d; d["name"] = "AudioFrame"; @@ -849,6 +850,22 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { native_structures.push_back(d); } + // TextServer structures + { + Dictionary d; + d["name"] = "Glyph"; + d["format"] = "int start,int end,uint8_t count,uint8_t repeat,uint16_t flags,float x_off,float y_off,float advance,RID font_rid,int font_size,int32_t index"; + + native_structures.push_back(d); + } + { + Dictionary d; + d["name"] = "CaretInfo"; + d["format"] = "Rect2 leading_caret,Rect2 trailing_caret,TextServer::Direction leading_direction,TextServer::Direction trailing_direction"; + + native_structures.push_back(d); + } + api_dump["native_structures"] = native_structures; } diff --git a/core/extension/native_extension_manager.cpp b/core/extension/native_extension_manager.cpp index 8b7a9df4f1..4eac5249c9 100644 --- a/core/extension/native_extension_manager.cpp +++ b/core/extension/native_extension_manager.cpp @@ -84,8 +84,8 @@ bool NativeExtensionManager::is_extension_loaded(const String &p_path) const { Vector<String> NativeExtensionManager::get_loaded_extensions() const { Vector<String> ret; - for (const Map<String, Ref<NativeExtension>>::Element *E = native_extension_map.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<String, Ref<NativeExtension>> &E : native_extension_map) { + ret.push_back(E.key); } return ret; } @@ -97,16 +97,16 @@ Ref<NativeExtension> NativeExtensionManager::get_extension(const String &p_path) void NativeExtensionManager::initialize_extensions(NativeExtension::InitializationLevel p_level) { ERR_FAIL_COND(int32_t(p_level) - 1 != level); - for (Map<String, Ref<NativeExtension>>::Element *E = native_extension_map.front(); E; E = E->next()) { - E->get()->initialize_library(p_level); + for (KeyValue<String, Ref<NativeExtension>> &E : native_extension_map) { + E.value->initialize_library(p_level); } level = p_level; } void NativeExtensionManager::deinitialize_extensions(NativeExtension::InitializationLevel p_level) { ERR_FAIL_COND(int32_t(p_level) != level); - for (Map<String, Ref<NativeExtension>>::Element *E = native_extension_map.front(); E; E = E->next()) { - E->get()->deinitialize_library(p_level); + for (KeyValue<String, Ref<NativeExtension>> &E : native_extension_map) { + E.value->deinitialize_library(p_level); } level = int32_t(p_level) - 1; } diff --git a/core/input/input.cpp b/core/input/input.cpp index 9195f7d8b5..05b02408a1 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -863,9 +863,9 @@ void Input::release_pressed_events() { joy_buttons_pressed.clear(); _joy_axis.clear(); - for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) { - if (E->get().pressed) { - action_release(E->key()); + for (const KeyValue<StringName, Input::Action> &E : action_state) { + if (E.value.pressed) { + action_release(E.key); } } } @@ -1322,8 +1322,8 @@ void Input::add_joy_mapping(String p_mapping, bool p_update_existing) { if (p_update_existing) { Vector<String> entry = p_mapping.split(","); String uid = entry[0]; - for (Map<int, Joypad>::Element *E = joy_names.front(); E; E = E->next()) { - Joypad &joy = E->get(); + for (KeyValue<int, Joypad> &E : joy_names) { + Joypad &joy = E.value; if (joy.uid == uid) { joy.mapping = map_db.size() - 1; } @@ -1337,8 +1337,8 @@ void Input::remove_joy_mapping(String p_guid) { map_db.remove(i); } } - for (Map<int, Joypad>::Element *E = joy_names.front(); E; E = E->next()) { - Joypad &joy = E->get(); + for (KeyValue<int, Joypad> &E : joy_names) { + Joypad &joy = E.value; if (joy.uid == p_guid) { joy.mapping = -1; } diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index c2a9d30fff..1d2b5f19ee 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -864,6 +864,8 @@ void InputEventMouseMotion::_bind_methods() { /////////////////////////////////// void InputEventJoypadMotion::set_axis(JoyAxis p_axis) { + ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX); + axis = p_axis; emit_changed(); } diff --git a/core/input/shortcut.cpp b/core/input/shortcut.cpp index d0cb08724e..30e35190e4 100644 --- a/core/input/shortcut.cpp +++ b/core/input/shortcut.cpp @@ -31,14 +31,26 @@ #include "shortcut.h" #include "core/os/keyboard.h" -void Shortcut::set_event(const Ref<InputEvent> &p_event) { - ERR_FAIL_COND_MSG(Object::cast_to<InputEventShortcut>(*p_event), "Cannot set a shortcut event to an instance of InputEventShortcut."); - event = p_event; +void Shortcut::set_events(const Array &p_events) { + for (int i = 0; i < p_events.size(); i++) { + Ref<InputEventShortcut> ies = p_events[i]; + ERR_FAIL_COND_MSG(ies.is_valid(), "Cannot set a shortcut event to an instance of InputEventShortcut."); + } + + events = p_events; emit_changed(); } -Ref<InputEvent> Shortcut::get_event() const { - return event; +void Shortcut::set_events_list(const List<Ref<InputEvent>> *p_events) { + events.clear(); + + for (const Ref<InputEvent> &ie : *p_events) { + events.push_back(ie); + } +} + +Array Shortcut::get_events() const { + return events; } bool Shortcut::matches_event(const Ref<InputEvent> &p_event) const { @@ -48,29 +60,73 @@ bool Shortcut::matches_event(const Ref<InputEvent> &p_event) const { return true; } } - return event.is_valid() && event->is_match(p_event, true); + + for (int i = 0; i < events.size(); i++) { + Ref<InputEvent> ie = events[i]; + bool valid = ie.is_valid() && ie->is_match(p_event); + + // Stop on first valid event - don't need to check further. + if (valid) { + return true; + } + } + + return false; } String Shortcut::get_as_text() const { - if (event.is_valid()) { - return event->as_text(); - } else { - return "None"; + for (int i = 0; i < events.size(); i++) { + Ref<InputEvent> ie = events[i]; + // Return first shortcut which is valid + if (ie.is_valid()) { + return ie->as_text(); + } } + + return "None"; } bool Shortcut::has_valid_event() const { - return event.is_valid(); + // Tests if there is ANY input event which is valid. + for (int i = 0; i < events.size(); i++) { + Ref<InputEvent> ie = events[i]; + if (ie.is_valid()) { + return true; + } + } + + return false; } void Shortcut::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_event", "event"), &Shortcut::set_event); - ClassDB::bind_method(D_METHOD("get_event"), &Shortcut::get_event); + ClassDB::bind_method(D_METHOD("set_events", "events"), &Shortcut::set_events); + ClassDB::bind_method(D_METHOD("get_events"), &Shortcut::get_events); ClassDB::bind_method(D_METHOD("has_valid_event"), &Shortcut::has_valid_event); ClassDB::bind_method(D_METHOD("matches_event", "event"), &Shortcut::matches_event); ClassDB::bind_method(D_METHOD("get_as_text"), &Shortcut::get_as_text); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_event", "get_event"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "events", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")), "set_events", "get_events"); +} + +bool Shortcut::is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2) { + if (p_event_array1.size() != p_event_array2.size()) { + return false; + } + + bool is_same = true; + for (int i = 0; i < p_event_array1.size(); i++) { + Ref<InputEvent> ie_1 = p_event_array1[i]; + Ref<InputEvent> ie_2 = p_event_array2[i]; + + is_same = ie_1->is_match(ie_2); + + // Break on the first that doesn't match - don't need to check further. + if (!is_same) { + break; + } + } + + return is_same; } diff --git a/core/input/shortcut.h b/core/input/shortcut.h index 249dd1971f..a989b10626 100644 --- a/core/input/shortcut.h +++ b/core/input/shortcut.h @@ -37,18 +37,22 @@ class Shortcut : public Resource { GDCLASS(Shortcut, Resource); - Ref<InputEvent> event; + Array events; protected: static void _bind_methods(); public: - void set_event(const Ref<InputEvent> &p_shortcut); - Ref<InputEvent> get_event() const; + void set_events(const Array &p_events); + Array get_events() const; + + void set_events_list(const List<Ref<InputEvent>> *p_events); + bool matches_event(const Ref<InputEvent> &p_event) const; bool has_valid_event() const; String get_as_text() const; -}; + static bool is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2); +}; #endif // SHORTCUT_H diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 7b43daf9c0..b2832b2a75 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -110,8 +110,8 @@ PackedData::PackedData() { } void PackedData::_free_packed_dirs(PackedDir *p_dir) { - for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next()) { - _free_packed_dirs(E->get()); + for (const KeyValue<String, PackedDir *> &E : p_dir->subdirs) { + _free_packed_dirs(E.value); } memdelete(p_dir); } @@ -395,8 +395,8 @@ Error DirAccessPack::list_dir_begin() { list_dirs.clear(); list_files.clear(); - for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) { - list_dirs.push_back(E->key()); + for (const KeyValue<String, PackedData::PackedDir *> &E : current->subdirs) { + list_dirs.push_back(E.key); } for (Set<String>::Element *E = current->files.front(); E; E = E->next()) { diff --git a/core/io/ip.cpp b/core/io/ip.cpp index e3102508a3..68b4e4b354 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -288,8 +288,8 @@ Array IP::_get_local_interfaces() const { Array results; Map<String, Interface_Info> interfaces; get_local_interfaces(&interfaces); - for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) { - Interface_Info &c = E->get(); + for (KeyValue<String, Interface_Info> &E : interfaces) { + Interface_Info &c = E.value; Dictionary rc; rc["name"] = c.name; rc["friendly"] = c.name_friendly; @@ -310,8 +310,8 @@ Array IP::_get_local_interfaces() const { void IP::get_local_addresses(List<IPAddress> *r_addresses) const { Map<String, Interface_Info> interfaces; get_local_interfaces(&interfaces); - for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) { - for (const IPAddress &F : E->get().ip_addresses) { + for (const KeyValue<String, Interface_Info> &E : interfaces) { + for (const IPAddress &F : E.value.ip_addresses) { r_addresses->push_front(F); } } diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 87b4d7195d..1cefa52d69 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -540,9 +540,9 @@ void ResourceCache::dump(const char *p_file, bool p_short) { } } - for (Map<String, int>::Element *E = type_count.front(); E; E = E->next()) { + for (const KeyValue<String, int> &E : type_count) { if (f) { - f->store_line(E->key() + " count: " + itos(E->get())); + f->store_line(E.key + " count: " + itos(E.value)); } } if (f) { diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 84fd6496a7..cbb033f6c6 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1960,8 +1960,8 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p Vector<RES> save_order; save_order.resize(external_resources.size()); - for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) { - save_order.write[E->get()] = E->key(); + for (const KeyValue<RES, int> &E : external_resources) { + save_order.write[E.value] = E.key; } for (int i = 0; i < save_order.size(); i++) { diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 3026236f07..2198761c2a 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -156,8 +156,8 @@ void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> * Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { Dictionary deps_dict; - for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) { - deps_dict[E->key()] = E->value(); + for (KeyValue<String, String> E : p_map) { + deps_dict[E.key] = E.value; } int64_t err; diff --git a/core/math/bvh_cull.inc b/core/math/bvh_cull.inc index cba8ea6cb3..d7edc8a884 100644 --- a/core/math/bvh_cull.inc +++ b/core/math/bvh_cull.inc @@ -14,7 +14,7 @@ struct CullParams { uint32_t pairable_type; // optional components for different tests - Vector3 point; + Point point; BVHABB_CLASS abb; typename BVHABB_CLASS::ConvexHull hull; typename BVHABB_CLASS::Segment segment; diff --git a/core/math/bvh_debug.inc b/core/math/bvh_debug.inc index a97304334c..55db794ee3 100644 --- a/core/math/bvh_debug.inc +++ b/core/math/bvh_debug.inc @@ -6,24 +6,21 @@ void _debug_recursive_print_tree(int p_tree_id) const { } String _debug_aabb_to_string(const BVHABB_CLASS &aabb) const { - String sz = "("; - sz += itos(aabb.min.x); - sz += " ~ "; - sz += itos(-aabb.neg_max.x); - sz += ") ("; + Point size = aabb.calculate_size(); - sz += itos(aabb.min.y); - sz += " ~ "; - sz += itos(-aabb.neg_max.y); - sz += ") ("; + String sz; + float vol = 0.0; - sz += itos(aabb.min.z); - sz += " ~ "; - sz += itos(-aabb.neg_max.z); - sz += ") "; + for (int i = 0; i < Point::AXES_COUNT; ++i) { + sz += "("; + sz += itos(aabb.min[i]); + sz += " ~ "; + sz += itos(-aabb.neg_max[i]); + sz += ") "; + + vol += size[i]; + } - Vector3 size = aabb.calculate_size(); - float vol = size.x * size.y * size.z; sz += "vol " + itos(vol); return sz; diff --git a/core/math/bvh_split.inc b/core/math/bvh_split.inc index 3fcc4c7b10..6f54d06ce7 100644 --- a/core/math/bvh_split.inc +++ b/core/math/bvh_split.inc @@ -28,11 +28,15 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u Point centre = full_bound.calculate_centre(); Point size = full_bound.calculate_size(); - int order[3]; + int order[Point::AXIS_COUNT]; order[0] = size.min_axis(); - order[2] = size.max_axis(); - order[1] = 3 - (order[0] + order[2]); + order[Point::AXIS_COUNT - 1] = size.max_axis(); + + static_assert(Point::AXIS_COUNT <= 3); + if (Point::AXIS_COUNT == 3) { + order[1] = 3 - (order[0] + order[2]); + } // simplest case, split on the longest axis int split_axis = order[0]; @@ -54,7 +58,7 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u // detect when split on longest axis failed int min_threshold = MAX_ITEMS / 4; - int min_group_size[3]; + int min_group_size[Point::AXIS_COUNT]; min_group_size[0] = MIN(num_a, num_b); if (min_group_size[0] < min_threshold) { // slow but sure .. first move everything back into a @@ -64,7 +68,7 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u num_b = 0; // now calculate the best split - for (int axis = 1; axis < 3; axis++) { + for (int axis = 1; axis < Point::AXIS_COUNT; axis++) { split_axis = order[axis]; int count = 0; @@ -82,7 +86,7 @@ void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, u // best axis int best_axis = 0; int best_min = min_group_size[0]; - for (int axis = 1; axis < 3; axis++) { + for (int axis = 1; axis < Point::AXIS_COUNT; axis++) { if (min_group_size[axis] > best_min) { best_min = min_group_size[axis]; best_axis = axis; diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 0960fe19a6..d438a9a377 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -265,8 +265,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ //create new faces from horizon edges List<List<Face>::Element *> new_faces; //new faces - for (Map<Edge, FaceConnect>::Element *E = lit_edges.front(); E; E = E->next()) { - FaceConnect &fc = E->get(); + for (KeyValue<Edge, FaceConnect> &E : lit_edges) { + FaceConnect &fc = E.value; if (fc.left && fc.right) { continue; //edge is uninteresting, not on horizon } @@ -275,8 +275,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ Face face; face.vertices[0] = f.points_over[next]; - face.vertices[1] = E->key().vertices[0]; - face.vertices[2] = E->key().vertices[1]; + face.vertices[1] = E.key.vertices[0]; + face.vertices[2] = E.key.vertices[1]; Plane p(p_points[face.vertices[0]], p_points[face.vertices[1]], p_points[face.vertices[2]]); @@ -418,13 +418,13 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ } // remove all edge connections to this face - for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) { - if (G->get().left == O) { - G->get().left = nullptr; + for (KeyValue<Edge, RetFaceConnect> &G : ret_edges) { + if (G.value.left == O) { + G.value.left = nullptr; } - if (G->get().right == O) { - G->get().right = nullptr; + if (G.value.right == O) { + G.value.right = nullptr; } } @@ -444,10 +444,10 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ } r_mesh.edges.resize(ret_edges.size()); idx = 0; - for (Map<Edge, RetFaceConnect>::Element *E = ret_edges.front(); E; E = E->next()) { + for (const KeyValue<Edge, RetFaceConnect> &E : ret_edges) { Geometry3D::MeshData::Edge e; - e.a = E->key().vertices[0]; - e.b = E->key().vertices[1]; + e.a = E.key.vertices[0]; + e.b = E.key.vertices[1]; r_mesh.edges.write[idx++] = e; } diff --git a/modules/gdnative/text/register_types.h b/core/math/static_raycaster.cpp index cd4f2a3089..da05d49428 100644 --- a/modules/gdnative/text/register_types.h +++ b/core/math/static_raycaster.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* register_types.h */ +/* static_raycaster.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,10 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TEXT_REGISTER_TYPES_H -#define TEXT_REGISTER_TYPES_H +#include "static_raycaster.h" -void register_text_server_gdn_types(); -void unregister_text_server_gdn_types(); +StaticRaycaster *(*StaticRaycaster::create_function)() = nullptr; -#endif // TEXT_REGISTER_TYPES_H +Ref<StaticRaycaster> StaticRaycaster::create() { + if (create_function) { + return Ref<StaticRaycaster>(create_function()); + } + return Ref<StaticRaycaster>(); +} diff --git a/core/math/static_raycaster.h b/core/math/static_raycaster.h new file mode 100644 index 0000000000..3759c788a7 --- /dev/null +++ b/core/math/static_raycaster.h @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* static_raycaster.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef STATIC_RAYCASTER_H +#define STATIC_RAYCASTER_H + +#include "core/object/ref_counted.h" + +#if !defined(__aligned) + +#if defined(_WIN32) && defined(_MSC_VER) +#define __aligned(...) __declspec(align(__VA_ARGS__)) +#else +#define __aligned(...) __attribute__((aligned(__VA_ARGS__))) +#endif + +#endif + +class StaticRaycaster : public RefCounted { + GDCLASS(StaticRaycaster, RefCounted) +protected: + static StaticRaycaster *(*create_function)(); + +public: + // compatible with embree3 rays + struct __aligned(16) Ray { + const static unsigned int INVALID_GEOMETRY_ID = ((unsigned int)-1); // from rtcore_common.h + + /*! Default construction does nothing. */ + _FORCE_INLINE_ Ray() : + geomID(INVALID_GEOMETRY_ID) {} + + /*! Constructs a ray from origin, direction, and ray segment. Near + * has to be smaller than far. */ + _FORCE_INLINE_ Ray(const Vector3 &org, + const Vector3 &dir, + float tnear = 0.0f, + float tfar = INFINITY) : + org(org), + tnear(tnear), + dir(dir), + time(0.0f), + tfar(tfar), + mask(-1), + u(0.0), + v(0.0), + primID(INVALID_GEOMETRY_ID), + geomID(INVALID_GEOMETRY_ID), + instID(INVALID_GEOMETRY_ID) {} + + /*! Tests if we hit something. */ + _FORCE_INLINE_ explicit operator bool() const { return geomID != INVALID_GEOMETRY_ID; } + + public: + Vector3 org; //!< Ray origin + tnear + float tnear; //!< Start of ray segment + Vector3 dir; //!< Ray direction + tfar + float time; //!< Time of this ray for motion blur. + float tfar; //!< End of ray segment + unsigned int mask; //!< used to mask out objects during traversal + unsigned int id; //!< ray ID + unsigned int flags; //!< ray flags + + Vector3 normal; //!< Not normalized geometry normal + float u; //!< Barycentric u coordinate of hit + float v; //!< Barycentric v coordinate of hit + unsigned int primID; //!< primitive ID + unsigned int geomID; //!< geometry ID + unsigned int instID; //!< instance ID + }; + + virtual bool intersect(Ray &p_ray) = 0; + virtual void intersect(Vector<Ray> &r_rays) = 0; + + virtual void add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) = 0; + virtual void commit() = 0; + + virtual void set_mesh_filter(const Set<int> &p_mesh_ids) = 0; + virtual void clear_mesh_filter() = 0; + + static Ref<StaticRaycaster> create(); +}; + +#endif // STATIC_RAYCASTER_H diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 16d9652ef2..2f3da0b6a8 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -157,8 +157,8 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) { vertices.resize(db.size()); Vector3 *vw = vertices.ptrw(); - for (Map<Vector3, int>::Element *E = db.front(); E; E = E->next()) { - vw[E->get()] = E->key(); + for (const KeyValue<Vector3, int> &E : db) { + vw[E.value] = E.key; } } diff --git a/core/multiplayer/multiplayer.h b/core/multiplayer/multiplayer.h index 00c81d3c9a..31b7bf0043 100644 --- a/core/multiplayer/multiplayer.h +++ b/core/multiplayer/multiplayer.h @@ -39,13 +39,13 @@ namespace Multiplayer { enum TransferMode { TRANSFER_MODE_UNRELIABLE, - TRANSFER_MODE_ORDERED, + TRANSFER_MODE_UNRELIABLE_ORDERED, TRANSFER_MODE_RELIABLE }; enum RPCMode { RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) - RPC_MODE_ANY, // Any peer can call this RPC + RPC_MODE_ANY_PEER, // Any peer can call this RPC RPC_MODE_AUTHORITY, // / Only the node's multiplayer authority (server by default) can call this RPC }; diff --git a/core/multiplayer/rpc_manager.cpp b/core/multiplayer/rpc_manager.cpp index 915571375e..20ab7a25bb 100644 --- a/core/multiplayer/rpc_manager.cpp +++ b/core/multiplayer/rpc_manager.cpp @@ -99,7 +99,7 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, Multiplayer::RPCMode mode, int case Multiplayer::RPC_MODE_DISABLED: { return false; } break; - case Multiplayer::RPC_MODE_ANY: { + case Multiplayer::RPC_MODE_ANY_PEER: { return true; } break; case Multiplayer::RPC_MODE_AUTHORITY: { diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp index 4751c69f1e..736e940846 100644 --- a/core/object/message_queue.cpp +++ b/core/object/message_queue.cpp @@ -227,16 +227,16 @@ void MessageQueue::statistics() { print_line("TOTAL BYTES: " + itos(buffer_end)); print_line("NULL count: " + itos(null_count)); - for (Map<StringName, int>::Element *E = set_count.front(); E; E = E->next()) { - print_line("SET " + E->key() + ": " + itos(E->get())); + for (const KeyValue<StringName, int> &E : set_count) { + print_line("SET " + E.key + ": " + itos(E.value)); } - for (Map<Callable, int>::Element *E = call_count.front(); E; E = E->next()) { - print_line("CALL " + E->key() + ": " + itos(E->get())); + for (const KeyValue<Callable, int> &E : call_count) { + print_line("CALL " + E.key + ": " + itos(E.value)); } - for (Map<int, int>::Element *E = notify_count.front(); E; E = E->next()) { - print_line("NOTIFY " + itos(E->key()) + ": " + itos(E->get())); + for (const KeyValue<int, int> &E : notify_count) { + print_line("NOTIFY " + itos(E.key) + ": " + itos(E.value)); } } diff --git a/core/object/object.cpp b/core/object/object.cpp index 3335942fb3..b5797a4633 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1409,7 +1409,7 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable, if (!p_force) { slot->reference_count--; // by default is zero, if it was not referenced it will go below it - if (slot->reference_count >= 0) { + if (slot->reference_count > 0) { return; } } diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 0fb8c7350c..b0ce46ca2b 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -93,8 +93,8 @@ Dictionary Script::_get_script_constant_map() { Dictionary ret; Map<StringName, Variant> map; get_constants(&map); - for (Map<StringName, Variant>::Element *E = map.front(); E; E = E->next()) { - ret[E->key()] = E->value(); + for (const KeyValue<StringName, Variant> &E : map) { + ret[E.key] = E.value; } return ret; } diff --git a/core/os/os.cpp b/core/os/os.cpp index 7505f3ff34..69366f688c 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -282,6 +282,11 @@ String OS::get_bundle_resource_dir() const { return "."; } +// Path to macOS .app bundle embedded icon +String OS::get_bundle_icon_path() const { + return String(); +} + // OS specific path for user:// String OS::get_user_data_dir() const { return "."; diff --git a/core/os/os.h b/core/os/os.h index c027428477..29d33ce4f0 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -252,6 +252,7 @@ public: virtual String get_config_path() const; virtual String get_cache_path() const; virtual String get_bundle_resource_dir() const; + virtual String get_bundle_icon_path() const; virtual String get_user_data_dir() const; virtual String get_resource_dir() const; diff --git a/core/os/thread.cpp b/core/os/thread.cpp index 92e43963d2..27aefc98de 100644 --- a/core/os/thread.cpp +++ b/core/os/thread.cpp @@ -28,9 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Define PLATFORM_CUSTOM_THREAD_H in platform_config.h -// Overriding the platform implementation is required in some proprietary platforms -#ifndef PLATFORM_CUSTOM_THREAD_H +#ifndef PLATFORM_THREAD_OVERRIDE // See details in thread.h #include "thread.h" @@ -130,4 +128,4 @@ Thread::~Thread() { } #endif -#endif // PLATFORM_CUSTOM_THREAD_H +#endif // PLATFORM_THREAD_OVERRIDE diff --git a/core/os/thread.h b/core/os/thread.h index 3a0938c7f7..59cb58ac57 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -28,10 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Define PLATFORM_CUSTOM_THREAD_H in platform_config.h +// Define PLATFORM_THREAD_OVERRIDE in your platform's `platform_config.h` +// to use a custom Thread implementation defined in `platform/[your_platform]/platform_thread.h` // Overriding the platform implementation is required in some proprietary platforms -#ifdef PLATFORM_CUSTOM_THREAD_H -#include PLATFORM_CUSTOM_THREAD_H +#ifdef PLATFORM_THREAD_OVERRIDE +#include "platform_thread.h" #else #ifndef THREAD_H #define THREAD_H @@ -121,4 +122,4 @@ public: }; #endif // THREAD_H -#endif // PLATFORM_CUSTOM_THREAD_H +#endif // PLATFORM_THREAD_OVERRIDE diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp index 5863bd1c46..839b7a9c01 100644 --- a/core/string/optimized_translation.cpp +++ b/core/string/optimized_translation.cpp @@ -162,11 +162,11 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) { btw[btindex++] = t.size(); btw[btindex++] = hfunc_table[i]; - for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) { - btw[btindex++] = E->key(); - btw[btindex++] = compressed[E->get()].offset; - btw[btindex++] = compressed[E->get()].compressed.size(); - btw[btindex++] = compressed[E->get()].orig_len; + for (const KeyValue<uint32_t, int> &E : t) { + btw[btindex++] = E.key; + btw[btindex++] = compressed[E.value].offset; + btw[btindex++] = compressed[E.value].compressed.size(); + btw[btindex++] = compressed[E.value].orig_len; } } diff --git a/core/string/translation.cpp b/core/string/translation.cpp index 5c0eb388f5..5e3b8297aa 100644 --- a/core/string/translation.cpp +++ b/core/string/translation.cpp @@ -820,8 +820,8 @@ static const char *locale_renames[][2] = { Dictionary Translation::_get_messages() const { Dictionary d; - for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) { - d[E->key()] = E->value(); + for (const KeyValue<StringName, StringName> &E : translation_map) { + d[E.key] = E.value; } return d; } @@ -830,8 +830,8 @@ Vector<String> Translation::_get_message_list() const { Vector<String> msgs; msgs.resize(translation_map.size()); int idx = 0; - for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) { - msgs.set(idx, E->key()); + for (const KeyValue<StringName, StringName> &E : translation_map) { + msgs.set(idx, E.key); idx += 1; } @@ -911,8 +911,8 @@ void Translation::erase_message(const StringName &p_src_text, const StringName & } void Translation::get_message_list(List<StringName> *r_messages) const { - for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) { - r_messages->push_back(E->key()); + for (const KeyValue<StringName, StringName> &E : translation_map) { + r_messages->push_back(E.key); } } diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index e947d2211c..71d41eacc4 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -151,7 +151,7 @@ public: return _allocate_rid(); } - _FORCE_INLINE_ T *getornull(const RID &p_rid, bool p_initialize = false) { + _FORCE_INLINE_ T *get_or_null(const RID &p_rid, bool p_initialize = false) { if (p_rid == RID()) { return nullptr; } @@ -210,12 +210,12 @@ public: return ptr; } void initialize_rid(RID p_rid) { - T *mem = getornull(p_rid, true); + T *mem = get_or_null(p_rid, true); ERR_FAIL_COND(!mem); memnew_placement(mem, T); } void initialize_rid(RID p_rid, const T &p_value) { - T *mem = getornull(p_rid, true); + T *mem = get_or_null(p_rid, true); ERR_FAIL_COND(!mem); memnew_placement(mem, T(p_value)); } @@ -399,8 +399,8 @@ public: alloc.initialize_rid(p_rid, p_ptr); } - _FORCE_INLINE_ T *getornull(const RID &p_rid) { - T **ptr = alloc.getornull(p_rid); + _FORCE_INLINE_ T *get_or_null(const RID &p_rid) { + T **ptr = alloc.get_or_null(p_rid); if (unlikely(!ptr)) { return nullptr; } @@ -408,7 +408,7 @@ public: } _FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) { - T **ptr = alloc.getornull(p_rid); + T **ptr = alloc.get_or_null(p_rid); ERR_FAIL_COND(!ptr); *ptr = p_new_ptr; } @@ -469,8 +469,8 @@ public: alloc.initialize_rid(p_rid, p_ptr); } - _FORCE_INLINE_ T *getornull(const RID &p_rid) { - return alloc.getornull(p_rid); + _FORCE_INLINE_ T *get_or_null(const RID &p_rid) { + return alloc.get_or_null(p_rid); } _FORCE_INLINE_ bool owns(const RID &p_rid) { diff --git a/modules/gdnative/text/register_types.cpp b/core/templates/search_array.h index 67385d2fbf..8efc32df82 100644 --- a/modules/gdnative/text/register_types.cpp +++ b/core/templates/search_array.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* register_types.cpp */ +/* search_array.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,9 +28,40 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "register_types.h" -#include "text_server_gdnative.h" +#ifndef SEARCH_ARRAY_H +#define SEARCH_ARRAY_H -void register_text_server_gdn_types() {} +#include <core/templates/sort_array.h> -void unregister_text_server_gdn_types() {} +template <class T, class Comparator = _DefaultComparator<T>> +class SearchArray { +public: + Comparator compare; + + inline int bisect(const T *p_array, int p_len, const T &p_value, bool p_before) const { + int lo = 0; + int hi = p_len; + if (p_before) { + while (lo < hi) { + const int mid = (lo + hi) / 2; + if (compare(p_array[mid], p_value)) { + lo = mid + 1; + } else { + hi = mid; + } + } + } else { + while (lo < hi) { + const int mid = (lo + hi) / 2; + if (compare(p_value, p_array[mid])) { + hi = mid; + } else { + lo = mid + 1; + } + } + } + return lo; + } +}; + +#endif // SEARCH_ARRAY_H diff --git a/core/templates/vector.h b/core/templates/vector.h index 2600604eb7..4b008a45a4 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -40,6 +40,7 @@ #include "core/error/error_macros.h" #include "core/os/memory.h" #include "core/templates/cowdata.h" +#include "core/templates/search_array.h" #include "core/templates/sort_array.h" template <class T> @@ -112,6 +113,11 @@ public: sort_custom<_DefaultComparator<T>>(); } + int bsearch(const T &p_value, bool p_before) { + SearchArray<T> search; + return search.bisect(ptrw(), size(), p_value, p_before); + } + Vector<T> duplicate() { return *this; } diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 8373cbd4e8..b4d6dffc6f 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -34,6 +34,7 @@ #include "core/object/class_db.h" #include "core/object/script_language.h" #include "core/templates/hashfuncs.h" +#include "core/templates/search_array.h" #include "core/templates/vector.h" #include "core/variant/callable.h" #include "core/variant/variant.h" @@ -484,44 +485,19 @@ void Array::shuffle() { } } -template <typename Less> -_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) { - int lo = 0; - int hi = p_array.size(); - if (p_before) { - while (lo < hi) { - const int mid = (lo + hi) / 2; - if (p_less(p_array.get(mid), p_value)) { - lo = mid + 1; - } else { - hi = mid; - } - } - } else { - while (lo < hi) { - const int mid = (lo + hi) / 2; - if (p_less(p_value, p_array.get(mid))) { - hi = mid; - } else { - lo = mid + 1; - } - } - } - return lo; -} - int Array::bsearch(const Variant &p_value, bool p_before) { ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1); - return bisect(_p->array, p_value, p_before, _ArrayVariantSort()); + SearchArray<Variant, _ArrayVariantSort> avs; + return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before); } int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before) { ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); - _ArrayVariantSortCustom less; - less.func = p_callable; + SearchArray<Variant, _ArrayVariantSortCustom> avs; + avs.compare.func = p_callable; - return bisect(_p->array, p_value, p_before, less); + return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before); } void Array::reverse() { diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index b7e8d92f62..913d4d8f7c 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -55,7 +55,7 @@ struct GDNativePtr { #define GDVIRTUAL_NATIVE_PTR(m_type) \ template <> \ - struct GDNativeConstPtr<m_type> { \ + struct GDNativeConstPtr<const m_type> { \ const m_type *data = nullptr; \ GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \ static const char *get_name() { return "const " #m_type; } \ diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 32d6778a2b..6284caae2d 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1241,8 +1241,8 @@ void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_c for (List<StringName>::Element *E = cd.value_ordered.front(); E; E = E->next()) { p_constants->push_back(E->get()); #else - for (Map<StringName, int>::Element *E = cd.value.front(); E; E = E->next()) { - p_constants->push_back(E->key()); + for (const KeyValue<StringName, int> &E : cd.value) { + p_constants->push_back(E.key); #endif } @@ -1250,8 +1250,8 @@ void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_c for (List<StringName>::Element *E = cd.variant_value_ordered.front(); E; E = E->next()) { p_constants->push_back(E->get()); #else - for (Map<StringName, Variant>::Element *E = cd.variant_value.front(); E; E = E->next()) { - p_constants->push_back(E->key()); + for (const KeyValue<StringName, Variant> &E : cd.variant_value) { + p_constants->push_back(E.key); #endif } } @@ -1845,6 +1845,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedByteArray, reverse, sarray(), varray()); bind_method(PackedByteArray, subarray, sarray("from", "to"), varray()); bind_method(PackedByteArray, sort, sarray(), varray()); + bind_method(PackedByteArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedByteArray, duplicate, sarray(), varray()); bind_function(PackedByteArray, get_string_from_ascii, _VariantCall::func_PackedByteArray_get_string_from_ascii, sarray(), varray()); @@ -1906,6 +1907,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray()); bind_method(PackedInt32Array, to_byte_array, sarray(), varray()); bind_method(PackedInt32Array, sort, sarray(), varray()); + bind_method(PackedInt32Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedInt32Array, duplicate, sarray(), varray()); /* Int64 Array */ @@ -1925,6 +1927,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray()); bind_method(PackedInt64Array, to_byte_array, sarray(), varray()); bind_method(PackedInt64Array, sort, sarray(), varray()); + bind_method(PackedInt64Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedInt64Array, duplicate, sarray(), varray()); /* Float32 Array */ @@ -1944,6 +1947,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray()); bind_method(PackedFloat32Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat32Array, sort, sarray(), varray()); + bind_method(PackedFloat32Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedFloat32Array, duplicate, sarray(), varray()); /* Float64 Array */ @@ -1963,6 +1967,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray()); bind_method(PackedFloat64Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat64Array, sort, sarray(), varray()); + bind_method(PackedFloat64Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedFloat64Array, duplicate, sarray(), varray()); /* String Array */ @@ -1982,6 +1987,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedStringArray, subarray, sarray("from", "to"), varray()); bind_method(PackedStringArray, to_byte_array, sarray(), varray()); bind_method(PackedStringArray, sort, sarray(), varray()); + bind_method(PackedStringArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedStringArray, duplicate, sarray(), varray()); /* Vector2 Array */ @@ -2001,6 +2007,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray()); bind_method(PackedVector2Array, to_byte_array, sarray(), varray()); bind_method(PackedVector2Array, sort, sarray(), varray()); + bind_method(PackedVector2Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedVector2Array, duplicate, sarray(), varray()); /* Vector3 Array */ @@ -2020,6 +2027,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray()); bind_method(PackedVector3Array, to_byte_array, sarray(), varray()); bind_method(PackedVector3Array, sort, sarray(), varray()); + bind_method(PackedVector3Array, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedVector3Array, duplicate, sarray(), varray()); /* Color Array */ @@ -2039,6 +2047,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedColorArray, subarray, sarray("from", "to"), varray()); bind_method(PackedColorArray, to_byte_array, sarray(), varray()); bind_method(PackedColorArray, sort, sarray(), varray()); + bind_method(PackedColorArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedColorArray, duplicate, sarray(), varray()); /* Register constants */ diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 0334bab32a..5d45947a19 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -23,7 +23,7 @@ Returns the absolute value of float parameter [code]x[/code] (i.e. positive value). [codeblock] # a is 1.2 - a = absf(-1.2) + var a = absf(-1.2) [/codeblock] </description> </method> @@ -34,7 +34,7 @@ Returns the absolute value of int parameter [code]x[/code] (i.e. positive value). [codeblock] # a is 1 - a = absi(-1) + var a = absi(-1) [/codeblock] </description> </method> @@ -45,7 +45,7 @@ Returns the arc cosine of [code]x[/code] in radians. Use to get the angle of cosine [code]x[/code]. [code]x[/code] must be between [code]-1.0[/code] and [code]1.0[/code] (inclusive), otherwise, [method acos] will return [constant @GDScript.NAN]. [codeblock] # c is 0.523599 or 30 degrees if converted with rad2deg(c) - c = acos(0.866025) + var c = acos(0.866025) [/codeblock] </description> </method> @@ -56,7 +56,7 @@ Returns the arc sine of [code]x[/code] in radians. Use to get the angle of sine [code]x[/code]. [code]x[/code] must be between [code]-1.0[/code] and [code]1.0[/code] (inclusive), otherwise, [method asin] will return [constant @GDScript.NAN]. [codeblock] # s is 0.523599 or 30 degrees if converted with rad2deg(s) - s = asin(0.5) + var s = asin(0.5) [/codeblock] </description> </method> @@ -64,11 +64,12 @@ <return type="float" /> <argument index="0" name="x" type="float" /> <description> - Returns the arc tangent of [code]x[/code] in radians. Use it to get the angle from an angle's tangent in trigonometry: [code]atan(tan(angle)) == angle[/code]. + Returns the arc tangent of [code]x[/code] in radians. Use it to get the angle from an angle's tangent in trigonometry. The method cannot know in which quadrant the angle should fall. See [method atan2] if you have both [code]y[/code] and [code]x[/code]. [codeblock] - a = atan(0.5) # a is 0.463648 + var a = atan(0.5) # a is 0.463648 [/codeblock] + If [code]x[/code] is between [code]-PI / 2[/code] and [code]PI / 2[/code] (inclusive), [code]atan(tan(x))[/code] is equal to [code]x[/code]. </description> </method> <method name="atan2"> @@ -79,7 +80,7 @@ Returns the arc tangent of [code]y/x[/code] in radians. Use to get the angle of tangent [code]y/x[/code]. To compute the value, the method takes into account the sign of both arguments in order to determine the quadrant. Important note: The Y coordinate comes first, by convention. [codeblock] - a = atan2(0, -1) # a is 3.141593 + var a = atan2(0, -1) # a is 3.141593 [/codeblock] </description> </method> @@ -105,8 +106,8 @@ <description> Rounds [code]x[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]x[/code]. [codeblock] - i = ceil(1.45) # i is 2 - i = ceil(1.001) # i is 2 + var i = ceil(1.45) # i is 2.0 + i = ceil(1.001) # i is 2.0 [/codeblock] See also [method floor], [method round], and [method snapped]. </description> @@ -127,9 +128,9 @@ <description> Clamps the float [code]value[/code] and returns a value not less than [code]min[/code] and not more than [code]max[/code]. [codeblock] - speed = 42.1 + var speed = 42.1 # a is 20.0 - a = clampf(speed, 1.0, 20.0) + var a = clampf(speed, 1.0, 20.0) speed = -10.0 # a is -1.0 @@ -145,9 +146,9 @@ <description> Clamps the integer [code]value[/code] and returns a value not less than [code]min[/code] and not more than [code]max[/code]. [codeblock] - speed = 42 + var speed = 42 # a is 20 - a = clampi(speed, 1, 20) + var a = clampi(speed, 1, 20) speed = -10 # a is -1 @@ -161,9 +162,9 @@ <description> Returns the cosine of angle [code]angle_rad[/code] in radians. [codeblock] - # Prints 1 then -1 - print(cos(PI * 2)) - print(cos(PI)) + cos(PI * 2) # Returns 1.0 + cos(PI) # Returns -1.0 + cos(deg2rad(90)) # Returns 0.0 [/codeblock] </description> </method> @@ -192,7 +193,7 @@ Converts an angle expressed in degrees to radians. [codeblock] # r is 3.141593 - r = deg2rad(180) + var r = deg2rad(180) [/codeblock] </description> </method> @@ -201,7 +202,18 @@ <argument index="0" name="x" type="float" /> <argument index="1" name="curve" type="float" /> <description> - Easing function, based on exponent. The curve values are: 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in. + Returns an "eased" value of [code]x[/code] based on an easing function defined with [code]curve[/code]. This easing function is based on an exponent. The [code]curve[/code] can be any floating-point number, with specific values leading to the following behaviors: + [codeblock] + - Lower than -1.0 (exclusive): Ease in-out + - 1.0: Linear + - Between -1.0 and 0.0 (exclusive): Ease out-in + - 0.0: Constant + - Between 0.0 to 1.0 (exclusive): Ease in + - 1.0: Linear + - Greater than 1.0 (exclusive): Ease out + [/codeblock] + [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/ease_cheatsheet.png]ease() curve values cheatsheet[/url] + See also [method smoothstep]. If you need to perform more advanced transitions, use [Tween] or [AnimationPlayer]. </description> </method> <method name="error_string"> @@ -219,7 +231,7 @@ [b]e[/b] has an approximate value of 2.71828, and can be obtained with [code]exp(1)[/code]. For exponents to other bases use the method [method pow]. [codeblock] - a = exp(2) # Approximately 7.39 + var a = exp(2) # Approximately 7.39 [/codeblock] </description> </method> @@ -230,7 +242,7 @@ Rounds [code]x[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]x[/code]. [codeblock] # a is 2.0 - a = floor(2.99) + var a = floor(2.99) # a is -3.0 a = floor(-2.99) [/codeblock] @@ -550,7 +562,7 @@ <description> Converts one or more arguments of any type to string in the best way possible and prints them to the console. [codeblock] - a = [1, 2, 3] + var a = [1, 2, 3] print("a", "b", a) # Prints ab[1, 2, 3] [/codeblock] [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. @@ -729,7 +741,7 @@ <description> Sets seed for the random number generator. [codeblock] - my_seed = "Godot Rocks" + var my_seed = "Godot Rocks" seed(my_seed.hash()) [/codeblock] </description> @@ -770,7 +782,8 @@ <description> Returns the sine of angle [code]angle_rad[/code] in radians. [codeblock] - sin(0.523599) # Returns 0.5 + sin(0.523599) # Returns 0.5 + sin(deg2rad(90)) # Returns 1.0 [/codeblock] </description> </method> @@ -780,7 +793,7 @@ <description> Returns the hyperbolic sine of [code]x[/code]. [codeblock] - a = log(2.0) # Returns 0.693147 + var a = log(2.0) # Returns 0.693147 sinh(a) # Returns 0.75 [/codeblock] </description> @@ -800,6 +813,8 @@ smoothstep(0, 2, 1.0) # Returns 0.5 smoothstep(0, 2, 2.0) # Returns 1.0 [/codeblock] + Compared to [method ease] with a curve value of [code]-1.6521[/code], [method smoothstep] returns the smoothest possible curve with no sudden changes in the derivative. If you need to perform more advanced transitions, use [Tween] or [AnimationPlayer]. + [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, -1.6521) return values[/url] </description> </method> <method name="snapped"> @@ -833,7 +848,7 @@ Returns the position of the first non-zero digit, after the decimal point. Note that the maximum return value is 10, which is a design decision in the implementation. [codeblock] # n is 0 - n = step_decimals(5) + var n = step_decimals(5) # n is 4 n = step_decimals(1.0005) # n is 9 @@ -853,8 +868,8 @@ <description> Converts a formatted string that was returned by [method var2str] to the original value. [codeblock] - a = '{ "a": 1, "b": 2 }' - b = str2var(a) + var a = '{ "a": 1, "b": 2 }' + var b = str2var(a) print(b["a"]) # Prints 1 [/codeblock] </description> @@ -875,7 +890,7 @@ <description> Returns the hyperbolic tangent of [code]x[/code]. [codeblock] - a = log(2.0) # Returns 0.693147 + var a = log(2.0) # Returns 0.693147 tanh(a) # Returns 0.6 [/codeblock] </description> @@ -2473,16 +2488,16 @@ <constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode"> Used with [method Node.rpc_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. </constant> - <constant name="RPC_MODE_ANY" value="1" enum="RPCMode"> + <constant name="RPC_MODE_ANY_PEER" value="1" enum="RPCMode"> Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not. </constant> <constant name="RPC_MODE_AUTH" value="2" enum="RPCMode"> Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(auth)[/code] annotation. See [method Node.set_multiplayer_authority]. </constant> <constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode"> - Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_ORDERED]. Use for non-critical data, and always consider whether the order matters. + Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always consider whether the order matters. </constant> - <constant name="TRANSFER_MODE_ORDERED" value="1" enum="TransferMode"> + <constant name="TRANSFER_MODE_UNRELIABLE_ORDERED" value="1" enum="TransferMode"> Packets are not acknowledged, no resend attempts are made for lost packets. Packets are received in the order they were sent in. Potentially faster than [constant TRANSFER_MODE_RELIABLE]. Use for non-critical data or data that would be outdated if received late due to resend attempt(s) anyway, for example movement and positional data. </constant> <constant name="TRANSFER_MODE_RELIABLE" value="2" enum="TransferMode"> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index a5516636aa..84ed0de42d 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -250,7 +250,8 @@ The strength of the normal map's effect. </member> <member name="normal_texture" type="Texture2D" setter="set_texture" getter="get_texture"> - Texture used to specify the normal at a given pixel. The [code]normal_texture[/code] only uses the red and green channels. The normal read from [code]normal_texture[/code] is oriented around the surface normal provided by the [Mesh]. + Texture used to specify the normal at a given pixel. The [code]normal_texture[/code] only uses the red and green channels; the blue and alpha channels are ignored. The normal read from [code]normal_texture[/code] is oriented around the surface normal provided by the [Mesh]. + [b]Note:[/b] The mesh must have both normals and tangents defined in its vertex data. Otherwise, the normal map won't render correctly and will only appear to darken the whole surface. If creating geometry with [SurfaceTool], you can use [method SurfaceTool.generate_normals] and [method SurfaceTool.generate_tangents] to automatically generate normals and tangents respectively. [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines. </member> <member name="orm_texture" type="Texture2D" setter="set_texture" getter="get_texture"> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 501f89fa0d..738594ea5d 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -150,7 +150,7 @@ <argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" /> <argument index="8" name="outline_size" type="int" default="0" /> <argument index="9" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" /> - <argument index="10" name="flags" type="int" default="51" /> + <argument index="10" name="flags" type="int" default="99" /> <description> Breaks [code]text[/code] to the lines and draws it using the specified [code]font[/code] at the [code]position[/code] (top-left corner). The text will have its color multiplied by [code]modulate[/code]. If [code]clip_w[/code] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. </description> diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml index 35702070be..e14c2dc110 100644 --- a/doc/classes/CharacterBody2D.xml +++ b/doc/classes/CharacterBody2D.xml @@ -28,6 +28,12 @@ Returns the surface normal of the floor at the last collision point. Only valid after calling [method move_and_slide] and when [method is_on_floor] returns [code]true[/code]. </description> </method> + <method name="get_last_motion" qualifiers="const"> + <return type="Vector2" /> + <description> + Returns the last motion applied to the [CharacterBody2D] during the last call to [method move_and_slide]. The movement can be split into multiple motions when sliding occurs, and this method return the last one, which is useful to retrieve the current direction of the movement. + </description> + </method> <method name="get_last_slide_collision"> <return type="KinematicCollision2D" /> <description> @@ -40,6 +46,18 @@ Returns the linear velocity of the platform at the last collision point. Only valid after calling [method move_and_slide]. </description> </method> + <method name="get_position_delta" qualifiers="const"> + <return type="Vector2" /> + <description> + Returns the travel (position delta) that occurred during the last call to [method move_and_slide]. + </description> + </method> + <method name="get_real_velocity" qualifiers="const"> + <return type="Vector2" /> + <description> + Returns the current real velocity since the last call to [method move_and_slide]. For example, when you climb a slope, you will move diagonally even though the velocity is horizontal. This method returns the diagonal movement, as opposed to [member motion_velocity] which returns the requested velocity. + </description> + </method> <method name="get_slide_collision"> <return type="KinematicCollision2D" /> <argument index="0" name="slide_idx" type="int" /> @@ -68,6 +86,12 @@ Returns the number of times the body collided and changed direction during the last call to [method move_and_slide]. </description> </method> + <method name="get_wall_normal" qualifiers="const"> + <return type="Vector2" /> + <description> + Returns the surface normal of the wall at the last collision point. Only valid after calling [method move_and_slide] and when [method is_on_wall] returns [code]true[/code]. + </description> + </method> <method name="is_on_ceiling" qualifiers="const"> <return type="bool" /> <description> @@ -107,9 +131,9 @@ <method name="move_and_slide"> <return type="bool" /> <description> - Moves the body based on [member linear_velocity]. If the body collides with another, it will slide along the other body (by default only on floor) rather than stop immediately. If the other body is a [CharacterBody2D] or [RigidDynamicBody2D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. + Moves the body based on [member motion_velocity]. If the body collides with another, it will slide along the other body (by default only on floor) rather than stop immediately. If the other body is a [CharacterBody2D] or [RigidDynamicBody2D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed. - Modifies [member linear_velocity] if a slide collision occurred. To get the latest collision call [method get_last_slide_collision], for detailed information about collisions that occurred, use [method get_slide_collision]. + Modifies [member motion_velocity] if a slide collision occurred. To get the latest collision call [method get_last_slide_collision], for detailed information about collisions that occurred, use [method get_slide_collision]. When the body touches a moving platform, the platform's velocity is automatically added to the body motion. If a collision occurs due to the platform's motion, it will always be first in the slide collisions. The general behaviour and available properties change according to the [member motion_mode]. Returns [code]true[/code] if the body collided, otherwise, returns [code]false[/code]. @@ -138,20 +162,24 @@ As long as the snapping vector is in contact with the ground and the body moves against `up_direction`, the body will remain attached to the surface. Snapping is not applied if the body moves along `up_direction`, so it will be able to detach from the ground when jumping. </member> <member name="floor_stop_on_slope" type="bool" setter="set_floor_stop_on_slope_enabled" getter="is_floor_stop_on_slope_enabled" default="true"> - If [code]true[/code], the body will not slide on floor's slopes when you include gravity in [code]linear_velocity[/code] when calling [method move_and_slide] and the body is standing still. + If [code]true[/code], the body will not slide on slopes when calling [method move_and_slide] when the body is standing still. + If [code]false[/code], the body will slide on floor's slopes when [member motion_velocity] applies a downward force. </member> <member name="free_mode_min_slide_angle" type="float" setter="set_free_mode_min_slide_angle" getter="get_free_mode_min_slide_angle" default="0.261799"> Minimum angle (in radians) where the body is allowed to slide when it encounters a slope. The default value equals 15 degrees. </member> - <member name="linear_velocity" type="Vector2" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector2(0, 0)"> - Current velocity vector in pixels per second, used and modified during calls to [method move_and_slide]. - </member> <member name="max_slides" type="int" setter="set_max_slides" getter="get_max_slides" default="4"> Maximum number of times the body can change direction before it stops when calling [method move_and_slide]. </member> <member name="motion_mode" type="int" setter="set_motion_mode" getter="get_motion_mode" enum="CharacterBody2D.MotionMode" default="0"> Sets the motion mode which defines the behaviour of [method move_and_slide]. See [enum MotionMode] constants for available modes. </member> + <member name="motion_velocity" type="Vector2" setter="set_motion_velocity" getter="get_motion_velocity" default="Vector2(0, 0)"> + Current velocity vector in pixels per second, used and modified during calls to [method move_and_slide]. + </member> + <member name="moving_platform_apply_velocity_on_leave" type="int" setter="set_moving_platform_apply_velocity_on_leave" getter="get_moving_platform_apply_velocity_on_leave" enum="CharacterBody2D.MovingPlatformApplyVelocityOnLeave" default="0"> + Sets the behaviour to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for available behaviour. + </member> <member name="moving_platform_floor_layers" type="int" setter="set_moving_platform_floor_layers" getter="get_moving_platform_floor_layers" default="4294967295"> Collision layers that will be included for detecting floor bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all floor bodies are detected and propagate their velocity. </member> @@ -172,5 +200,14 @@ <constant name="MOTION_MODE_FREE" value="1" enum="MotionMode"> Apply when there is no notion of floor or ceiling. All collisions will be reported as [code]on_wall[/code]. In this mode, when you slide, the speed will always be constant. This mode is suitable for top-down games. </constant> + <constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave"> + Add the last platform velocity to the [member motion_velocity] when you leave a moving platform. + </constant> + <constant name="PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY" value="1" enum="MovingPlatformApplyVelocityOnLeave"> + Add the last platform velocity to the [member motion_velocity] when you leave a moving platform, but any downward motion is ignored. It's useful to keep full jump height even when the platform is moving down. + </constant> + <constant name="PLATFORM_VEL_ON_LEAVE_NEVER" value="2" enum="MovingPlatformApplyVelocityOnLeave"> + Do nothing when leaving a platform. + </constant> </constants> </class> diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml index 66d9940b60..24b26fb16e 100644 --- a/doc/classes/CharacterBody3D.xml +++ b/doc/classes/CharacterBody3D.xml @@ -32,7 +32,7 @@ <method name="get_last_motion" qualifiers="const"> <return type="Vector3" /> <description> - Returns the last motion applied to the [CharacterBody3D] during the last call to [method move_and_slide]. The movement can be split if needed into multiple motion, this method return the last one, it's useful to retrieve the current direction of the movement. + Returns the last motion applied to the [CharacterBody3D] during the last call to [method move_and_slide]. The movement can be split into multiple motions when sliding occurs, and this method return the last one, which is useful to retrieve the current direction of the movement. </description> </method> <method name="get_last_slide_collision"> @@ -56,7 +56,7 @@ <method name="get_real_velocity" qualifiers="const"> <return type="Vector3" /> <description> - Returns the current real velocity since the last call to [method move_and_slide]. For example, when you climb a slope, you will move diagonally even though the velocity is horizontal. This method returns the diagonal movement, as opposed to [member linear_velocity] which returns the requested velocity. + Returns the current real velocity since the last call to [method move_and_slide]. For example, when you climb a slope, you will move diagonally even though the velocity is horizontal. This method returns the diagonal movement, as opposed to [member motion_velocity] which returns the requested velocity. </description> </method> <method name="get_slide_collision"> @@ -117,9 +117,9 @@ <method name="move_and_slide"> <return type="bool" /> <description> - Moves the body based on [member linear_velocity]. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [CharacterBody3D] or [RigidDynamicBody3D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. + Moves the body based on [member motion_velocity]. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [CharacterBody3D] or [RigidDynamicBody3D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed. - Modifies [member linear_velocity] if a slide collision occurred. To get the latest collision call [method get_last_slide_collision], for more detailed information about collisions that occurred, use [method get_slide_collision]. + Modifies [member motion_velocity] if a slide collision occurred. To get the latest collision call [method get_last_slide_collision], for more detailed information about collisions that occurred, use [method get_slide_collision]. When the body touches a moving platform, the platform's velocity is automatically added to the body motion. If a collision occurs due to the platform's motion, it will always be first in the slide collisions. Returns [code]true[/code] if the body collided, otherwise, returns [code]false[/code]. </description> @@ -147,10 +147,8 @@ As long as the snapping vector is in contact with the ground and the body moves against `up_direction`, the body will remain attached to the surface. Snapping is not applied if the body moves along `up_direction`, so it will be able to detach from the ground when jumping. </member> <member name="floor_stop_on_slope" type="bool" setter="set_floor_stop_on_slope_enabled" getter="is_floor_stop_on_slope_enabled" default="true"> - If [code]true[/code], the body will not slide on slopes when you include gravity in [code]linear_velocity[/code] when calling [method move_and_slide] and the body is standing still. - </member> - <member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector3(0, 0, 0)"> - Current velocity vector (typically meters per second), used and modified during calls to [method move_and_slide]. + If [code]true[/code], the body will not slide on slopes when calling [method move_and_slide] when the body is standing still. + If [code]false[/code], the body will slide on floor's slopes when [member motion_velocity] applies a downward force. </member> <member name="max_slides" type="int" setter="set_max_slides" getter="get_max_slides" default="6"> Maximum number of times the body can change direction before it stops when calling [method move_and_slide]. @@ -158,6 +156,9 @@ <member name="motion_mode" type="int" setter="set_motion_mode" getter="get_motion_mode" enum="CharacterBody3D.MotionMode" default="0"> Sets the motion mode which defines the behaviour of [method move_and_slide]. See [enum MotionMode] constants for available modes. </member> + <member name="motion_velocity" type="Vector3" setter="set_motion_velocity" getter="get_motion_velocity" default="Vector3(0, 0, 0)"> + Current velocity vector (typically meters per second), used and modified during calls to [method move_and_slide]. + </member> <member name="moving_platform_apply_velocity_on_leave" type="int" setter="set_moving_platform_apply_velocity_on_leave" getter="get_moving_platform_apply_velocity_on_leave" enum="CharacterBody3D.MovingPlatformApplyVelocityOnLeave" default="0"> Sets the behaviour to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for available behaviour. </member> @@ -185,10 +186,10 @@ Apply when there is no notion of floor or ceiling. All collisions will be reported as [code]on_wall[/code]. In this mode, when you slide, the speed will always be constant. This mode is suitable for games without ground like space games. </constant> <constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave"> - Add the last platform velocity to the [member linear_velocity] when you leave a moving platform. + Add the last platform velocity to the [member motion_velocity] when you leave a moving platform. </constant> <constant name="PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY" value="1" enum="MovingPlatformApplyVelocityOnLeave"> - Add the last platform velocity to the [member linear_velocity] when you leave a moving platform, but any downward motion is ignored. It's useful to keep full jump height even when the platform is moving down. + Add the last platform velocity to the [member motion_velocity] when you leave a moving platform, but any downward motion is ignored. It's useful to keep full jump height even when the platform is moving down. </constant> <constant name="PLATFORM_VEL_ON_LEAVE_NEVER" value="2" enum="MovingPlatformApplyVelocityOnLeave"> Do nothing when leaving a platform. diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index c9a2de66a8..b00bf1c250 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -742,10 +742,10 @@ </method> <method name="set_drag_forwarding"> <return type="void" /> - <argument index="0" name="target" type="Control" /> + <argument index="0" name="target" type="Node" /> <description> - Forwards the handling of this control's drag and drop to [code]target[/code] control. - Forwarding can be implemented in the target control similar to the methods [method _get_drag_data], [method _can_drop_data], and [method _drop_data] but with two differences: + Forwards the handling of this control's drag and drop to [code]target[/code] node. + Forwarding can be implemented in the target node similar to the methods [method _get_drag_data], [method _can_drop_data], and [method _drop_data] but with two differences: 1. The function name must be suffixed with [b]_fw[/b] 2. The function must take an extra argument that is the control doing the forwarding [codeblocks] diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 0575ea3eef..adc1eab393 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -40,7 +40,7 @@ }; [/csharp] [/codeblocks] - You can access a dictionary's values by referencing the appropriate key. In the above example, [code]points_dir["White"][/code] will return [code]50[/code]. You can also write [code]points_dir.White[/code], which is equivalent. However, you'll have to use the bracket syntax if the key you're accessing the dictionary with isn't a fixed string (such as a number or variable). + You can access a dictionary's values by referencing the appropriate key. In the above example, [code]points_dict["White"][/code] will return [code]50[/code]. You can also write [code]points_dict.White[/code], which is equivalent. However, you'll have to use the bracket syntax if the key you're accessing the dictionary with isn't a fixed string (such as a number or variable). [codeblocks] [gdscript] export(string, "White", "Yellow", "Orange") var my_color @@ -72,7 +72,7 @@ my_dict = {"First Array": [1, 2, 3, 4]} # Assigns an Array to a String key. [/gdscript] [csharp] - var myDir = new Godot.Collections.Dictionary + var myDict = new Godot.Collections.Dictionary { {"First Array", new Godot.Collections.Array{1, 2, 3, 4}} }; @@ -85,7 +85,7 @@ points_dict["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value. [/gdscript] [csharp] - var pointsDir = new Godot.Collections.Dictionary + var pointsDict = new Godot.Collections.Dictionary { {"White", 50}, {"Yellow", 75}, @@ -98,7 +98,7 @@ [codeblocks] [gdscript] # This is a valid dictionary. - # To access the string "Nested value" below, use `my_dir.sub_dir.sub_key` or `my_dir["sub_dir"]["sub_key"]`. + # To access the string "Nested value" below, use `my_dict.sub_dict.sub_key` or `my_dict["sub_dict"]["sub_key"]`. # Indexing styles can be mixed and matched depending on your needs. var my_dict = { "String Key": 5, @@ -109,8 +109,7 @@ [/gdscript] [csharp] // This is a valid dictionary. - // To access the string "Nested value" below, use `my_dir.sub_dir.sub_key` or `my_dir["sub_dir"]["sub_key"]`. - // Indexing styles can be mixed and matched depending on your needs. + // To access the string "Nested value" below, use `((Godot.Collections.Dictionary)myDict["sub_dict"])["sub_key"]`. var myDict = new Godot.Collections.Dictionary { {"String Key", 5}, {4, new Godot.Collections.Array{1,2,3}}, @@ -213,7 +212,8 @@ <return type="bool" /> <argument index="0" name="key" type="Variant" /> <description> - Erase a dictionary key/value pair by key. Returns [code]true[/code] if the given key was present in the dictionary, [code]false[/code] otherwise. Does not erase elements while iterating over the dictionary. + Erase a dictionary key/value pair by key. Returns [code]true[/code] if the given key was present in the dictionary, [code]false[/code] otherwise. + [b]Note:[/b] Don't erase elements while iterating over the dictionary. You can iterate over the [method keys] array instead. </description> </method> <method name="get" qualifiers="const"> diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 4f495eaec9..7eff8db59c 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -276,6 +276,14 @@ [b]Note:[/b] This method is implemented on Linux, macOS and Windows. </description> </method> + <method name="keyboard_get_keycode_from_physical" qualifiers="const"> + <return type="int" enum="Key" /> + <argument index="0" name="keycode" type="int" enum="Key" /> + <description> + Converts a physical (US QWERTY) [code]keycode[/code] to one in the active keyboard layout. + [b]Note:[/b] This method is implemented on Linux, macOS and Windows. + </description> + </method> <method name="keyboard_get_layout_count" qualifiers="const"> <return type="int" /> <description> diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index e8ff0f60ec..39881e9eb7 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -103,7 +103,7 @@ <argument index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" /> <argument index="8" name="outline_size" type="int" default="0" /> <argument index="9" name="outline_modulate" type="Color" default="Color(1, 1, 1, 0)" /> - <argument index="10" name="flags" type="int" default="51" /> + <argument index="10" name="flags" type="int" default="99" /> <description> Breaks [code]text[/code] to the lines using rules specified by [code]flags[/code] and draws it into a canvas item using the font, at a given position, with [code]modulate[/code] color, optionally clipping the width and aligning horizontally. [code]position[/code] specifies the baseline of the first line, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. See also [method CanvasItem.draw_multiline_string]. @@ -185,7 +185,7 @@ <argument index="0" name="text" type="String" /> <argument index="1" name="width" type="float" default="-1" /> <argument index="2" name="size" type="int" default="-1" /> - <argument index="3" name="flags" type="int" default="48" /> + <argument index="3" name="flags" type="int" default="96" /> <description> Returns the size of a bounding box of a string broken into the lines, taking kerning and advance into account. See also [method draw_multiline_string]. diff --git a/doc/classes/KinematicCollision2D.xml b/doc/classes/KinematicCollision2D.xml index c558c541ad..29fc4700fd 100644 --- a/doc/classes/KinematicCollision2D.xml +++ b/doc/classes/KinematicCollision2D.xml @@ -25,9 +25,6 @@ <member name="collider_id" type="int" setter="" getter="get_collider_id" default="0"> The colliding body's unique instance ID. See [method Object.get_instance_id]. </member> - <member name="collider_metadata" type="Variant" setter="" getter="get_collider_metadata"> - The colliding body's metadata. See [Object]. - </member> <member name="collider_rid" type="RID" setter="" getter="get_collider_rid"> The colliding body's [RID] used by the [PhysicsServer2D]. </member> diff --git a/doc/classes/KinematicCollision3D.xml b/doc/classes/KinematicCollision3D.xml index db32cf57bc..3db6fe019b 100644 --- a/doc/classes/KinematicCollision3D.xml +++ b/doc/classes/KinematicCollision3D.xml @@ -32,13 +32,6 @@ Returns the collider ID by index (the latest by default). </description> </method> - <method name="get_collider_metadata" qualifiers="const"> - <return type="Variant" /> - <argument index="0" name="collision_index" type="int" default="0" /> - <description> - Returns the collider metadata by index (the latest by default). - </description> - </method> <method name="get_collider_rid" qualifiers="const"> <return type="RID" /> <argument index="0" name="collision_index" type="int" default="0" /> @@ -96,9 +89,6 @@ <member name="collider_id" type="int" setter="" getter="get_best_collider_id" default="0"> The colliding body's unique instance ID. See [method Object.get_instance_id]. </member> - <member name="collider_metadata" type="Variant" setter="" getter="get_best_collider_metadata"> - The colliding body's metadata. See [Object]. - </member> <member name="collider_rid" type="RID" setter="" getter="get_best_collider_rid"> The colliding body's [RID] used by the [PhysicsServer3D]. </member> diff --git a/doc/classes/MultiplayerPeer.xml b/doc/classes/MultiplayerPeer.xml index 15517f7c2f..67d3161aba 100644 --- a/doc/classes/MultiplayerPeer.xml +++ b/doc/classes/MultiplayerPeer.xml @@ -58,7 +58,7 @@ </member> <member name="transfer_channel" type="int" setter="set_transfer_channel" getter="get_transfer_channel" default="0"> The channel to use to send packets. Many network APIs such as ENet and WebRTC allow the creation of multiple independent channels which behaves, in a way, like separate connections. This means that reliable data will only block delivery of other packets on that channel, and ordering will only be in respect to the channel the packet is being sent on. Using different channels to send [b]different and independent[/b] state updates is a common way to optimize network usage and decrease latency in fast-paced games. - [b]Note:[/b] The default channel ([code]0[/code]) actually works as 3 separate channels (one for each [enum TransferMode]) so that [constant TRANSFER_MODE_RELIABLE] and [constant TRANSFER_MODE_ORDERED] does not interact with each other by default. Refer to the specific network API documentation (e.g. ENet or WebRTC) to learn how to set up channels correctly. + [b]Note:[/b] The default channel ([code]0[/code]) actually works as 3 separate channels (one for each [enum TransferMode]) so that [constant TRANSFER_MODE_RELIABLE] and [constant TRANSFER_MODE_UNRELIABLE_ORDERED] does not interact with each other by default. Refer to the specific network API documentation (e.g. ENet or WebRTC) to learn how to set up channels correctly. </member> <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="TransferMode" default="2"> The manner in which to send packets to the [code]target_peer[/code]. See [enum TransferMode]. diff --git a/doc/classes/MultiplayerPeerExtension.xml b/doc/classes/MultiplayerPeerExtension.xml index d9c173a4a1..46f9b22758 100644 --- a/doc/classes/MultiplayerPeerExtension.xml +++ b/doc/classes/MultiplayerPeerExtension.xml @@ -24,7 +24,7 @@ </method> <method name="_get_packet" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="r_buffer" type="const void*" /> + <argument index="0" name="r_buffer" type="const uint8_t **" /> <argument index="1" name="r_buffer_size" type="int32_t*" /> <description> </description> @@ -66,7 +66,7 @@ </method> <method name="_put_packet" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="p_buffer" type="const void*" /> + <argument index="0" name="p_buffer" type="const uint8_t*" /> <argument index="1" name="p_buffer_size" type="int" /> <description> </description> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 608d76cd9f..b4edcf49f4 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -700,9 +700,6 @@ <member name="custom_multiplayer" type="MultiplayerAPI" setter="set_custom_multiplayer" getter="get_custom_multiplayer"> The override to the default [MultiplayerAPI]. Set to [code]null[/code] to use the default [SceneTree] one. </member> - <member name="filename" type="String" setter="set_filename" getter="get_filename"> - When a scene is instantiated from a file, its topmost node contains the filename from which it was loaded. - </member> <member name="multiplayer" type="MultiplayerAPI" setter="" getter="get_multiplayer"> The [MultiplayerAPI] instance associated with this node. Either the [member custom_multiplayer], or the default SceneTree one (if inside tree). </member> @@ -719,6 +716,9 @@ <member name="process_priority" type="int" setter="set_process_priority" getter="get_process_priority" default="0"> The node's priority in the execution order of the enabled processing callbacks (i.e. [constant NOTIFICATION_PROCESS], [constant NOTIFICATION_PHYSICS_PROCESS] and their internal counterparts). Nodes whose process priority value is [i]lower[/i] will have their processing callbacks executed first. </member> + <member name="scene_file_path" type="String" setter="set_scene_file_path" getter="get_scene_file_path"> + If a scene is instantiated from a file, its topmost node contains the absolute file path from which it was loaded in [member scene_file_path] (e.g. [code]res://levels/1.tscn[/code]). Otherwise, [member scene_file_path] is set to an empty string. + </member> </members> <signals> <signal name="ready"> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 9d0d185c42..656fa61af7 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -246,7 +246,7 @@ <method name="get_name" qualifiers="const"> <return type="String" /> <description> - Returns the name of the host OS. Possible values are: [code]"Android"[/code], [code]"iOS"[/code], [code]"HTML5"[/code], [code]"OSX"[/code], [code]"Server"[/code], [code]"Windows"[/code], [code]"UWP"[/code], [code]"X11"[/code]. + Returns the name of the host OS. Possible values are: [code]"Android"[/code], [code]"iOS"[/code], [code]"HTML5"[/code], [code]"macOS"[/code], [code]"Server"[/code], [code]"Windows"[/code], [code]"UWP"[/code], [code]"X11"[/code]. </description> </method> <method name="get_process_id" qualifiers="const"> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index 8e94254a1f..39733baf40 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -43,6 +43,15 @@ Appends a [PackedByteArray] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="int" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="compress" qualifiers="const"> <return type="PackedByteArray" /> <argument index="0" name="compression_mode" type="int" default="0" /> diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index 4bccdcd939..00e670646d 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -43,6 +43,15 @@ Appends a [PackedColorArray] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="Color" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedColorArray" /> <description> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index 51e14ea3d4..2ee2ac44df 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -44,6 +44,15 @@ Appends a [PackedFloat32Array] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="float" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedFloat32Array" /> <description> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index 25c9c025f7..7414bc72fc 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -44,6 +44,15 @@ Appends a [PackedFloat64Array] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="float" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedFloat64Array" /> <description> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index 1a61ce0ead..8ecf4a70ae 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -44,6 +44,15 @@ Appends a [PackedInt32Array] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="int" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedInt32Array" /> <description> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 06f7900237..b82ce79009 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -44,6 +44,15 @@ Appends a [PackedInt64Array] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="int" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedInt64Array" /> <description> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 763ed0cc55..353bbfb827 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -44,6 +44,15 @@ Appends a [PackedStringArray] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="String" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedStringArray" /> <description> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index 3f0797bb59..7b7df221e7 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -44,6 +44,15 @@ Appends a [PackedVector2Array] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="Vector2" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedVector2Array" /> <description> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index 6b950cad61..efbf2169fd 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -43,6 +43,15 @@ Appends a [PackedVector3Array] at the end of this array. </description> </method> + <method name="bsearch"> + <return type="int" /> + <argument index="0" name="value" type="Vector3" /> + <argument index="1" name="before" type="bool" default="true" /> + <description> + Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. + [b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior. + </description> + </method> <method name="duplicate"> <return type="PackedVector3Array" /> <description> diff --git a/doc/classes/PacketPeerExtension.xml b/doc/classes/PacketPeerExtension.xml index 6804053484..f6b925eb30 100644 --- a/doc/classes/PacketPeerExtension.xml +++ b/doc/classes/PacketPeerExtension.xml @@ -19,14 +19,14 @@ </method> <method name="_get_packet" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="r_buffer" type="const void*" /> + <argument index="0" name="r_buffer" type="const uint8_t **" /> <argument index="1" name="r_buffer_size" type="int32_t*" /> <description> </description> </method> <method name="_put_packet" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="p_buffer" type="const void*" /> + <argument index="0" name="p_buffer" type="const uint8_t*" /> <argument index="1" name="p_buffer_size" type="int" /> <description> </description> diff --git a/doc/classes/PhysicsDirectBodyState2D.xml b/doc/classes/PhysicsDirectBodyState2D.xml index bbb708c9b4..aa189f17f4 100644 --- a/doc/classes/PhysicsDirectBodyState2D.xml +++ b/doc/classes/PhysicsDirectBodyState2D.xml @@ -90,13 +90,6 @@ Returns the collider's shape index. </description> </method> - <method name="get_contact_collider_shape_metadata" qualifiers="const"> - <return type="Variant" /> - <argument index="0" name="contact_idx" type="int" /> - <description> - Returns the collided shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method PhysicsServer2D.shape_set_data]. - </description> - </method> <method name="get_contact_collider_velocity_at_position" qualifiers="const"> <return type="Vector2" /> <argument index="0" name="contact_idx" type="int" /> diff --git a/doc/classes/PhysicsDirectSpaceState2D.xml b/doc/classes/PhysicsDirectSpaceState2D.xml index 0264249dab..9aa00022cd 100644 --- a/doc/classes/PhysicsDirectSpaceState2D.xml +++ b/doc/classes/PhysicsDirectSpaceState2D.xml @@ -36,7 +36,6 @@ [b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object. The returned object is a dictionary containing the following fields: [code]collider_id[/code]: The colliding object's ID. [code]linear_velocity[/code]: The colliding object's velocity [Vector2]. If the object is an [Area2D], the result is [code](0, 0)[/code]. - [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method PhysicsServer2D.shape_set_data]. [code]normal[/code]: The object's surface normal at the intersection point. [code]point[/code]: The intersection point. [code]rid[/code]: The intersecting object's [RID]. @@ -55,7 +54,6 @@ Checks whether a point is inside any solid shape. The shapes the point is inside of are returned in an array containing dictionaries with the following fields: [code]collider[/code]: The colliding object. [code]collider_id[/code]: The colliding object's ID. - [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method PhysicsServer2D.shape_set_data]. [code]rid[/code]: The intersecting object's [RID]. [code]shape[/code]: The shape index of the colliding shape. Additionally, the method can take an [code]exclude[/code] array of objects or [RID]s that are to be excluded from collisions, a [code]collision_mask[/code] bitmask representing the physics layers to detect (all layers by default), or booleans to determine if the ray should collide with [PhysicsBody2D]s or [Area2D]s, respectively. @@ -75,7 +73,6 @@ Checks whether a point is inside any solid shape, in a specific canvas layer given by [code]canvas_instance_id[/code]. The shapes the point is inside of are returned in an array containing dictionaries with the following fields: [code]collider[/code]: The colliding object. [code]collider_id[/code]: The colliding object's ID. - [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method PhysicsServer2D.shape_set_data]. [code]rid[/code]: The intersecting object's [RID]. [code]shape[/code]: The shape index of the colliding shape. Additionally, the method can take an [code]exclude[/code] array of objects or [RID]s that are to be excluded from collisions, a [code]collision_mask[/code] bitmask representing the physics layers to detect (all layers by default), or booleans to determine if the ray should collide with [PhysicsBody2D]s or [Area2D]s, respectively. @@ -94,7 +91,6 @@ Intersects a ray in a given space. The returned object is a dictionary with the following fields: [code]collider[/code]: The colliding object. [code]collider_id[/code]: The colliding object's ID. - [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method PhysicsServer2D.shape_set_data]. [code]normal[/code]: The object's surface normal at the intersection point. [code]position[/code]: The intersection point. [code]rid[/code]: The intersecting object's [RID]. @@ -112,7 +108,6 @@ [b]Note:[/b] This method does not take into account the [code]motion[/code] property of the object. The intersected shapes are returned in an array containing dictionaries with the following fields: [code]collider[/code]: The colliding object. [code]collider_id[/code]: The colliding object's ID. - [code]metadata[/code]: The intersecting shape's metadata. This metadata is different from [method Object.get_meta], and is set with [method PhysicsServer2D.shape_set_data]. [code]rid[/code]: The intersecting object's [RID]. [code]shape[/code]: The shape index of the colliding shape. The number of intersections can be limited with the [code]max_results[/code] parameter, to reduce the processing time. diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 791a04e4c2..b5b6a7ea58 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -395,14 +395,6 @@ Returns the number of shapes assigned to a body. </description> </method> - <method name="body_get_shape_metadata" qualifiers="const"> - <return type="Variant" /> - <argument index="0" name="body" type="RID" /> - <argument index="1" name="shape_idx" type="int" /> - <description> - Returns the metadata of a shape of a body. - </description> - </method> <method name="body_get_shape_transform" qualifiers="const"> <return type="Transform2D" /> <argument index="0" name="body" type="RID" /> @@ -562,15 +554,6 @@ Disables shape in body if [code]disable[/code] is [code]true[/code]. </description> </method> - <method name="body_set_shape_metadata"> - <return type="void" /> - <argument index="0" name="body" type="RID" /> - <argument index="1" name="shape_idx" type="int" /> - <argument index="2" name="metadata" type="Variant" /> - <description> - Sets metadata of a shape within a body. This metadata is different from [method Object.set_meta], and can be retrieved on shape queries. - </description> - </method> <method name="body_set_shape_transform"> <return type="void" /> <argument index="0" name="body" type="RID" /> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index b5be04fb01..d40ad80d68 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -185,6 +185,18 @@ <description> </description> </method> + <method name="canvas_item_add_msdf_texture_rect_region"> + <return type="void" /> + <argument index="0" name="item" type="RID" /> + <argument index="1" name="rect" type="Rect2" /> + <argument index="2" name="texture" type="RID" /> + <argument index="3" name="src_rect" type="Rect2" /> + <argument index="4" name="modulate" type="Color" default="Color(1, 1, 1, 1)" /> + <argument index="5" name="outline_size" type="int" default="0" /> + <argument index="6" name="px_range" type="float" default="1.0" /> + <description> + </description> + </method> <method name="canvas_item_add_multimesh"> <return type="void" /> <argument index="0" name="item" type="RID" /> diff --git a/doc/classes/Shortcut.xml b/doc/classes/Shortcut.xml index 9fbe91f38b..f95d069069 100644 --- a/doc/classes/Shortcut.xml +++ b/doc/classes/Shortcut.xml @@ -4,8 +4,8 @@ A shortcut for binding input. </brief_description> <description> - A shortcut for binding input. Shortcuts are commonly used for interacting with a [Control] element from an [InputEvent] (also known as hotkeys). + One shortcut can contain multiple [InputEvent]'s, allowing the possibility of triggering one action with multiple different inputs. </description> <tutorials> </tutorials> @@ -13,27 +13,27 @@ <method name="get_as_text" qualifiers="const"> <return type="String" /> <description> - Returns the shortcut's [InputEvent] as a [String]. + Returns the shortcut's first valid [InputEvent] as a [String]. </description> </method> <method name="has_valid_event" qualifiers="const"> <return type="bool" /> <description> - Returns whether the shortcut has a valid [member event] assigned to it. + Returns whether [member events] contains an [InputEvent] which is valid. </description> </method> <method name="matches_event" qualifiers="const"> <return type="bool" /> <argument index="0" name="event" type="InputEvent" /> <description> - Returns whether the shortcut's [member event] matches [code]event[/code]. + Returns whether any [InputEvent] in [member events] equals [code]event[/code]. </description> </method> </methods> <members> - <member name="event" type="InputEvent" setter="set_event" getter="get_event"> - The shortcut's [InputEvent]. - Generally the [InputEvent] is a keyboard key, though it can be any [InputEvent], including an [InputEventAction]. + <member name="events" type="Array" setter="set_events" getter="get_events" default="[]"> + The shortcut's [InputEvent] array. + Generally the [InputEvent] used is an [InputEventKey], though it can be any [InputEvent], including an [InputEventAction]. </member> </members> </class> diff --git a/doc/classes/StreamPeerExtension.xml b/doc/classes/StreamPeerExtension.xml index 93fda8cf5d..ceb9486a33 100644 --- a/doc/classes/StreamPeerExtension.xml +++ b/doc/classes/StreamPeerExtension.xml @@ -30,7 +30,7 @@ </method> <method name="_put_data" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="p_data" type="const void*" /> + <argument index="0" name="p_data" type="const uint8_t*" /> <argument index="1" name="p_bytes" type="int" /> <argument index="2" name="r_sent" type="int32_t*" /> <description> @@ -38,7 +38,7 @@ </method> <method name="_put_partial_data" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="p_data" type="const void*" /> + <argument index="0" name="p_data" type="const uint8_t*" /> <argument index="1" name="p_bytes" type="int" /> <argument index="2" name="r_sent" type="int32_t*" /> <description> diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index e5b03eb4d4..6a4ec08ec3 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -129,14 +129,14 @@ <return type="void" /> <argument index="0" name="flip" type="bool" default="false" /> <description> - Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted. [method generate_normals] should be called [i]after[/i] generating geometry and [i]before[/i] committing the mesh using [method commit] or [method commit_to_arrays]. + Generates normals from vertices so you do not have to do it manually. If [code]flip[/code] is [code]true[/code], the resulting normals will be inverted. [method generate_normals] should be called [i]after[/i] generating geometry and [i]before[/i] committing the mesh using [method commit] or [method commit_to_arrays]. For correct display of normal-mapped surfaces, you will also have to generate tangents using [method generate_tangents]. [b]Note:[/b] [method generate_normals] only works if the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]. </description> </method> <method name="generate_tangents"> <return type="void" /> <description> - Generates a tangent vector for each vertex. Requires that each vertex have UVs and normals set already. + Generates a tangent vector for each vertex. Requires that each vertex have UVs and normals set already (see [method generate_normals]). </description> </method> <method name="get_custom_format" qualifiers="const"> diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index 3ee3feb365..ded4f0b32f 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -217,18 +217,12 @@ </member> </members> <signals> - <signal name="reposition_active_tab_request"> + <signal name="active_tab_rearranged"> <argument index="0" name="idx_to" type="int" /> <description> Emitted when the active tab is rearranged via mouse drag. See [member drag_to_rearrange_enabled]. </description> </signal> - <signal name="right_button_pressed"> - <argument index="0" name="tab" type="int" /> - <description> - Emitted when a tab is right-clicked. - </description> - </signal> <signal name="tab_changed"> <argument index="0" name="tab" type="int" /> <description> @@ -253,6 +247,12 @@ Emitted when a tab is hovered by the mouse. </description> </signal> + <signal name="tab_rmb_clicked"> + <argument index="0" name="tab" type="int" /> + <description> + Emitted when a tab is right-clicked. + </description> + </signal> </signals> <constants> <constant name="ALIGN_LEFT" value="0" enum="TabAlign"> @@ -281,15 +281,15 @@ </constant> </constants> <theme_items> - <theme_item name="button" data_type="style" type="StyleBox"> + <theme_item name="close" data_type="icon" type="Texture2D"> + The icon for the close button (see [member tab_close_display_policy]). + </theme_item> + <theme_item name="close_bg_highlight" data_type="style" type="StyleBox"> Background of the close button when it's being hovered with the cursor. </theme_item> - <theme_item name="button_pressed" data_type="style" type="StyleBox"> + <theme_item name="close_bg_pressed" data_type="style" type="StyleBox"> Background of the close button when it's being pressed. </theme_item> - <theme_item name="close" data_type="icon" type="Texture2D"> - The icon for the close button (see [member tab_close_display_policy]). - </theme_item> <theme_item name="decrement" data_type="icon" type="Texture2D"> Icon for the left arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the first tab is visible), it appears semi-transparent. </theme_item> @@ -315,7 +315,7 @@ Font color of the other, unselected tabs. </theme_item> <theme_item name="hseparation" data_type="constant" type="int" default="4"> - The horizontal separation between the tabs. + The horizontal separation between the elements inside tabs. </theme_item> <theme_item name="increment" data_type="icon" type="Texture2D"> Icon for the right arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the last tab is visible) it appears semi-transparent. diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml index aa35acdbd2..e06dfee698 100644 --- a/doc/classes/TextParagraph.xml +++ b/doc/classes/TextParagraph.xml @@ -281,7 +281,7 @@ <member name="direction" type="int" setter="set_direction" getter="get_direction" enum="TextServer.Direction" default="0"> Text writing direction. </member> - <member name="flags" type="int" setter="set_flags" getter="get_flags" default="51"> + <member name="flags" type="int" setter="set_flags" getter="get_flags" default="99"> Line breaking and alignment rules. For more info see [TextServer]. </member> <member name="max_lines_visible" type="int" setter="set_max_lines_visible" getter="get_max_lines_visible" default="-1"> diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 7fe9278f2c..18ace85465 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TextServer" inherits="Object" version="4.0"> +<class name="TextServer" inherits="RefCounted" version="4.0"> <brief_description> Interface for the fonts and complex text layouts. </brief_description> @@ -487,8 +487,8 @@ </method> <method name="font_set_data"> <return type="void" /> - <argument index="0" name="data" type="RID" /> - <argument index="1" name="arg1" type="PackedByteArray" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="data" type="PackedByteArray" /> <description> Sets font source data, e.g contents of the dynamic font source file. </description> @@ -714,12 +714,14 @@ <return type="Dictionary" /> <argument index="0" name="font_rid" type="RID" /> <description> + Returns the dictionary of the supported OpenType features. </description> </method> <method name="font_supported_variation_list" qualifiers="const"> <return type="Dictionary" /> <argument index="0" name="font_rid" type="RID" /> <description> + Returns the dictionary of the supported OpenType variation coordinates. </description> </method> <method name="format_number" qualifiers="const"> @@ -737,6 +739,12 @@ Frees an object created by this [TextServer]. </description> </method> + <method name="get_features" qualifiers="const"> + <return type="int" /> + <description> + Returns text server features, see [enum Feature]. + </description> + </method> <method name="get_hex_code_box_size" qualifiers="const"> <return type="Vector2" /> <argument index="0" name="size" type="int" /> @@ -751,6 +759,18 @@ Returns the name of the server interface. </description> </method> + <method name="get_support_data_filename" qualifiers="const"> + <return type="String" /> + <description> + Returns default TextServer database (e.g. ICU break iterators and dictionaries) filename. + </description> + </method> + <method name="get_support_data_info" qualifiers="const"> + <return type="String" /> + <description> + Returns TextServer database (e.g. ICU break iterators and dictionaries) description. + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="rid" type="RID" /> @@ -758,14 +778,14 @@ Returns [code]true[/code] if [code]rid[/code] is valid resource owned by this text server. </description> </method> - <method name="has_feature"> + <method name="has_feature" qualifiers="const"> <return type="bool" /> <argument index="0" name="feature" type="int" enum="TextServer.Feature" /> <description> Returns [code]true[/code] if the server supports a feature. </description> </method> - <method name="is_locale_right_to_left"> + <method name="is_locale_right_to_left" qualifiers="const"> <return type="bool" /> <argument index="0" name="locale" type="String" /> <description> @@ -802,6 +822,14 @@ Returns percent sign used in the [code]language[/code]. </description> </method> + <method name="save_support_data" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="filename" type="String" /> + <description> + Saves optional TextServer database (e.g. ICU break iterators and dictionaries) to the file. + Note: This function is used by during project export, to include TextServer database. + </description> + </method> <method name="shaped_text_add_object"> <return type="bool" /> <argument index="0" name="shaped" type="RID" /> @@ -898,7 +926,7 @@ Returns direction of the text. </description> </method> - <method name="shaped_text_get_dominant_direciton_in_range" qualifiers="const"> + <method name="shaped_text_get_dominant_direction_in_range" qualifiers="const"> <return type="int" enum="TextServer.Direction" /> <argument index="0" name="shaped" type="RID" /> <argument index="1" name="start" type="int" /> @@ -907,30 +935,58 @@ Returns dominant direction of in the range of text. </description> </method> + <method name="shaped_text_get_ellipsis_glyph_count" qualifiers="const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns number of glyphs in the ellipsis. + </description> + </method> + <method name="shaped_text_get_ellipsis_glyphs" qualifiers="const"> + <return type="Array" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns array of the glyphs in the ellipsis. + </description> + </method> + <method name="shaped_text_get_ellipsis_pos" qualifiers="const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns position of the ellipsis. + </description> + </method> + <method name="shaped_text_get_glyph_count" qualifiers="const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns number of glyphs in the buffer. + </description> + </method> <method name="shaped_text_get_glyphs" qualifiers="const"> <return type="Array" /> <argument index="0" name="shaped" type="RID" /> <description> - Returns text glyphs. + Returns text glyphs in the visual order. </description> </method> <method name="shaped_text_get_line_breaks" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <argument index="0" name="shaped" type="RID" /> <argument index="1" name="width" type="float" /> <argument index="2" name="start" type="int" default="0" /> - <argument index="3" name="break_flags" type="int" default="48" /> + <argument index="3" name="break_flags" type="int" default="96" /> <description> Breaks text to the lines and returns character ranges for each line. </description> </method> <method name="shaped_text_get_line_breaks_adv" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <argument index="0" name="shaped" type="RID" /> <argument index="1" name="width" type="PackedFloat32Array" /> <argument index="2" name="start" type="int" default="0" /> <argument index="3" name="once" type="bool" default="true" /> - <argument index="4" name="break_flags" type="int" default="48" /> + <argument index="4" name="break_flags" type="int" default="96" /> <description> Breaks text to the lines and columns. Returns character ranges for each segment. </description> @@ -987,7 +1043,7 @@ </description> </method> <method name="shaped_text_get_selection" qualifiers="const"> - <return type="Array" /> + <return type="PackedVector2Array" /> <argument index="0" name="shaped" type="RID" /> <argument index="1" name="start" type="int" /> <argument index="2" name="end" type="int" /> @@ -1002,6 +1058,13 @@ Returns size of the text. </description> </method> + <method name="shaped_text_get_trim_pos" qualifiers="const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns position of the trim. + </description> + </method> <method name="shaped_text_get_underline_position" qualifiers="const"> <return type="float" /> <argument index="0" name="shaped" type="RID" /> @@ -1024,8 +1087,9 @@ </description> </method> <method name="shaped_text_get_word_breaks" qualifiers="const"> - <return type="Array" /> + <return type="PackedInt32Array" /> <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="grapheme_flags" type="int" /> <description> Breaks text into words and returns array of character ranges. </description> @@ -1053,7 +1117,7 @@ Returns [code]true[/code] if buffer is successfully shaped. </description> </method> - <method name="shaped_text_next_grapheme_pos"> + <method name="shaped_text_next_grapheme_pos" qualifiers="const"> <return type="int" /> <argument index="0" name="shaped" type="RID" /> <argument index="1" name="pos" type="int" /> @@ -1070,7 +1134,7 @@ Trims text if it exceeds the given width. </description> </method> - <method name="shaped_text_prev_grapheme_pos"> + <method name="shaped_text_prev_grapheme_pos" qualifiers="const"> <return type="int" /> <argument index="0" name="shaped" type="RID" /> <argument index="1" name="pos" type="int" /> @@ -1139,6 +1203,13 @@ Note: It is not necessary to call this function manually, buffer will be shaped automatically as soon as any of its output data is requested. </description> </method> + <method name="shaped_text_sort_logical"> + <return type="Array" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns text glyphs in the logical order. + </description> + </method> <method name="shaped_text_substr" qualifiers="const"> <return type="RID" /> <argument index="0" name="shaped" type="RID" /> @@ -1196,18 +1267,24 @@ <constant name="JUSTIFICATION_AFTER_LAST_TAB" value="8" enum="JustificationFlag"> Only apply justification to the part of the text after the last tab. </constant> + <constant name="JUSTIFICATION_CONSTRAIN_ELLIPSIS" value="16" enum="JustificationFlag"> + Apply justification to the trimmed line with ellipsis. + </constant> <constant name="BREAK_NONE" value="0" enum="LineBreakFlag"> Do not break the line. </constant> - <constant name="BREAK_MANDATORY" value="16" enum="LineBreakFlag"> + <constant name="BREAK_MANDATORY" value="32" enum="LineBreakFlag"> Break the line at the line mandatory break characters (e.g. [code]"\n"[/code]). </constant> - <constant name="BREAK_WORD_BOUND" value="32" enum="LineBreakFlag"> + <constant name="BREAK_WORD_BOUND" value="64" enum="LineBreakFlag"> Break the line between the words. </constant> - <constant name="BREAK_GRAPHEME_BOUND" value="64" enum="LineBreakFlag"> + <constant name="BREAK_GRAPHEME_BOUND" value="128" enum="LineBreakFlag"> Break the line between any unconnected graphemes. </constant> + <constant name="BREAK_WORD_BOUND_ADAPTIVE" value="320" enum="LineBreakFlag"> + Break the line between the words, or any unconnected graphemes if line is too short to fit the whole word. + </constant> <constant name="OVERRUN_NO_TRIMMING" value="0" enum="TextOverrunFlag"> No trimming is performed. </constant> @@ -1223,6 +1300,11 @@ <constant name="OVERRUN_ENFORCE_ELLIPSIS" value="8" enum="TextOverrunFlag"> Determines whether the ellipsis at the end of the text is enforced and may not be hidden. </constant> + <constant name="OVERRUN_JUSTIFICATION_AWARE" value="16" enum="TextOverrunFlag"> + </constant> + <constant name="GRAPHEME_IS_VALID" value="1" enum="GraphemeFlag"> + Grapheme is supprted by the font, and can be drawn. + </constant> <constant name="GRAPHEME_IS_RTL" value="2" enum="GraphemeFlag"> Grapheme is part of right-to-left or bottom-to-top run. </constant> diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml new file mode 100644 index 0000000000..29571463d2 --- /dev/null +++ b/doc/classes/TextServerExtension.xml @@ -0,0 +1,1262 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="TextServerExtension" inherits="TextServer" version="4.0"> + <brief_description> + Base class for TextServer custom implementations (plugins). + </brief_description> + <description> + External TextServer implementations should inherit from this class. + </description> + <tutorials> + </tutorials> + <methods> + <method name="_create_font" qualifiers="virtual"> + <return type="RID" /> + <description> + Creates new, empty font cache entry resource. To free the resulting resourec, use [method _free] method. + </description> + </method> + <method name="_create_shaped_text" qualifiers="virtual"> + <return type="RID" /> + <argument index="0" name="direction" type="int" enum="TextServer.Direction" /> + <argument index="1" name="orientation" type="int" enum="TextServer.Orientation" /> + <description> + Creates new buffer for complex text layout, with the given [code]direction[/code] and [code]orientation[/code]. To free the resulting buffer, use [method _free] method. + Note: Direction is ignored if server does not support [code]FEATURE_BIDI_LAYOUT[/code] feature. + Note: Orientation is ignored if server does not support [code]FEATURE_VERTICAL_LAYOUT[/code] feature. + </description> + </method> + <method name="_draw_hex_code_box" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="canvas" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="pos" type="Vector2" /> + <argument index="3" name="index" type="int" /> + <argument index="4" name="color" type="Color" /> + <description> + Draws box displaying character hexadecimal code. Used for replacing missing characters. + </description> + </method> + <method name="_font_clear_glyphs" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <description> + Removes all rendered glyphs information from the cache entry. Note: This function will not remove textures associated with the glyphs, use [method _font_remove_texture] to remove them manually. + </description> + </method> + <method name="_font_clear_kerning_map" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <description> + Removes all kerning overrides. + </description> + </method> + <method name="_font_clear_size_cache" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Removes all font sizes from the cache entry + </description> + </method> + <method name="_font_clear_textures" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <description> + Removes all textures from font cache entry. Note: This function will not remove glyphs associated with the texture, use [method _font_remove_glyph] to remove them manually. + </description> + </method> + <method name="_font_draw_glyph" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="canvas" type="RID" /> + <argument index="2" name="size" type="int" /> + <argument index="3" name="pos" type="Vector2" /> + <argument index="4" name="index" type="int" /> + <argument index="5" name="color" type="Color" /> + <description> + Draws single glyph into a canvas item at the position, using [code]font_rid[/code] at the size [code]size[/code]. + Note: Glyph index is specific to the font, use glyphs indices returned by [method _shaped_text_get_glyphs] or [method _font_get_glyph_index]. + </description> + </method> + <method name="_font_draw_glyph_outline" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="canvas" type="RID" /> + <argument index="2" name="size" type="int" /> + <argument index="3" name="outline_size" type="int" /> + <argument index="4" name="pos" type="Vector2" /> + <argument index="5" name="index" type="int" /> + <argument index="6" name="color" type="Color" /> + <description> + Draws single glyph outline of size [code]outline_size[/code] into a canvas item at the position, using [code]font_rid[/code] at the size [code]size[/code]. + Note: Glyph index is specific to the font, use glyphs indices returned by [method _shaped_text_get_glyphs] or [method _font_get_glyph_index]. + </description> + </method> + <method name="_font_get_ascent" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <description> + Returns the font ascent (number of pixels above the baseline). + </description> + </method> + <method name="_font_get_descent" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <description> + Returns the font descent (number of pixels below the baseline). + </description> + </method> + <method name="_font_get_fixed_size" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns bitmap font fixed size. + </description> + </method> + <method name="_font_get_global_oversampling" qualifiers="virtual const"> + <return type="float" /> + <description> + Returns the font oversampling factor, shared by all fonts in the TextServer. + </description> + </method> + <method name="_font_get_glyph_advance" qualifiers="virtual const"> + <return type="Vector2" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="glyph" type="int" /> + <description> + Returns glyph advance (offset of the next glyph). Note: advance for glyphs outlines is the same as the base glyph advance and is not saved. + </description> + </method> + <method name="_font_get_glyph_contours" qualifiers="virtual const"> + <return type="Dictionary" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="index" type="int" /> + <description> + Returns outline contours of the glyph as a [code]Dictionary[/code] with the following contents: + [code]points[/code] - [PackedVector3Array], containing outline points. [code]x[/code] and [code]y[/code] are point coordinates. [code]z[/code] is the type of the point, using the [enum TextServer.ContourPointTag] values. + [code]contours[/code] - [PackedInt32Array], containing indices the end points of each contour. + [code]orientation[/code] - [bool], contour orientation. If [code]true[/code], clockwise contours must be filled. + </description> + </method> + <method name="_font_get_glyph_index" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="char" type="int" /> + <argument index="3" name="variation_selector" type="int" /> + <description> + Returns the glyph index of a [code]char[/code], optionally modified by the [code]variation_selector[/code]. + </description> + </method> + <method name="_font_get_glyph_list" qualifiers="virtual const"> + <return type="Array" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <description> + Returns list of rendered glyphs in the cache entry. + </description> + </method> + <method name="_font_get_glyph_offset" qualifiers="virtual const"> + <return type="Vector2" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <description> + Returns glyph offset from the baseline. + </description> + </method> + <method name="_font_get_glyph_size" qualifiers="virtual const"> + <return type="Vector2" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <description> + Returns size of the glyph. + </description> + </method> + <method name="_font_get_glyph_texture_idx" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <description> + Returns index of the cache texture containing the glyph. + </description> + </method> + <method name="_font_get_glyph_uv_rect" qualifiers="virtual const"> + <return type="Rect2" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <description> + Returns rectangle in the cache texture containing the glyph. + </description> + </method> + <method name="_font_get_hinting" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns the font hinting mode. Used by dynamic fonts only. + </description> + </method> + <method name="_font_get_kerning" qualifiers="virtual const"> + <return type="Vector2" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="glyph_pair" type="Vector2i" /> + <description> + Returns kerning for the pair of glyphs. + </description> + </method> + <method name="_font_get_kerning_list" qualifiers="virtual const"> + <return type="Array" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <description> + Returns list of the kerning overrides. + </description> + </method> + <method name="_font_get_language_support_override" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="language" type="String" /> + <description> + Returns [code]true[/code] if support override is enabled for the [code]language[/code]. + </description> + </method> + <method name="_font_get_language_support_overrides" qualifiers="virtual"> + <return type="PackedStringArray" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns list of language support overrides. + </description> + </method> + <method name="_font_get_msdf_pixel_range" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Return the width of the range around the shape between the minimum and maximum representable signed distance. + </description> + </method> + <method name="_font_get_msdf_size" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns source font size used to generate MSDF textures. + </description> + </method> + <method name="_font_get_oversampling" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only. + </description> + </method> + <method name="_font_get_scale" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <description> + Returns scaling factor of the color bitmap font. + </description> + </method> + <method name="_font_get_script_support_override" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="script" type="String" /> + <description> + Returns [code]true[/code] if support override is enabled for the [code]script[/code]. + </description> + </method> + <method name="_font_get_script_support_overrides" qualifiers="virtual"> + <return type="PackedStringArray" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns list of script support overrides. + </description> + </method> + <method name="_font_get_size_cache_list" qualifiers="virtual const"> + <return type="Array" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Return list of the font sizes in the cache. Each size is [code]Vector2i[/code] with font size and outline size. + </description> + </method> + <method name="_font_get_spacing" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="spacing" type="int" enum="TextServer.SpacingType" /> + <description> + Returns extra spacing added between glyphs in pixels. + </description> + </method> + <method name="_font_get_supported_chars" qualifiers="virtual const"> + <return type="String" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns a string containing all the characters available in the font. + </description> + </method> + <method name="_font_get_texture_count" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <description> + Returns number of textures used by font cache entry. + </description> + </method> + <method name="_font_get_texture_image" qualifiers="virtual const"> + <return type="Image" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="texture_index" type="int" /> + <description> + Returns font cache texture image data. + </description> + </method> + <method name="_font_get_texture_offsets" qualifiers="virtual const"> + <return type="PackedInt32Array" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="texture_index" type="int" /> + <description> + Returns array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty. + </description> + </method> + <method name="_font_get_underline_position" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <description> + Returns pixel offset of the underline below the baseline. + </description> + </method> + <method name="_font_get_underline_thickness" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <description> + Returns thickness of the underline in pixels. + </description> + </method> + <method name="_font_get_variation_coordinates" qualifiers="virtual const"> + <return type="Dictionary" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns variation coordinates for the specified font cache entry. See [method _font_supported_variation_list] for more info. + </description> + </method> + <method name="_font_has_char" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="char" type="int" /> + <description> + Return [code]true[/code] if a Unicode [code]char[/code] is available in the font. + </description> + </method> + <method name="_font_is_antialiased" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns [code]true[/code] if font 8-bit anitialiased glyph rendering is supported and enabled. + </description> + </method> + <method name="_font_is_force_autohinter" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns [code]true[/code] if auto-hinting is supported and preffered over font built-in hinting. Used by dynamic fonts only. + </description> + </method> + <method name="_font_is_language_supported" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="language" type="String" /> + <description> + Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code). + </description> + </method> + <method name="_font_is_multichannel_signed_distance_field" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns [code]true[/code] if glyphs of all sizes are rendered using single multichannel signed distance field generated from the dynamic font vector data. + </description> + </method> + <method name="_font_is_script_supported" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="script" type="String" /> + <description> + Returns [code]true[/code], if font supports given script (ISO 15924 code). + </description> + </method> + <method name="_font_remove_glyph" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <description> + Removes specified rendered glyph information from the cache entry. Note: This function will not remove textures associated with the glyphs, use [method _font_remove_texture] to remove them manually. + </description> + </method> + <method name="_font_remove_kerning" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="glyph_pair" type="Vector2i" /> + <description> + Removes kerning override for the pair of glyphs. + </description> + </method> + <method name="_font_remove_language_support_override" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="language" type="String" /> + <description> + Remove language support override. + </description> + </method> + <method name="_font_remove_script_support_override" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="script" type="String" /> + <description> + Removes script support override. + </description> + </method> + <method name="_font_remove_size_cache" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <description> + Removes specified font size from the cache entry. + </description> + </method> + <method name="_font_remove_texture" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="texture_index" type="int" /> + <description> + Removes specified texture from font cache entry. Note: This function will not remove glyphs associated with the texture, remove them manually, using [method _font_remove_glyph]. + </description> + </method> + <method name="_font_render_glyph" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="index" type="int" /> + <description> + Renders specified glyph the the font cache texture. + </description> + </method> + <method name="_font_render_range" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="start" type="int" /> + <argument index="3" name="end" type="int" /> + <description> + Renders the range of characters to the font cache texture. + </description> + </method> + <method name="_font_set_antialiased" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="antialiased" type="bool" /> + <description> + If set to [code]true[/code], 8-bit antialiased glyph rendering is used, otherwise 1-bit rendering is used. Used by dynamic fonts only. + </description> + </method> + <method name="_font_set_ascent" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="ascent" type="float" /> + <description> + Sets the font ascent (number of pixels above the baseline). + </description> + </method> + <method name="_font_set_data" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="data" type="PackedByteArray" /> + <description> + Sets font source data, e.g contents of the dynamic font source file. + </description> + </method> + <method name="_font_set_data_ptr" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="data_ptr" type="const uint8_t*" /> + <argument index="2" name="data_size" type="int" /> + <description> + Sets the font descent (number of pixels below the baseline). + </description> + </method> + <method name="_font_set_descent" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="descent" type="float" /> + <description> + Sets bitmap font fixed size. If set to value greater than zero, same cache entry will be used for all font sizes. + </description> + </method> + <method name="_font_set_fixed_size" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="fixed_size" type="int" /> + <description> + If set to [code]true[/code] auto-hinting is preffered over font built-in hinting. + </description> + </method> + <method name="_font_set_force_autohinter" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="force_autohinter" type="bool" /> + <description> + </description> + </method> + <method name="_font_set_global_oversampling" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="oversampling" type="float" /> + <description> + Sets oversampling factor, shared by all font in the TextServer. + Note: This value can be automaticaly changed by display server. + </description> + </method> + <method name="_font_set_glyph_advance" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="glyph" type="int" /> + <argument index="3" name="advance" type="Vector2" /> + <description> + Sets glyph advance (offset of the next glyph). Note: advance for glyphs outlines is the same as the base glyph advance and is not saved. + </description> + </method> + <method name="_font_set_glyph_offset" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <argument index="3" name="offset" type="Vector2" /> + <description> + Sets glyph offset from the baseline. + </description> + </method> + <method name="_font_set_glyph_size" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <argument index="3" name="gl_size" type="Vector2" /> + <description> + Sets size of the glyph. + </description> + </method> + <method name="_font_set_glyph_texture_idx" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <argument index="3" name="texture_idx" type="int" /> + <description> + Sets index of the cache texture containing the glyph. + </description> + </method> + <method name="_font_set_glyph_uv_rect" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="glyph" type="int" /> + <argument index="3" name="uv_rect" type="Rect2" /> + <description> + Sets rectangle in the cache texture containing the glyph. + </description> + </method> + <method name="_font_set_hinting" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="hinting" type="int" enum="TextServer.Hinting" /> + <description> + Sets font hinting mode. Used by dynamic fonts only. + </description> + </method> + <method name="_font_set_kerning" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="glyph_pair" type="Vector2i" /> + <argument index="3" name="kerning" type="Vector2" /> + <description> + Sets kerning for the pair of glyphs. + </description> + </method> + <method name="_font_set_language_support_override" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="language" type="String" /> + <argument index="2" name="supported" type="bool" /> + <description> + Adds override for [method _font_is_language_supported]. + </description> + </method> + <method name="_font_set_msdf_pixel_range" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="msdf_pixel_range" type="int" /> + <description> + Sets the width of the range around the shape between the minimum and maximum representable signed distance. + </description> + </method> + <method name="_font_set_msdf_size" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="msdf_size" type="int" /> + <description> + Sets source font size used to generate MSDF textures. + </description> + </method> + <method name="_font_set_multichannel_signed_distance_field" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="msdf" type="bool" /> + <description> + If set to [code]true[/code], glyphs of all sizes are rendered using single multichannel signed distance field generated from the dynamic font vector data. + </description> + </method> + <method name="_font_set_oversampling" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="oversampling" type="float" /> + <description> + Sets font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only. + </description> + </method> + <method name="_font_set_scale" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="scale" type="float" /> + <description> + Sets scaling factor of the color bitmap font. + </description> + </method> + <method name="_font_set_script_support_override" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="script" type="String" /> + <argument index="2" name="supported" type="bool" /> + <description> + Adds override for [method _font_is_script_supported]. + </description> + </method> + <method name="_font_set_spacing" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="spacing" type="int" enum="TextServer.SpacingType" /> + <argument index="3" name="value" type="int" /> + <description> + Sets extra spacing added between glyphs in pixels. + </description> + </method> + <method name="_font_set_texture_image" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="texture_index" type="int" /> + <argument index="3" name="image" type="Image" /> + <description> + Sets font cache texture image data. + </description> + </method> + <method name="_font_set_texture_offsets" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="Vector2i" /> + <argument index="2" name="texture_index" type="int" /> + <argument index="3" name="offset" type="PackedInt32Array" /> + <description> + Sets array containing the first free pixel in the each column of texture. Should be the same size as texture width or empty. + </description> + </method> + <method name="_font_set_underline_position" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="underline_position" type="float" /> + <description> + Sets pixel offset of the underline below the baseline. + </description> + </method> + <method name="_font_set_underline_thickness" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="size" type="int" /> + <argument index="2" name="underline_thickness" type="float" /> + <description> + Sets thickness of the underline in pixels. + </description> + </method> + <method name="_font_set_variation_coordinates" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="font_rid" type="RID" /> + <argument index="1" name="variation_coordinates" type="Dictionary" /> + <description> + Sets variation coordinates for the specified font cache entry. See [method _font_supported_variation_list] for more info. + </description> + </method> + <method name="_font_supported_feature_list" qualifiers="virtual const"> + <return type="Dictionary" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns the dictionary of the supported OpenType features. + </description> + </method> + <method name="_font_supported_variation_list" qualifiers="virtual const"> + <return type="Dictionary" /> + <argument index="0" name="font_rid" type="RID" /> + <description> + Returns the dictionary of the supported OpenType variation coordinates. + </description> + </method> + <method name="_format_number" qualifiers="virtual const"> + <return type="String" /> + <argument index="0" name="string" type="String" /> + <argument index="1" name="language" type="String" /> + <description> + Converts a number from the Western Arabic (0..9) to the numeral systems used in [code]language[/code]. + </description> + </method> + <method name="_free" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="rid" type="RID" /> + <description> + Frees an object created by this [TextServer]. + </description> + </method> + <method name="_get_features" qualifiers="virtual const"> + <return type="int" /> + <description> + Returns text server features, see [enum TextServer.Feature]. + </description> + </method> + <method name="_get_hex_code_box_size" qualifiers="virtual const"> + <return type="Vector2" /> + <argument index="0" name="size" type="int" /> + <argument index="1" name="index" type="int" /> + <description> + Returns size of the replacement character (box with character hexadecimal code that is drawn in place of invalid characters). + </description> + </method> + <method name="_get_name" qualifiers="virtual const"> + <return type="String" /> + <description> + Returns the name of the server interface. + </description> + </method> + <method name="_get_support_data_filename" qualifiers="virtual const"> + <return type="String" /> + <description> + Returns default TextServer database (e.g. ICU break iterators and dictionaries) filename. + </description> + </method> + <method name="_get_support_data_info" qualifiers="virtual const"> + <return type="String" /> + <description> + Returns TextServer database (e.g. ICU break iterators and dictionaries) description. + </description> + </method> + <method name="_has" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="rid" type="RID" /> + <description> + Returns [code]true[/code] if [code]rid[/code] is valid resource owned by this text server. + </description> + </method> + <method name="_has_feature" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="feature" type="int" enum="TextServer.Feature" /> + <description> + Returns [code]true[/code] if the server supports a feature. + </description> + </method> + <method name="_is_locale_right_to_left" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="locale" type="String" /> + <description> + Returns [code]true[/code] if locale is right-to-left. + </description> + </method> + <method name="_load_support_data" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="filename" type="String" /> + <description> + Loads optional TextServer database (e.g. ICU break iterators and dictionaries). + Note: This function should be called before any other TextServer functions used, otherwise it won't have any effect. + </description> + </method> + <method name="_name_to_tag" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="name" type="String" /> + <description> + Converts readable feature, variation, script or language name to OpenType tag. + </description> + </method> + <method name="_parse_number" qualifiers="virtual const"> + <return type="String" /> + <argument index="0" name="string" type="String" /> + <argument index="1" name="language" type="String" /> + <description> + Converts a number from the numeral systems used in [code]language[/code] to Western Arabic (0..9). + </description> + </method> + <method name="_percent_sign" qualifiers="virtual const"> + <return type="String" /> + <argument index="0" name="language" type="String" /> + <description> + Returns percent sign used in the [code]language[/code]. + </description> + </method> + <method name="_save_support_data" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="filename" type="String" /> + <description> + Saves optional TextServer database (e.g. ICU break iterators and dictionaries) to the file. + Note: This function is used by during project export, to include TextServer database. + </description> + </method> + <method name="_shaped_text_add_object" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="key" type="Variant" /> + <argument index="2" name="size" type="Vector2" /> + <argument index="3" name="inline_align" type="int" enum="InlineAlign" /> + <argument index="4" name="length" type="int" /> + <description> + Adds inline object to the text buffer, [code]key[/code] must be unique. In the text, object is represented as [code]length[/code] object replacement characters. + </description> + </method> + <method name="_shaped_text_add_string" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="text" type="String" /> + <argument index="2" name="fonts" type="Array" /> + <argument index="3" name="size" type="int" /> + <argument index="4" name="opentype_features" type="Dictionary" /> + <argument index="5" name="language" type="String" /> + <description> + Adds text span and font to draw it to the text buffer. + </description> + </method> + <method name="_shaped_text_clear" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Clears text buffer (removes text and inline objects). + </description> + </method> + <method name="_shaped_text_draw" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="canvas" type="RID" /> + <argument index="2" name="pos" type="Vector2" /> + <argument index="3" name="clip_l" type="float" /> + <argument index="4" name="clip_r" type="float" /> + <argument index="5" name="color" type="Color" /> + <description> + Draw shaped text into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). + </description> + </method> + <method name="_shaped_text_draw_outline" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="canvas" type="RID" /> + <argument index="2" name="pos" type="Vector2" /> + <argument index="3" name="clip_l" type="float" /> + <argument index="4" name="clip_r" type="float" /> + <argument index="5" name="outline_size" type="int" /> + <argument index="6" name="color" type="Color" /> + <description> + Draw the outline of the shaped text into a canvas item at a given position, with [code]color[/code]. [code]pos[/code] specifies the leftmost point of the baseline (for horizontal layout) or topmost point of the baseline (for vertical layout). + </description> + </method> + <method name="_shaped_text_fit_to_width" qualifiers="virtual"> + <return type="float" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="width" type="float" /> + <argument index="2" name="jst_flags" type="int" /> + <description> + Adjusts text with to fit to specified width, returns new text width + </description> + </method> + <method name="_shaped_text_get_ascent" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns the text ascent (number of pixels above the baseline for horizontal layout or to the left of baseline for vertical). + Note: overall ascent can be higher than font ascent, if some glyphs are displaced from the baseline. + </description> + </method> + <method name="_shaped_text_get_carets" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="position" type="int" /> + <argument index="2" name="caret" type="CaretInfo*" /> + <description> + Returns shapes of the carets corresponding to the character offset [code]position[/code] in the text. Returned caret shape is 1 pixel wide rectangle. + </description> + </method> + <method name="_shaped_text_get_descent" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns the text descent (number of pixels below the baseline for horizontal layout or to the right of baseline for vertical). + Note: overall descent can be higher than font descent, if some glyphs are displaced from the baseline. + </description> + </method> + <method name="_shaped_text_get_direction" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns direction of the text. + </description> + </method> + <method name="_shaped_text_get_dominant_direction_in_range" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="start" type="int" /> + <argument index="2" name="end" type="int" /> + <description> + Returns dominant direction of in the range of text. + </description> + </method> + <method name="_shaped_text_get_ellipsis_glyph_count" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns number of glyphs in the ellipsis. + </description> + </method> + <method name="_shaped_text_get_ellipsis_glyphs" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="r_glyphs" type="void*" /> + <description> + Returns array of the glyphs in the ellipsis. + </description> + </method> + <method name="_shaped_text_get_ellipsis_pos" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns position of the ellipsis. + </description> + </method> + <method name="_shaped_text_get_glyph_count" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns text glyphs count. + </description> + </method> + <method name="_shaped_text_get_glyphs" qualifiers="virtual const"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="r_glyphs" type="void*" /> + <description> + Copies text glyphs in the visual order, into preallocated array of the size returned by [method _shaped_text_get_glyph_count]. + </description> + </method> + <method name="_shaped_text_get_line_breaks" qualifiers="virtual const"> + <return type="PackedInt32Array" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="width" type="float" /> + <argument index="2" name="start" type="int" /> + <argument index="3" name="break_flags" type="int" /> + <description> + Breaks text to the lines and returns character ranges for each line. + </description> + </method> + <method name="_shaped_text_get_line_breaks_adv" qualifiers="virtual const"> + <return type="PackedInt32Array" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="width" type="PackedFloat32Array" /> + <argument index="2" name="start" type="int" /> + <argument index="3" name="once" type="bool" /> + <argument index="4" name="break_flags" type="int" /> + <description> + Breaks text to the lines and columns. Returns character ranges for each segment. + </description> + </method> + <method name="_shaped_text_get_object_rect" qualifiers="virtual const"> + <return type="Rect2" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="key" type="Variant" /> + <description> + Returns bounding rectangle of the inline object. + </description> + </method> + <method name="_shaped_text_get_objects" qualifiers="virtual const"> + <return type="Array" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns array of inline objects. + </description> + </method> + <method name="_shaped_text_get_orientation" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns text orientation. + </description> + </method> + <method name="_shaped_text_get_parent" qualifiers="virtual const"> + <return type="RID" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Sets text orientation. + </description> + </method> + <method name="_shaped_text_get_preserve_control" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns [code]true[/code] if text buffer is configured to display control characters. + </description> + </method> + <method name="_shaped_text_get_preserve_invalid" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns [code]true[/code] if text buffer is configured to display hexadecimal codes in place of invalid characters. + Note: If set to [code]false[/code], nothing is displayed in place of invalid characters. + </description> + </method> + <method name="_shaped_text_get_range" qualifiers="virtual const"> + <return type="Vector2i" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns substring buffer character range in the parent buffer. + </description> + </method> + <method name="_shaped_text_get_selection" qualifiers="virtual const"> + <return type="PackedVector2Array" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="start" type="int" /> + <argument index="2" name="end" type="int" /> + <description> + Returns selection rectangles for the specified character range. + </description> + </method> + <method name="_shaped_text_get_size" qualifiers="virtual const"> + <return type="Vector2" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns size of the text. + </description> + </method> + <method name="_shaped_text_get_trim_pos" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns ellipsis and trim positions. + </description> + </method> + <method name="_shaped_text_get_underline_position" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns pixel offset of the underline below the baseline. + </description> + </method> + <method name="_shaped_text_get_underline_thickness" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns thickness of the underline. + </description> + </method> + <method name="_shaped_text_get_width" qualifiers="virtual const"> + <return type="float" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns width (for horizontal layout) or height (for vertical) of the text. + </description> + </method> + <method name="_shaped_text_get_word_breaks" qualifiers="virtual const"> + <return type="PackedInt32Array" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="grapheme_flags" type="int" /> + <description> + Breaks text into words and returns array of character ranges. + </description> + </method> + <method name="_shaped_text_hit_test_grapheme" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="coord" type="float" /> + <description> + Returns grapheme index at the specified pixel offset at the baseline, or [code]-1[/code] if none is found. + </description> + </method> + <method name="_shaped_text_hit_test_position" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="coord" type="float" /> + <description> + Returns caret character offset at the specified pixel offset at the baseline. This function always returns a valid position. + </description> + </method> + <method name="_shaped_text_is_ready" qualifiers="virtual const"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Returns [code]true[/code] if buffer is successfully shaped. + </description> + </method> + <method name="_shaped_text_next_grapheme_pos" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="pos" type="int" /> + <description> + Returns composite character end position closest to the [code]pos[/code]. + </description> + </method> + <method name="_shaped_text_overrun_trim_to_width" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="width" type="float" /> + <argument index="2" name="trim_flags" type="int" /> + <description> + Trims text if it exceeds the given width. + </description> + </method> + <method name="_shaped_text_prev_grapheme_pos" qualifiers="virtual const"> + <return type="int" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="pos" type="int" /> + <description> + Returns composite character start position closest to the [code]pos[/code]. + </description> + </method> + <method name="_shaped_text_resize_object" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="key" type="Variant" /> + <argument index="2" name="size" type="Vector2" /> + <argument index="3" name="inline_align" type="int" enum="InlineAlign" /> + <description> + Sets new size and alignment of embedded object. + </description> + </method> + <method name="_shaped_text_set_bidi_override" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="override" type="Array" /> + <description> + Overrides BiDi for the structured text. + Override ranges should cover full source text without overlaps. BiDi algorithm will be used on each range separately. + </description> + </method> + <method name="_shaped_text_set_direction" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="direction" type="int" enum="TextServer.Direction" /> + <description> + Sets desired text direction. If set to [code]TEXT_DIRECTION_AUTO[/code], direction will be detected based on the buffer contents and current locale. + Note: Direction is ignored if server does not support [code]FEATURE_BIDI_LAYOUT[/code] feature. + </description> + </method> + <method name="_shaped_text_set_orientation" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="orientation" type="int" enum="TextServer.Orientation" /> + <description> + Sets desired text orientation. + Note: Orientation is ignored if server does not support [code]FEATURE_VERTICAL_LAYOUT[/code] feature. + </description> + </method> + <method name="_shaped_text_set_preserve_control" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="enabled" type="bool" /> + <description> + If set to [code]true[/code] text buffer will display control characters. + </description> + </method> + <method name="_shaped_text_set_preserve_invalid" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="enabled" type="bool" /> + <description> + If set to [code]true[/code] text buffer will display invalid characters as hexadecimal codes, otherwise nothing is displayed. + </description> + </method> + <method name="_shaped_text_shape" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Shapes buffer if it's not shaped. Returns [code]true[/code] if the string is shaped successfully. + Note: It is not necessary to call this function manually, buffer will be shaped automatically as soon as any of its output data is requested. + </description> + </method> + <method name="_shaped_text_sort_logical" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="r_glyphs" type="void*" /> + <description> + Copies text glyphs in the logical order, into preallocated array of the size returned by [method _shaped_text_get_glyph_count]. + </description> + </method> + <method name="_shaped_text_substr" qualifiers="virtual const"> + <return type="RID" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="start" type="int" /> + <argument index="2" name="length" type="int" /> + <description> + Returns text buffer for the substring of the text in the [code]shaped[/code] text buffer (including inline objects). + </description> + </method> + <method name="_shaped_text_tab_align" qualifiers="virtual"> + <return type="float" /> + <argument index="0" name="shaped" type="RID" /> + <argument index="1" name="tab_stops" type="PackedFloat32Array" /> + <description> + Aligns shaped text to the given tab-stops. + </description> + </method> + <method name="_shaped_text_update_breaks" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Updates line and word breaks. + </description> + </method> + <method name="_shaped_text_update_justification_ops" qualifiers="virtual"> + <return type="bool" /> + <argument index="0" name="shaped" type="RID" /> + <description> + Updates justification opportunities (spaces, kashidas, etc.). + </description> + </method> + <method name="_tag_to_name" qualifiers="virtual const"> + <return type="String" /> + <argument index="0" name="tag" type="int" /> + <description> + Converts OpenType tag to readable feature, variation, script or language name. + </description> + </method> + </methods> +</class> diff --git a/doc/classes/TextServerManager.xml b/doc/classes/TextServerManager.xml index 0e7b6d15d3..aa2177c3b1 100644 --- a/doc/classes/TextServerManager.xml +++ b/doc/classes/TextServerManager.xml @@ -10,6 +10,13 @@ <tutorials> </tutorials> <methods> + <method name="add_interface"> + <return type="void" /> + <argument index="0" name="interface" type="TextServer" /> + <description> + Registers an [TextServer] interface. + </description> + </method> <method name="find_interface" qualifiers="const"> <return type="TextServer" /> <argument index="0" name="name" type="String" /> @@ -19,7 +26,7 @@ </method> <method name="get_interface" qualifiers="const"> <return type="TextServer" /> - <argument index="0" name="index" type="int" /> + <argument index="0" name="idx" type="int" /> <description> Returns the interface registered at a given index. </description> @@ -30,20 +37,6 @@ Returns the number of interfaces currently registered. </description> </method> - <method name="get_interface_features" qualifiers="const"> - <return type="int" /> - <argument index="0" name="index" type="int" /> - <description> - Returns text server supported features (binary OR). - </description> - </method> - <method name="get_interface_name" qualifiers="const"> - <return type="String" /> - <argument index="0" name="index" type="int" /> - <description> - Returns the interface name registered at a given index. - </description> - </method> <method name="get_interfaces" qualifiers="const"> <return type="Array" /> <description> @@ -53,15 +46,36 @@ <method name="get_primary_interface" qualifiers="const"> <return type="TextServer" /> <description> - Returns the primary [TextServer] interface. + Returns the primary [TextServer] interface currently in use. + </description> + </method> + <method name="remove_interface"> + <return type="void" /> + <argument index="0" name="interface" type="TextServer" /> + <description> + Removes interface. All fonts and shaped text caches should be freed before removing interface. </description> </method> <method name="set_primary_interface"> - <return type="bool" /> - <argument index="0" name="index" type="int" /> + <return type="void" /> + <argument index="0" name="index" type="TextServer" /> <description> - Sets (and initializes it if required) interface registered at a given index as the primary. Invalidates all references to the fonts and text buffers. + Sets the primary [TextServer] interface. </description> </method> </methods> + <signals> + <signal name="interface_added"> + <argument index="0" name="interface_name" type="StringName" /> + <description> + Emitted when a new interface has been added. + </description> + </signal> + <signal name="interface_removed"> + <argument index="0" name="interface_name" type="StringName" /> + <description> + Emitted when an interface is removed. + </description> + </signal> + </signals> </class> diff --git a/doc/classes/TileData.xml b/doc/classes/TileData.xml index 0d3282c6d3..81c5743ccc 100644 --- a/doc/classes/TileData.xml +++ b/doc/classes/TileData.xml @@ -37,6 +37,20 @@ Returns how many polygons the tile has for TileSet physics layer with index [code]layer_id[/code]. </description> </method> + <method name="get_constant_angular_velocity" qualifiers="const"> + <return type="float" /> + <argument index="0" name="layer_id" type="int" /> + <description> + Returns the constant angular velocity applied to objects colliding with this tile. + </description> + </method> + <method name="get_constant_linear_velocity" qualifiers="const"> + <return type="Vector2" /> + <argument index="0" name="layer_id" type="int" /> + <description> + Returns the constant linear velocity applied to objects colliding with this tile. + </description> + </method> <method name="get_custom_data" qualifiers="const"> <return type="Variant" /> <argument index="0" name="layer_name" type="String" /> @@ -123,6 +137,22 @@ Sets the polygons count for TileSet physics layer with index [code]layer_id[/code]. </description> </method> + <method name="set_constant_angular_velocity"> + <return type="void" /> + <argument index="0" name="layer_id" type="int" /> + <argument index="1" name="velocity" type="float" /> + <description> + Sets the constant angular velocity. This does not rotate the tile. This angular velocity is applied to objects colliding with this tile. + </description> + </method> + <method name="set_constant_linear_velocity"> + <return type="void" /> + <argument index="0" name="layer_id" type="int" /> + <argument index="1" name="velocity" type="Vector2" /> + <description> + Sets the constant linear velocity. This does not move the tile. This linear velocity is applied to objects colliding with this tile. This is useful to create conveyor belts. + </description> + </method> <method name="set_custom_data"> <return type="void" /> <argument index="0" name="layer_name" type="String" /> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 4621d138ac..e5fe823be6 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -29,6 +29,13 @@ Clears all cells. </description> </method> + <method name="clear_layer"> + <return type="void" /> + <argument index="0" name="layer" type="int" /> + <description> + Clears all cells on the given layer. + </description> + </method> <method name="fix_invalid_tiles"> <return type="void" /> <description> @@ -62,6 +69,13 @@ Returns the tile source ID of the cell on layer [code]layer[/code] at coordinates [code]coords[/code]. If [code]use_proxies[/code] is [code]false[/code], ignores the [TileSet]'s tile proxies, returning the raw alternative identifier. See [method TileSet.map_tile_proxy]. </description> </method> + <method name="get_coords_for_body_rid"> + <return type="Vector2i" /> + <argument index="0" name="body" type="RID" /> + <description> + Returns the coodinates of the tile for given physics body RID. Such RID can be retrieved from [member KinematicCollision2D.collider_rid], when colliding with a tile. + </description> + </method> <method name="get_layer_name" qualifiers="const"> <return type="String" /> <argument index="0" name="layer" type="int" /> @@ -220,6 +234,10 @@ <member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" default="16"> The TileMap's quadrant size. Optimizes drawing by batching, using chunks of this size. </member> + <member name="collision_animatable" type="bool" setter="set_collision_animatable" getter="is_collision_animatable" default="false"> + If enabled, the TileMap will see its collisions synced to the physics tick and change its collision type from static to kinematic. This is required to create TileMap-based moving platform. + [b]Note:[/b] Enabling [code]collision_animatable[/code] may have a small performance impact, only do it if the TileMap is moving and has colliding tiles. + </member> <member name="collision_visibility_mode" type="int" setter="set_collision_visibility_mode" getter="get_collision_visibility_mode" enum="TileMap.VisibilityMode" default="0"> Show or hide the TileMap's collision shapes. If set to [code]VISIBILITY_MODE_DEFAULT[/code], this depends on the show collision debug settings. </member> diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index e01c6a0e0f..768b819650 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -258,8 +258,8 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IPAddress p_ip, Str uint32_t if_v6id = 0; Map<String, IP::Interface_Info> if_info; IP::get_singleton()->get_local_interfaces(&if_info); - for (Map<String, IP::Interface_Info>::Element *E = if_info.front(); E; E = E->next()) { - IP::Interface_Info &c = E->get(); + for (KeyValue<String, IP::Interface_Info> &E : if_info) { + IP::Interface_Info &c = E.value; if (c.name != p_if_name) { continue; } diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index f8fc949220..8743135f89 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -47,7 +47,7 @@ RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &r_stage_mask, VkAccessFlags &r_access_mask, uint32_t p_post_barrier) { Buffer *buffer = nullptr; if (vertex_buffer_owner.owns(p_buffer)) { - buffer = vertex_buffer_owner.getornull(p_buffer); + buffer = vertex_buffer_owner.get_or_null(p_buffer); r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; r_access_mask |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; @@ -64,7 +64,7 @@ RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID } else if (index_buffer_owner.owns(p_buffer)) { r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; r_access_mask |= VK_ACCESS_INDEX_READ_BIT; - buffer = index_buffer_owner.getornull(p_buffer); + buffer = index_buffer_owner.get_or_null(p_buffer); } else if (uniform_buffer_owner.owns(p_buffer)) { if (p_post_barrier & BARRIER_MASK_RASTER) { r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; @@ -73,7 +73,7 @@ RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID r_stage_mask |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; } r_access_mask |= VK_ACCESS_UNIFORM_READ_BIT; - buffer = uniform_buffer_owner.getornull(p_buffer); + buffer = uniform_buffer_owner.get_or_null(p_buffer); } else if (texture_buffer_owner.owns(p_buffer)) { if (p_post_barrier & BARRIER_MASK_RASTER) { r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; @@ -84,9 +84,9 @@ RenderingDeviceVulkan::Buffer *RenderingDeviceVulkan::_get_buffer_from_owner(RID r_access_mask |= VK_ACCESS_SHADER_READ_BIT; } - buffer = &texture_buffer_owner.getornull(p_buffer)->buffer; + buffer = &texture_buffer_owner.get_or_null(p_buffer)->buffer; } else if (storage_buffer_owner.owns(p_buffer)) { - buffer = storage_buffer_owner.getornull(p_buffer); + buffer = storage_buffer_owner.get_or_null(p_buffer); if (p_post_barrier & BARRIER_MASK_RASTER) { r_stage_mask |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; r_access_mask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; @@ -2048,12 +2048,12 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID p_with_texture) { _THREAD_SAFE_METHOD_ - Texture *src_texture = texture_owner.getornull(p_with_texture); + Texture *src_texture = texture_owner.get_or_null(p_with_texture); ERR_FAIL_COND_V(!src_texture, RID()); if (src_texture->owner.is_valid()) { //ahh this is a share p_with_texture = src_texture->owner; - src_texture = texture_owner.getornull(src_texture->owner); + src_texture = texture_owner.get_or_null(src_texture->owner); ERR_FAIL_COND_V(!src_texture, RID()); //this is a bug } @@ -2173,12 +2173,12 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) { _THREAD_SAFE_METHOD_ - Texture *src_texture = texture_owner.getornull(p_with_texture); + Texture *src_texture = texture_owner.get_or_null(p_with_texture); ERR_FAIL_COND_V(!src_texture, RID()); if (src_texture->owner.is_valid()) { //ahh this is a share p_with_texture = src_texture->owner; - src_texture = texture_owner.getornull(src_texture->owner); + src_texture = texture_owner.get_or_null(src_texture->owner); ERR_FAIL_COND_V(!src_texture, RID()); //this is a bug } @@ -2299,12 +2299,12 @@ Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, co ERR_FAIL_COND_V_MSG((draw_list || compute_list) && !p_use_setup_queue, ERR_INVALID_PARAMETER, "Updating textures is forbidden during creation of a draw or compute list"); - Texture *texture = texture_owner.getornull(p_texture); + Texture *texture = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!texture, ERR_INVALID_PARAMETER); if (texture->owner != RID()) { p_texture = texture->owner; - texture = texture_owner.getornull(texture->owner); + texture = texture_owner.get_or_null(texture->owner); ERR_FAIL_COND_V(!texture, ERR_BUG); //this is a bug } @@ -2601,7 +2601,7 @@ Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t p_layer) { _THREAD_SAFE_METHOD_ - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!tex, Vector<uint8_t>()); ERR_FAIL_COND_V_MSG(tex->bound, Vector<uint8_t>(), @@ -2731,7 +2731,7 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t bool RenderingDeviceVulkan::texture_is_shared(RID p_texture) { _THREAD_SAFE_METHOD_ - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!tex, false); return tex->owner.is_valid(); } @@ -2743,7 +2743,7 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) { Size2i RenderingDeviceVulkan::texture_size(RID p_texture) { _THREAD_SAFE_METHOD_ - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!tex, Size2i()); return Size2i(tex->width, tex->height); } @@ -2751,7 +2751,7 @@ Size2i RenderingDeviceVulkan::texture_size(RID p_texture) { Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ - Texture *src_tex = texture_owner.getornull(p_from_texture); + Texture *src_tex = texture_owner.get_or_null(p_from_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER, @@ -2772,7 +2772,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, ERR_FAIL_COND_V(p_src_mipmap >= src_tex->mipmaps, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_src_layer >= src_layer_count, ERR_INVALID_PARAMETER); - Texture *dst_tex = texture_owner.getornull(p_to_texture); + Texture *dst_tex = texture_owner.get_or_null(p_to_texture); ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(dst_tex->bound, ERR_INVALID_PARAMETER, @@ -2939,7 +2939,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ - Texture *src_tex = texture_owner.getornull(p_from_texture); + Texture *src_tex = texture_owner.get_or_null(p_from_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER, @@ -2950,7 +2950,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID ERR_FAIL_COND_V_MSG(src_tex->type != TEXTURE_TYPE_2D, ERR_INVALID_PARAMETER, "Source texture must be 2D (or a slice of a 3D/Cube texture)"); ERR_FAIL_COND_V_MSG(src_tex->samples == TEXTURE_SAMPLES_1, ERR_INVALID_PARAMETER, "Source texture must be multisampled."); - Texture *dst_tex = texture_owner.getornull(p_to_texture); + Texture *dst_tex = texture_owner.get_or_null(p_to_texture); ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(dst_tex->bound, ERR_INVALID_PARAMETER, @@ -3110,7 +3110,7 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ - Texture *src_tex = texture_owner.getornull(p_texture); + Texture *src_tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(src_tex->bound, ERR_INVALID_PARAMETER, @@ -3880,7 +3880,7 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac FramebufferPass pass; for (int i = 0; i < p_texture_attachments.size(); i++) { - Texture *texture = texture_owner.getornull(p_texture_attachments[i]); + Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]); ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture."); ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer"); @@ -3905,7 +3905,7 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex Size2i size; for (int i = 0; i < p_texture_attachments.size(); i++) { - Texture *texture = texture_owner.getornull(p_texture_attachments[i]); + Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]); ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture."); ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer"); @@ -3951,7 +3951,7 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_get_format(RID p_framebuffer) { _THREAD_SAFE_METHOD_ - Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer); + Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_framebuffer); ERR_FAIL_COND_V(!framebuffer, INVALID_ID); return framebuffer->format_id; @@ -4101,7 +4101,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo vertex_array.description = p_vertex_format; vertex_array.max_instances_allowed = 0xFFFFFFFF; //by default as many as you want for (int i = 0; i < p_src_buffers.size(); i++) { - Buffer *buffer = vertex_buffer_owner.getornull(p_src_buffers[i]); + Buffer *buffer = vertex_buffer_owner.get_or_null(p_src_buffers[i]); //validate with buffer { @@ -4197,7 +4197,7 @@ RID RenderingDeviceVulkan::index_array_create(RID p_index_buffer, uint32_t p_ind ERR_FAIL_COND_V(!index_buffer_owner.owns(p_index_buffer), RID()); - IndexBuffer *index_buffer = index_buffer_owner.getornull(p_index_buffer); + IndexBuffer *index_buffer = index_buffer_owner.get_or_null(p_index_buffer); ERR_FAIL_COND_V(p_index_count == 0, RID()); ERR_FAIL_COND_V(p_index_offset + p_index_count > index_buffer->index_count, RID()); @@ -4241,7 +4241,7 @@ static VkShaderStageFlagBits shader_stage_masks[RenderingDevice::SHADER_STAGE_MA String RenderingDeviceVulkan::_shader_uniform_debug(RID p_shader, int p_set) { String ret; - const Shader *shader = shader_owner.getornull(p_shader); + const Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, String()); for (int i = 0; i < shader->sets.size(); i++) { if (p_set >= 0 && i != p_set) { @@ -5272,7 +5272,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ uint32_t RenderingDeviceVulkan::shader_get_vertex_input_attribute_mask(RID p_shader) { _THREAD_SAFE_METHOD_ - const Shader *shader = shader_owner.getornull(p_shader); + const Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, 0); return shader->vertex_input_mask; } @@ -5494,7 +5494,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, ERR_FAIL_COND_V(p_uniforms.size() == 0, RID()); - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RID()); ERR_FAIL_COND_V_MSG(p_shader_set >= (uint32_t)shader->sets.size() || shader->sets[p_shader_set].uniform_info.size() == 0, RID(), @@ -5563,7 +5563,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Vector<VkDescriptorImageInfo> image_info; for (int j = 0; j < uniform.ids.size(); j++) { - VkSampler *sampler = sampler_owner.getornull(uniform.ids[j]); + VkSampler *sampler = sampler_owner.get_or_null(uniform.ids[j]); ERR_FAIL_COND_V_MSG(!sampler, RID(), "Sampler (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid sampler."); VkDescriptorImageInfo img_info; @@ -5596,10 +5596,10 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Vector<VkDescriptorImageInfo> image_info; for (int j = 0; j < uniform.ids.size(); j += 2) { - VkSampler *sampler = sampler_owner.getornull(uniform.ids[j + 0]); + VkSampler *sampler = sampler_owner.get_or_null(uniform.ids[j + 0]); ERR_FAIL_COND_V_MSG(!sampler, RID(), "SamplerBuffer (binding: " + itos(uniform.binding) + ", index " + itos(j + 1) + ") is not a valid sampler."); - Texture *texture = texture_owner.getornull(uniform.ids[j + 1]); + Texture *texture = texture_owner.get_or_null(uniform.ids[j + 1]); ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture."); ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(), @@ -5621,7 +5621,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, mutable_sampled_textures.push_back(texture); } if (texture->owner.is_valid()) { - texture = texture_owner.getornull(texture->owner); + texture = texture_owner.get_or_null(texture->owner); ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen } @@ -5652,7 +5652,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Vector<VkDescriptorImageInfo> image_info; for (int j = 0; j < uniform.ids.size(); j++) { - Texture *texture = texture_owner.getornull(uniform.ids[j]); + Texture *texture = texture_owner.get_or_null(uniform.ids[j]); ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture."); ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(), @@ -5675,7 +5675,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, } if (texture->owner.is_valid()) { - texture = texture_owner.getornull(texture->owner); + texture = texture_owner.get_or_null(texture->owner); ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen } @@ -5705,7 +5705,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Vector<VkDescriptorImageInfo> image_info; for (int j = 0; j < uniform.ids.size(); j++) { - Texture *texture = texture_owner.getornull(uniform.ids[j]); + Texture *texture = texture_owner.get_or_null(uniform.ids[j]); ERR_FAIL_COND_V_MSG(!texture, RID(), "Image (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture."); @@ -5723,7 +5723,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, } if (texture->owner.is_valid()) { - texture = texture_owner.getornull(texture->owner); + texture = texture_owner.get_or_null(texture->owner); ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen } @@ -5755,7 +5755,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Vector<VkBufferView> buffer_view; for (int j = 0; j < uniform.ids.size(); j++) { - TextureBuffer *buffer = texture_buffer_owner.getornull(uniform.ids[j]); + TextureBuffer *buffer = texture_buffer_owner.get_or_null(uniform.ids[j]); ERR_FAIL_COND_V_MSG(!buffer, RID(), "Texture Buffer (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture buffer."); buffer_info.push_back(buffer->buffer.buffer_info); @@ -5786,10 +5786,10 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Vector<VkBufferView> buffer_view; for (int j = 0; j < uniform.ids.size(); j += 2) { - VkSampler *sampler = sampler_owner.getornull(uniform.ids[j + 0]); + VkSampler *sampler = sampler_owner.get_or_null(uniform.ids[j + 0]); ERR_FAIL_COND_V_MSG(!sampler, RID(), "SamplerBuffer (binding: " + itos(uniform.binding) + ", index " + itos(j + 1) + ") is not a valid sampler."); - TextureBuffer *buffer = texture_buffer_owner.getornull(uniform.ids[j + 1]); + TextureBuffer *buffer = texture_buffer_owner.get_or_null(uniform.ids[j + 1]); VkDescriptorImageInfo img_info; img_info.sampler = *sampler; @@ -5821,7 +5821,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, ERR_FAIL_COND_V_MSG(uniform.ids.size() != 1, RID(), "Uniform buffer supplied (binding: " + itos(uniform.binding) + ") must provide one ID (" + itos(uniform.ids.size()) + " provided)."); - Buffer *buffer = uniform_buffer_owner.getornull(uniform.ids[0]); + Buffer *buffer = uniform_buffer_owner.get_or_null(uniform.ids[0]); ERR_FAIL_COND_V_MSG(!buffer, RID(), "Uniform buffer supplied (binding: " + itos(uniform.binding) + ") is invalid."); ERR_FAIL_COND_V_MSG(buffer->size != (uint32_t)set_uniform.length, RID(), @@ -5842,9 +5842,9 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Buffer *buffer = nullptr; if (storage_buffer_owner.owns(uniform.ids[0])) { - buffer = storage_buffer_owner.getornull(uniform.ids[0]); + buffer = storage_buffer_owner.get_or_null(uniform.ids[0]); } else if (vertex_buffer_owner.owns(uniform.ids[0])) { - buffer = vertex_buffer_owner.getornull(uniform.ids[0]); + buffer = vertex_buffer_owner.get_or_null(uniform.ids[0]); ERR_FAIL_COND_V_MSG(!(buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), RID(), "Vertex buffer supplied (binding: " + itos(uniform.binding) + ") was not created with storage flag."); } @@ -5875,7 +5875,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, Vector<VkDescriptorImageInfo> image_info; for (int j = 0; j < uniform.ids.size(); j++) { - Texture *texture = texture_owner.getornull(uniform.ids[j]); + Texture *texture = texture_owner.get_or_null(uniform.ids[j]); ERR_FAIL_COND_V_MSG(!texture, RID(), "InputAttachment (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture."); @@ -5888,7 +5888,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, img_info.imageView = texture->view; if (texture->owner.is_valid()) { - texture = texture_owner.getornull(texture->owner); + texture = texture_owner.get_or_null(texture->owner); ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen } @@ -5977,7 +5977,7 @@ bool RenderingDeviceVulkan::uniform_set_is_valid(RID p_uniform_set) { } void RenderingDeviceVulkan::uniform_set_set_invalidation_callback(RID p_uniform_set, UniformSetInvalidatedCallback p_callback, void *p_userdata) { - UniformSet *us = uniform_set_owner.getornull(p_uniform_set); + UniformSet *us = uniform_set_owner.get_or_null(p_uniform_set); ERR_FAIL_COND(!us); us->invalidated_callback = p_callback; us->invalidated_callback_userdata = p_userdata; @@ -6126,7 +6126,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma _THREAD_SAFE_METHOD_ //needs a shader - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RID()); ERR_FAIL_COND_V_MSG(shader->is_compute, RID(), @@ -6568,7 +6568,7 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader, const Vector<Pi _THREAD_SAFE_METHOD_ //needs a shader - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RID()); ERR_FAIL_COND_V_MSG(!shader->is_compute, RID(), @@ -6779,7 +6779,7 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu framebuffer_create_info.renderPass = version.render_pass; Vector<VkImageView> attachments; for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) { - Texture *texture = texture_owner.getornull(p_framebuffer->texture_ids[i]); + Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]); ERR_FAIL_COND_V(!texture, ERR_BUG); attachments.push_back(texture->view); ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG); @@ -6831,7 +6831,7 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff { int color_index = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { - Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); + Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); VkClearValue clear_value; if (color_index < p_clear_colors.size() && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { @@ -6859,7 +6859,7 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff render_pass_begin.pClearValues = clear_values.ptr(); for (int i = 0; i < p_storage_textures.size(); i++) { - Texture *texture = texture_owner.getornull(p_storage_textures[i]); + Texture *texture = texture_owner.get_or_null(p_storage_textures[i]); ERR_CONTINUE_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), "Supplied storage texture " + itos(i) + " for draw list is not set to be used for storage."); if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) { @@ -6897,7 +6897,7 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff draw_list_unbind_depth_textures = p_final_depth_action != FINAL_ACTION_CONTINUE; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { - Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); + Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); texture->bound = true; draw_list_bound_textures.push_back(framebuffer->texture_ids[i]); } @@ -6909,7 +6909,7 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Vector<VkClearAttachment> clear_attachments; int color_index = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { - Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); + Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); VkClearAttachment clear_at = {}; if (p_clear_color && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { @@ -6952,7 +6952,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); ERR_FAIL_COND_V_MSG(compute_list != nullptr && !compute_list->state.allow_draw_overlap, INVALID_ID, "Only one draw/compute list can be active at the same time."); - Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer); + Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_framebuffer); ERR_FAIL_COND_V(!framebuffer, INVALID_ID); Point2i viewport_offset; @@ -6993,7 +6993,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu int color_count = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { - Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); + Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { color_count++; @@ -7056,7 +7056,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p ERR_FAIL_COND_V(p_splits < 1, ERR_INVALID_DECLARATION); - Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer); + Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_framebuffer); ERR_FAIL_COND_V(!framebuffer, ERR_INVALID_DECLARATION); Point2i viewport_offset; @@ -7091,7 +7091,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p int color_count = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { - Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); + Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]); if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { color_count++; @@ -7192,7 +7192,7 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); #endif - const RenderPipeline *pipeline = render_pipeline_owner.getornull(p_render_pipeline); + const RenderPipeline *pipeline = render_pipeline_owner.get_or_null(p_render_pipeline); ERR_FAIL_COND(!pipeline); #ifdef DEBUG_ENABLED ERR_FAIL_COND(pipeline->validation.framebuffer_format != draw_list_framebuffer_format && pipeline->validation.render_pass != draw_list_current_subpass); @@ -7267,7 +7267,7 @@ void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_ ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); #endif - const UniformSet *uniform_set = uniform_set_owner.getornull(p_uniform_set); + const UniformSet *uniform_set = uniform_set_owner.get_or_null(p_uniform_set); ERR_FAIL_COND(!uniform_set); if (p_index > dl->state.set_count) { @@ -7315,7 +7315,7 @@ void RenderingDeviceVulkan::draw_list_bind_vertex_array(DrawListID p_list, RID p ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); #endif - const VertexArray *vertex_array = vertex_array_owner.getornull(p_vertex_array); + const VertexArray *vertex_array = vertex_array_owner.get_or_null(p_vertex_array); ERR_FAIL_COND(!vertex_array); if (dl->state.vertex_array == p_vertex_array) { @@ -7339,7 +7339,7 @@ void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_ ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); #endif - const IndexArray *index_array = index_array_owner.getornull(p_index_array); + const IndexArray *index_array = index_array_owner.get_or_null(p_index_array); ERR_FAIL_COND(!index_array); if (dl->state.index_array == p_index_array) { @@ -7425,7 +7425,7 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices if (dl->state.sets[i].uniform_set_format == 0) { ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline"); } else if (uniform_set_owner.owns(dl->state.sets[i].uniform_set)) { - UniformSet *us = uniform_set_owner.getornull(dl->state.sets[i].uniform_set); + UniformSet *us = uniform_set_owner.get_or_null(dl->state.sets[i].uniform_set); ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + "):\n" + _shader_uniform_debug(us->shader_id, us->shader_set) + "\nare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(dl->state.pipeline_shader)); } else { ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + ", which was was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(dl->state.pipeline_shader)); @@ -7696,7 +7696,7 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) { vkCmdEndRenderPass(frames[frame].draw_command_buffer); for (int i = 0; i < draw_list_bound_textures.size(); i++) { - Texture *texture = texture_owner.getornull(draw_list_bound_textures[i]); + Texture *texture = texture_owner.get_or_null(draw_list_bound_textures[i]); ERR_CONTINUE(!texture); //wtf if (draw_list_unbind_color_textures && (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) { texture->bound = false; @@ -7744,7 +7744,7 @@ void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) { } for (uint32_t i = 0; i < image_barrier_count; i++) { - Texture *texture = texture_owner.getornull(draw_list_storage_textures[i]); + Texture *texture = texture_owner.get_or_null(draw_list_storage_textures[i]); VkImageMemoryBarrier &image_memory_barrier = image_barriers[i]; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -7810,7 +7810,7 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l ComputeList *cl = compute_list; - const ComputePipeline *pipeline = compute_pipeline_owner.getornull(p_compute_pipeline); + const ComputePipeline *pipeline = compute_pipeline_owner.get_or_null(p_compute_pipeline); ERR_FAIL_COND(!pipeline); if (p_compute_pipeline == cl->state.pipeline) { @@ -7883,7 +7883,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, ERR_FAIL_COND_MSG(!cl->validation.active, "Submitted Compute Lists can no longer be modified."); #endif - UniformSet *uniform_set = uniform_set_owner.getornull(p_uniform_set); + UniformSet *uniform_set = uniform_set_owner.get_or_null(p_uniform_set); ERR_FAIL_COND(!uniform_set); if (p_index > cl->state.set_count) { @@ -8082,7 +8082,7 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t if (cl->state.sets[i].uniform_set_format == 0) { ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline"); } else if (uniform_set_owner.owns(cl->state.sets[i].uniform_set)) { - UniformSet *us = uniform_set_owner.getornull(cl->state.sets[i].uniform_set); + UniformSet *us = uniform_set_owner.get_or_null(cl->state.sets[i].uniform_set); ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + "):\n" + _shader_uniform_debug(us->shader_id, us->shader_set) + "\nare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader)); } else { ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + ", which was was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader)); @@ -8125,7 +8125,7 @@ void RenderingDeviceVulkan::compute_list_dispatch_indirect(ComputeListID p_list, ERR_FAIL_COND(!compute_list); ComputeList *cl = compute_list; - Buffer *buffer = storage_buffer_owner.getornull(p_buffer); + Buffer *buffer = storage_buffer_owner.get_or_null(p_buffer); ERR_FAIL_COND(!buffer); ERR_FAIL_COND_MSG(!(buffer->usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT), "Buffer provided was not created to do indirect dispatch."); @@ -8159,7 +8159,7 @@ void RenderingDeviceVulkan::compute_list_dispatch_indirect(ComputeListID p_list, if (cl->state.sets[i].uniform_set_format == 0) { ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline"); } else if (uniform_set_owner.owns(cl->state.sets[i].uniform_set)) { - UniformSet *us = uniform_set_owner.getornull(cl->state.sets[i].uniform_set); + UniformSet *us = uniform_set_owner.get_or_null(cl->state.sets[i].uniform_set); ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + "):\n" + _shader_uniform_debug(us->shader_id, us->shader_set) + "\nare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader)); } else { ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + ", which was was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader)); @@ -8371,25 +8371,25 @@ void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_frame void RenderingDeviceVulkan::_free_internal(RID p_id) { //push everything so it's disposed of next time this frame index is processed (means, it's safe to do it) if (texture_owner.owns(p_id)) { - Texture *texture = texture_owner.getornull(p_id); + Texture *texture = texture_owner.get_or_null(p_id); frames[frame].textures_to_dispose_of.push_back(*texture); texture_owner.free(p_id); } else if (framebuffer_owner.owns(p_id)) { - Framebuffer *framebuffer = framebuffer_owner.getornull(p_id); + Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_id); frames[frame].framebuffers_to_dispose_of.push_back(*framebuffer); framebuffer_owner.free(p_id); } else if (sampler_owner.owns(p_id)) { - VkSampler *sampler = sampler_owner.getornull(p_id); + VkSampler *sampler = sampler_owner.get_or_null(p_id); frames[frame].samplers_to_dispose_of.push_back(*sampler); sampler_owner.free(p_id); } else if (vertex_buffer_owner.owns(p_id)) { - Buffer *vertex_buffer = vertex_buffer_owner.getornull(p_id); + Buffer *vertex_buffer = vertex_buffer_owner.get_or_null(p_id); frames[frame].buffers_to_dispose_of.push_back(*vertex_buffer); vertex_buffer_owner.free(p_id); } else if (vertex_array_owner.owns(p_id)) { vertex_array_owner.free(p_id); } else if (index_buffer_owner.owns(p_id)) { - IndexBuffer *index_buffer = index_buffer_owner.getornull(p_id); + IndexBuffer *index_buffer = index_buffer_owner.get_or_null(p_id); Buffer b; b.allocation = index_buffer->allocation; b.buffer = index_buffer->buffer; @@ -8400,24 +8400,24 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) { } else if (index_array_owner.owns(p_id)) { index_array_owner.free(p_id); } else if (shader_owner.owns(p_id)) { - Shader *shader = shader_owner.getornull(p_id); + Shader *shader = shader_owner.get_or_null(p_id); frames[frame].shaders_to_dispose_of.push_back(*shader); shader_owner.free(p_id); } else if (uniform_buffer_owner.owns(p_id)) { - Buffer *uniform_buffer = uniform_buffer_owner.getornull(p_id); + Buffer *uniform_buffer = uniform_buffer_owner.get_or_null(p_id); frames[frame].buffers_to_dispose_of.push_back(*uniform_buffer); uniform_buffer_owner.free(p_id); } else if (texture_buffer_owner.owns(p_id)) { - TextureBuffer *texture_buffer = texture_buffer_owner.getornull(p_id); + TextureBuffer *texture_buffer = texture_buffer_owner.get_or_null(p_id); frames[frame].buffers_to_dispose_of.push_back(texture_buffer->buffer); frames[frame].buffer_views_to_dispose_of.push_back(texture_buffer->view); texture_buffer_owner.free(p_id); } else if (storage_buffer_owner.owns(p_id)) { - Buffer *storage_buffer = storage_buffer_owner.getornull(p_id); + Buffer *storage_buffer = storage_buffer_owner.get_or_null(p_id); frames[frame].buffers_to_dispose_of.push_back(*storage_buffer); storage_buffer_owner.free(p_id); } else if (uniform_set_owner.owns(p_id)) { - UniformSet *uniform_set = uniform_set_owner.getornull(p_id); + UniformSet *uniform_set = uniform_set_owner.get_or_null(p_id); frames[frame].uniform_sets_to_dispose_of.push_back(*uniform_set); if (uniform_set->invalidated_callback != nullptr) { uniform_set->invalidated_callback(p_id, uniform_set->invalidated_callback_userdata); @@ -8425,11 +8425,11 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) { uniform_set_owner.free(p_id); } else if (render_pipeline_owner.owns(p_id)) { - RenderPipeline *pipeline = render_pipeline_owner.getornull(p_id); + RenderPipeline *pipeline = render_pipeline_owner.get_or_null(p_id); frames[frame].render_pipelines_to_dispose_of.push_back(*pipeline); render_pipeline_owner.free(p_id); } else if (compute_pipeline_owner.owns(p_id)) { - ComputePipeline *pipeline = compute_pipeline_owner.getornull(p_id); + ComputePipeline *pipeline = compute_pipeline_owner.get_or_null(p_id); frames[frame].compute_pipelines_to_dispose_of.push_back(*pipeline); compute_pipeline_owner.free(p_id); } else { @@ -8448,49 +8448,49 @@ void RenderingDeviceVulkan::free(RID p_id) { // We just expose the resources that are owned and can be accessed easily. void RenderingDeviceVulkan::set_resource_name(RID p_id, const String p_name) { if (texture_owner.owns(p_id)) { - Texture *texture = texture_owner.getornull(p_id); + Texture *texture = texture_owner.get_or_null(p_id); if (texture->owner.is_null()) { // Don't set the source texture's name when calling on a texture view context->set_object_name(VK_OBJECT_TYPE_IMAGE, uint64_t(texture->image), p_name); } context->set_object_name(VK_OBJECT_TYPE_IMAGE_VIEW, uint64_t(texture->view), p_name + " View"); } else if (framebuffer_owner.owns(p_id)) { - //Framebuffer *framebuffer = framebuffer_owner.getornull(p_id); + //Framebuffer *framebuffer = framebuffer_owner.get_or_null(p_id); // Not implemented for now as the relationship between Framebuffer and RenderPass is very complex } else if (sampler_owner.owns(p_id)) { - VkSampler *sampler = sampler_owner.getornull(p_id); + VkSampler *sampler = sampler_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_SAMPLER, uint64_t(*sampler), p_name); } else if (vertex_buffer_owner.owns(p_id)) { - Buffer *vertex_buffer = vertex_buffer_owner.getornull(p_id); + Buffer *vertex_buffer = vertex_buffer_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(vertex_buffer->buffer), p_name); } else if (index_buffer_owner.owns(p_id)) { - IndexBuffer *index_buffer = index_buffer_owner.getornull(p_id); + IndexBuffer *index_buffer = index_buffer_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(index_buffer->buffer), p_name); } else if (shader_owner.owns(p_id)) { - Shader *shader = shader_owner.getornull(p_id); + Shader *shader = shader_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(shader->pipeline_layout), p_name + " Pipeline Layout"); for (int i = 0; i < shader->sets.size(); i++) { context->set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, uint64_t(shader->sets[i].descriptor_set_layout), p_name); } } else if (uniform_buffer_owner.owns(p_id)) { - Buffer *uniform_buffer = uniform_buffer_owner.getornull(p_id); + Buffer *uniform_buffer = uniform_buffer_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(uniform_buffer->buffer), p_name); } else if (texture_buffer_owner.owns(p_id)) { - TextureBuffer *texture_buffer = texture_buffer_owner.getornull(p_id); + TextureBuffer *texture_buffer = texture_buffer_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(texture_buffer->buffer.buffer), p_name); context->set_object_name(VK_OBJECT_TYPE_BUFFER_VIEW, uint64_t(texture_buffer->view), p_name + " View"); } else if (storage_buffer_owner.owns(p_id)) { - Buffer *storage_buffer = storage_buffer_owner.getornull(p_id); + Buffer *storage_buffer = storage_buffer_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_BUFFER, uint64_t(storage_buffer->buffer), p_name); } else if (uniform_set_owner.owns(p_id)) { - UniformSet *uniform_set = uniform_set_owner.getornull(p_id); + UniformSet *uniform_set = uniform_set_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET, uint64_t(uniform_set->descriptor_set), p_name); } else if (render_pipeline_owner.owns(p_id)) { - RenderPipeline *pipeline = render_pipeline_owner.getornull(p_id); + RenderPipeline *pipeline = render_pipeline_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_PIPELINE, uint64_t(pipeline->pipeline), p_name); context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(pipeline->pipeline_layout), p_name + " Layout"); } else if (compute_pipeline_owner.owns(p_id)) { - ComputePipeline *pipeline = compute_pipeline_owner.getornull(p_id); + ComputePipeline *pipeline = compute_pipeline_owner.get_or_null(p_id); context->set_object_name(VK_OBJECT_TYPE_PIPELINE, uint64_t(pipeline->pipeline), p_name); context->set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, uint64_t(pipeline->pipeline_layout), p_name + " Layout"); } else { @@ -8688,10 +8688,10 @@ void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { while (frames[p_frame].framebuffers_to_dispose_of.front()) { Framebuffer *framebuffer = &frames[p_frame].framebuffers_to_dispose_of.front()->get(); - for (Map<Framebuffer::VersionKey, Framebuffer::Version>::Element *E = framebuffer->framebuffers.front(); E; E = E->next()) { + for (const KeyValue<Framebuffer::VersionKey, Framebuffer::Version> &E : framebuffer->framebuffers) { //first framebuffer, then render pass because it depends on it - vkDestroyFramebuffer(device, E->get().framebuffer, nullptr); - vkDestroyRenderPass(device, E->get().render_pass, nullptr); + vkDestroyFramebuffer(device, E.value.framebuffer, nullptr); + vkDestroyRenderPass(device, E.value.render_pass, nullptr); } frames[p_frame].framebuffers_to_dispose_of.pop_front(); @@ -9037,31 +9037,31 @@ uint64_t RenderingDeviceVulkan::get_driver_resource(DriverResource p_resource, R return context->get_graphics_queue_family_index(); }; break; case DRIVER_RESOURCE_VULKAN_IMAGE: { - Texture *tex = texture_owner.getornull(p_rid); + Texture *tex = texture_owner.get_or_null(p_rid); ERR_FAIL_NULL_V(tex, 0); return (uint64_t)tex->image; }; break; case DRIVER_RESOURCE_VULKAN_IMAGE_VIEW: { - Texture *tex = texture_owner.getornull(p_rid); + Texture *tex = texture_owner.get_or_null(p_rid); ERR_FAIL_NULL_V(tex, 0); return (uint64_t)tex->view; }; break; case DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT: { - Texture *tex = texture_owner.getornull(p_rid); + Texture *tex = texture_owner.get_or_null(p_rid); ERR_FAIL_NULL_V(tex, 0); return vulkan_formats[tex->format]; }; break; case DRIVER_RESOURCE_VULKAN_SAMPLER: { - VkSampler *sampler = sampler_owner.getornull(p_rid); + VkSampler *sampler = sampler_owner.get_or_null(p_rid); ERR_FAIL_NULL_V(sampler, 0); return uint64_t(*sampler); }; break; case DRIVER_RESOURCE_VULKAN_DESCRIPTOR_SET: { - UniformSet *uniform_set = uniform_set_owner.getornull(p_rid); + UniformSet *uniform_set = uniform_set_owner.get_or_null(p_rid); ERR_FAIL_NULL_V(uniform_set, 0); return uint64_t(uniform_set->descriptor_set); @@ -9069,15 +9069,15 @@ uint64_t RenderingDeviceVulkan::get_driver_resource(DriverResource p_resource, R case DRIVER_RESOURCE_VULKAN_BUFFER: { Buffer *buffer = nullptr; if (vertex_buffer_owner.owns(p_rid)) { - buffer = vertex_buffer_owner.getornull(p_rid); + buffer = vertex_buffer_owner.get_or_null(p_rid); } else if (index_buffer_owner.owns(p_rid)) { - buffer = index_buffer_owner.getornull(p_rid); + buffer = index_buffer_owner.get_or_null(p_rid); } else if (uniform_buffer_owner.owns(p_rid)) { - buffer = uniform_buffer_owner.getornull(p_rid); + buffer = uniform_buffer_owner.get_or_null(p_rid); } else if (texture_buffer_owner.owns(p_rid)) { - buffer = &texture_buffer_owner.getornull(p_rid)->buffer; + buffer = &texture_buffer_owner.get_or_null(p_rid)->buffer; } else if (storage_buffer_owner.owns(p_rid)) { - buffer = storage_buffer_owner.getornull(p_rid); + buffer = storage_buffer_owner.get_or_null(p_rid); } ERR_FAIL_NULL_V(buffer, 0); @@ -9085,13 +9085,13 @@ uint64_t RenderingDeviceVulkan::get_driver_resource(DriverResource p_resource, R return uint64_t(buffer->buffer); }; break; case DRIVER_RESOURCE_VULKAN_COMPUTE_PIPELINE: { - ComputePipeline *compute_pipeline = compute_pipeline_owner.getornull(p_rid); + ComputePipeline *compute_pipeline = compute_pipeline_owner.get_or_null(p_rid); ERR_FAIL_NULL_V(compute_pipeline, 0); return uint64_t(compute_pipeline->pipeline); }; break; case DRIVER_RESOURCE_VULKAN_RENDER_PIPELINE: { - RenderPipeline *render_pipeline = render_pipeline_owner.getornull(p_rid); + RenderPipeline *render_pipeline = render_pipeline_owner.get_or_null(p_rid); ERR_FAIL_NULL_V(render_pipeline, 0); return uint64_t(render_pipeline->pipeline); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index bb0123e536..152efc7807 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1755,8 +1755,8 @@ Error VulkanContext::prepare_buffers() { vkWaitForFences(device, 1, &fences[frame_index], VK_TRUE, UINT64_MAX); vkResetFences(device, 1, &fences[frame_index]); - for (Map<int, Window>::Element *E = windows.front(); E; E = E->next()) { - Window *w = &E->get(); + for (KeyValue<int, Window> &E : windows) { + Window *w = &E.value; w->semaphore_acquired = false; @@ -1837,8 +1837,8 @@ Error VulkanContext::swap_buffers() { VkSemaphore *semaphores_to_acquire = (VkSemaphore *)alloca(windows.size() * sizeof(VkSemaphore)); uint32_t semaphores_to_acquire_count = 0; - for (Map<int, Window>::Element *E = windows.front(); E; E = E->next()) { - Window *w = &E->get(); + for (KeyValue<int, Window> &E : windows) { + Window *w = &E.value; if (w->semaphore_acquired) { semaphores_to_acquire[semaphores_to_acquire_count++] = w->image_acquired_semaphores[frame_index]; @@ -1876,8 +1876,8 @@ Error VulkanContext::swap_buffers() { VkCommandBuffer *cmdbufptr = (VkCommandBuffer *)alloca(sizeof(VkCommandBuffer *) * windows.size()); submit_info.pCommandBuffers = cmdbufptr; - for (Map<int, Window>::Element *E = windows.front(); E; E = E->next()) { - Window *w = &E->get(); + for (KeyValue<int, Window> &E : windows) { + Window *w = &E.value; if (w->swapchain == VK_NULL_HANDLE) { continue; @@ -1911,8 +1911,8 @@ Error VulkanContext::swap_buffers() { present.pSwapchains = pSwapchains; present.pImageIndices = pImageIndices; - for (Map<int, Window>::Element *E = windows.front(); E; E = E->next()) { - Window *w = &E->get(); + for (KeyValue<int, Window> &E : windows) { + Window *w = &E.value; if (w->swapchain == VK_NULL_HANDLE) { continue; @@ -2084,12 +2084,12 @@ RID VulkanContext::local_device_create() { } VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) { - LocalDevice *ld = local_device_owner.getornull(p_local_device); + LocalDevice *ld = local_device_owner.get_or_null(p_local_device); return ld->device; } void VulkanContext::local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count) { - LocalDevice *ld = local_device_owner.getornull(p_local_device); + LocalDevice *ld = local_device_owner.get_or_null(p_local_device); ERR_FAIL_COND(ld->waiting); VkSubmitInfo submit_info; @@ -2119,7 +2119,7 @@ void VulkanContext::local_device_push_command_buffers(RID p_local_device, const } void VulkanContext::local_device_sync(RID p_local_device) { - LocalDevice *ld = local_device_owner.getornull(p_local_device); + LocalDevice *ld = local_device_owner.get_or_null(p_local_device); ERR_FAIL_COND(!ld->waiting); vkDeviceWaitIdle(ld->device); @@ -2127,7 +2127,7 @@ void VulkanContext::local_device_sync(RID p_local_device) { } void VulkanContext::local_device_free(RID p_local_device) { - LocalDevice *ld = local_device_owner.getornull(p_local_device); + LocalDevice *ld = local_device_owner.get_or_null(p_local_device); vkDestroyDevice(ld->device, nullptr); local_device_owner.free(p_local_device); } diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 276fda2a8f..24c9b69542 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -301,7 +301,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c } if (using_audio_client_3) { - AudioClientProperties audioProps; + AudioClientProperties audioProps{}; audioProps.cbSize = sizeof(AudioClientProperties); audioProps.bIsOffload = FALSE; audioProps.eCategory = AudioCategory_GameEffects; diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 28642f1bb4..02b4a12b92 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -398,17 +398,17 @@ void AnimationBezierTrackEdit::_notification(int p_what) { float scale = timeline->get_zoom_scale(); Ref<Texture2D> point = get_theme_icon(SNAME("KeyValue"), SNAME("EditorIcons")); - for (Map<int, Color>::Element *E = subtrack_colors.front(); E; E = E->next()) { - _draw_track(E->key(), E->get()); + for (const KeyValue<int, Color> &E : subtrack_colors) { + _draw_track(E.key, E.value); - for (int i = 0; i < animation->track_get_key_count(E->key()); i++) { - float offset = animation->track_get_key_time(E->key(), i); - float value = animation->bezier_track_get_key_value(E->key(), i); + for (int i = 0; i < animation->track_get_key_count(E.key); i++) { + float offset = animation->track_get_key_time(E.key, i); + float value = animation->bezier_track_get_key_value(E.key, i); Vector2 pos((offset - timeline->get_value()) * scale + limit, _bezier_h_to_pixel(value)); if (pos.x >= limit && pos.x <= right_limit) { - draw_texture(point, pos - point->get_size() / 2, E->get()); + draw_texture(point, pos - point->get_size() / 2, E.value); } } } @@ -680,9 +680,9 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { emit_signal(SNAME("close_request")); return; } - for (Map<int, Rect2>::Element *E = subtracks.front(); E; E = E->next()) { - if (E->get().has_point(mb->get_position())) { - set_animation_and_track(animation, E->key()); + for (const KeyValue<int, Rect2> &E : subtracks) { + if (E.value.has_point(mb->get_position())) { + set_animation_and_track(animation, E.key); _clear_selection(); return; } diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 324237ff82..d5afd5020c 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -700,16 +700,15 @@ public: return; } - for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { + for (const KeyValue<int, List<float>> &E : key_ofs_map) { int key = 0; - for (float &F : E->value()) { - float key_ofs = F; + for (const float &key_ofs : E.value) { if (from != key_ofs) { key++; continue; } - int track = E->key(); + int track = E.key; key_ofs_map[track][key] = to; if (setting) { @@ -726,10 +725,9 @@ public: bool _set(const StringName &p_name, const Variant &p_value) { bool update_obj = false; bool change_notify_deserved = false; - for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { - int track = E->key(); - for (float &F : E->value()) { - float key_ofs = F; + for (const KeyValue<int, List<float>> &E : key_ofs_map) { + int track = E.key; + for (const float &key_ofs : E.value) { int key = animation->track_find_key(track, key_ofs, true); ERR_FAIL_COND_V(key == -1, false); @@ -984,10 +982,9 @@ public: } bool _get(const StringName &p_name, Variant &r_ret) const { - for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { - int track = E->key(); - for (float &F : E->value()) { - float key_ofs = F; + for (const KeyValue<int, List<float>> &E : key_ofs_map) { + int track = E.key; + for (const float &key_ofs : E.value) { int key = animation->track_find_key(track, key_ofs, true); ERR_CONTINUE(key == -1); @@ -1119,15 +1116,15 @@ public: bool show_time = true; bool same_track_type = true; bool same_key_type = true; - for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) { - int track = E->key(); + for (const KeyValue<int, List<float>> &E : key_ofs_map) { + int track = E.key; ERR_FAIL_INDEX(track, animation->get_track_count()); if (first_track < 0) { first_track = track; } - if (show_time && E->value().size() > 1) { + if (show_time && E.value.size() > 1) { show_time = false; } @@ -1137,7 +1134,7 @@ public: same_key_type = false; } - for (float &F : E->value()) { + for (const float &F : E.value) { int key = animation->track_find_key(track, F, true); ERR_FAIL_COND(key == -1); if (first_key < 0) { @@ -4831,8 +4828,8 @@ void AnimationTrackEditor::_update_key_edit() { Map<int, List<float>> key_ofs_map; Map<int, NodePath> base_map; int first_track = -1; - for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) { - int track = E->key().track; + for (const KeyValue<SelectedKey, KeyInfo> &E : selection) { + int track = E.key.track; if (first_track < 0) { first_track = track; } @@ -4842,7 +4839,7 @@ void AnimationTrackEditor::_update_key_edit() { base_map[track] = NodePath(); } - key_ofs_map[track].push_back(animation->track_get_key_time(track, E->key().key)); + key_ofs_map[track].push_back(animation->track_get_key_time(track, E.key.key)); } multi_key_edit->key_ofs_map = key_ofs_map; multi_key_edit->base_map = base_map; @@ -5386,8 +5383,8 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { float len = -1e20; float pivot = 0; - for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) { - float t = animation->track_get_key_time(E->key().track, E->key().key); + for (const KeyValue<SelectedKey, KeyInfo> &E : selection) { + float t = animation->track_get_key_time(E.key.track, E.key.key); if (t < from_t) { from_t = t; } diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp index f7f4988873..2efcdcda31 100644 --- a/editor/audio_stream_preview.cpp +++ b/editor/audio_stream_preview.cpp @@ -216,15 +216,15 @@ AudioStreamPreviewGenerator *AudioStreamPreviewGenerator::singleton = nullptr; void AudioStreamPreviewGenerator::_notification(int p_what) { if (p_what == NOTIFICATION_PROCESS) { List<ObjectID> to_erase; - for (Map<ObjectID, Preview>::Element *E = previews.front(); E; E = E->next()) { - if (!E->get().generating.is_set()) { - if (E->get().thread) { - E->get().thread->wait_to_finish(); - memdelete(E->get().thread); - E->get().thread = nullptr; + for (KeyValue<ObjectID, Preview> &E : previews) { + if (!E.value.generating.is_set()) { + if (E.value.thread) { + E.value.thread->wait_to_finish(); + memdelete(E.value.thread); + E.value.thread = nullptr; } - if (!ObjectDB::get_instance(E->key())) { //no longer in use, get rid of preview - to_erase.push_back(E->key()); + if (!ObjectDB::get_instance(E.key)) { //no longer in use, get rid of preview + to_erase.push_back(E.key); } } } diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp index fbd3aaa409..485d58f4a3 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp @@ -306,8 +306,8 @@ Dictionary DebugAdapterParser::req_stackTrace(const Dictionary &p_params) const Array arr; DebugAdapterProtocol *dap = DebugAdapterProtocol::get_singleton(); - for (Map<DAP::StackFrame, List<int>>::Element *E = dap->stackframe_list.front(); E; E = E->next()) { - DAP::StackFrame sf = E->key(); + for (const KeyValue<DAP::StackFrame, List<int>> &E : dap->stackframe_list) { + DAP::StackFrame sf = E.key; if (!lines_at_one) { sf.line--; } diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index a1eb71235c..e53f66e72e 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -200,12 +200,12 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) { } void EditorDebuggerInspector::clear_cache() { - for (Map<ObjectID, EditorDebuggerRemoteObject *>::Element *E = remote_objects.front(); E; E = E->next()) { + for (const KeyValue<ObjectID, EditorDebuggerRemoteObject *> &E : remote_objects) { EditorNode *editor = EditorNode::get_singleton(); - if (editor->get_editor_history()->get_current() == E->value()->get_instance_id()) { + if (editor->get_editor_history()->get_current() == E.value->get_instance_id()) { editor->push_item(nullptr); } - memdelete(E->value()); + memdelete(E.value); } remote_objects.clear(); remote_dependencies.clear(); diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index be84e8dec5..188f5708aa 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -328,9 +328,9 @@ void EditorDebuggerNode::_notification(int p_what) { debugger->set_editor_remote_tree(remote_scene_tree); debugger->start(server->take_connection()); // Send breakpoints. - for (Map<Breakpoint, bool>::Element *E = breakpoints.front(); E; E = E->next()) { - const Breakpoint &bp = E->key(); - debugger->set_breakpoint(bp.source, bp.line, E->get()); + for (const KeyValue<Breakpoint, bool> &E : breakpoints) { + const Breakpoint &bp = E.key; + debugger->set_breakpoint(bp.source, bp.line, E.value); } // Will arrive too late, how does the regular run work? debugger->update_live_edit_root(); @@ -497,8 +497,8 @@ void EditorDebuggerNode::set_breakpoints(const String &p_path, Array p_lines) { set_breakpoint(p_path, p_lines[i], true); } - for (Map<Breakpoint, bool>::Element *E = breakpoints.front(); E; E = E->next()) { - Breakpoint b = E->key(); + for (const KeyValue<Breakpoint, bool> &E : breakpoints) { + Breakpoint b = E.key; if (b.source == p_path && !p_lines.has(b.line)) { set_breakpoint(p_path, b.line, false); } diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp index 9479fbd5d4..d4385630be 100644 --- a/editor/debugger/editor_network_profiler.cpp +++ b/editor/debugger/editor_network_profiler.cpp @@ -56,18 +56,18 @@ void EditorNetworkProfiler::_update_frame() { TreeItem *root = counters_display->create_item(); - for (Map<ObjectID, DebuggerMarshalls::MultiplayerNodeInfo>::Element *E = nodes_data.front(); E; E = E->next()) { + for (const KeyValue<ObjectID, DebuggerMarshalls::MultiplayerNodeInfo> &E : nodes_data) { TreeItem *node = counters_display->create_item(root); for (int j = 0; j < counters_display->get_columns(); ++j) { node->set_text_align(j, j > 0 ? TreeItem::ALIGN_RIGHT : TreeItem::ALIGN_LEFT); } - node->set_text(0, E->get().node_path); - node->set_text(1, E->get().incoming_rpc == 0 ? "-" : itos(E->get().incoming_rpc)); - node->set_text(2, E->get().incoming_rset == 0 ? "-" : itos(E->get().incoming_rset)); - node->set_text(3, E->get().outgoing_rpc == 0 ? "-" : itos(E->get().outgoing_rpc)); - node->set_text(4, E->get().outgoing_rset == 0 ? "-" : itos(E->get().outgoing_rset)); + node->set_text(0, E.value.node_path); + node->set_text(1, E.value.incoming_rpc == 0 ? "-" : itos(E.value.incoming_rpc)); + node->set_text(2, E.value.incoming_rset == 0 ? "-" : itos(E.value.incoming_rset)); + node->set_text(3, E.value.outgoing_rpc == 0 ? "-" : itos(E.value.outgoing_rpc)); + node->set_text(4, E.value.outgoing_rset == 0 ? "-" : itos(E.value.outgoing_rset)); } } diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index fa9c9f61f5..2fe7cd7886 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -515,11 +515,11 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const { if (!m.valid) { continue; } - for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) { - possible_signatures.insert(E->key()); + for (const KeyValue<StringName, Metric::Category *> &E : m.category_ptrs) { + possible_signatures.insert(E.key); } - for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) { - possible_signatures.insert(E->key()); + for (const KeyValue<StringName, Metric::Category::Item *> &E : m.item_ptrs) { + possible_signatures.insert(E.key); } } @@ -557,11 +557,11 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const { values.clear(); values.resize(possible_signatures.size()); - for (Map<StringName, Metric::Category *>::Element *E = m.category_ptrs.front(); E; E = E->next()) { - values.write[sig_map[E->key()]] = String::num_real(E->value()->total_time); + for (const KeyValue<StringName, Metric::Category *> &E : m.category_ptrs) { + values.write[sig_map[E.key]] = String::num_real(E.value->total_time); } - for (Map<StringName, Metric::Category::Item *>::Element *E = m.item_ptrs.front(); E; E = E->next()) { - values.write[sig_map[E->key()]] = String::num_real(E->value()->total); + for (const KeyValue<StringName, Metric::Category::Item *> &E : m.item_ptrs) { + values.write[sig_map[E.key]] = String::num_real(E.value->total); } res.push_back(values); diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index d6650c3319..a312c161a8 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1238,7 +1238,7 @@ void ScriptEditorDebugger::update_live_edit_root() { Array msg; msg.push_back(np); if (editor->get_edited_scene()) { - msg.push_back(editor->get_edited_scene()->get_filename()); + msg.push_back(editor->get_edited_scene()->get_scene_file_path()); } else { msg.push_back(""); } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index a9d8cb219c..d07d77c112 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -74,16 +74,16 @@ void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String String path = efsd->get_file_path(i); - for (Map<String, String>::Element *E = candidates[file].front(); E; E = E->next()) { - if (E->get() == String()) { - E->get() = path; + for (KeyValue<String, String> &E : candidates[file]) { + if (E.value == String()) { + E.value = path; continue; } //must match the best, using subdirs - String existing = E->get().replace_first("res://", ""); + String existing = E.value.replace_first("res://", ""); String current = path.replace_first("res://", ""); - String lost = E->key().replace_first("res://", ""); + String lost = E.key.replace_first("res://", ""); Vector<String> existingv = existing.split("/"); existingv.reverse(); @@ -107,7 +107,7 @@ void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String if (current_score > existing_score) { //if it was the same, could track distance to new path but.. - E->get() = path; //replace by more accurate + E.value = path; //replace by more accurate } } } @@ -133,10 +133,10 @@ void DependencyEditor::_fix_all() { Map<String, String> remaps; - for (Map<String, Map<String, String>>::Element *E = candidates.front(); E; E = E->next()) { - for (Map<String, String>::Element *F = E->get().front(); F; F = F->next()) { - if (F->get() != String()) { - remaps[F->key()] = F->get(); + for (KeyValue<String, Map<String, String>> &E : candidates) { + for (const KeyValue<String, String> &F : E.value) { + if (F.value != String()) { + remaps[F.key] = F.value; } } } diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index ec162231e9..beead74c53 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -44,8 +44,8 @@ #include "modules/modules_enabled.gen.h" void DocTools::merge_from(const DocTools &p_data) { - for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - DocData::ClassDoc &c = E->get(); + for (KeyValue<String, DocData::ClassDoc> &E : class_list) { + DocData::ClassDoc &c = E.value; if (!p_data.class_list.has(c.name)) { continue; @@ -185,9 +185,9 @@ void DocTools::merge_from(const DocTools &p_data) { } void DocTools::remove_from(const DocTools &p_data) { - for (Map<String, DocData::ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { - if (class_list.has(E->key())) { - class_list.erase(E->key()); + for (const KeyValue<String, DocData::ClassDoc> &E : p_data.class_list) { + if (class_list.has(E.key)) { + class_list.erase(E.key); } } } @@ -1227,8 +1227,8 @@ static void _write_method_doc(FileAccess *f, const String &p_name, Vector<DocDat } Error DocTools::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { - for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - DocData::ClassDoc &c = E->get(); + for (KeyValue<String, DocData::ClassDoc> &E : class_list) { + DocData::ClassDoc &c = E.value; String save_path; if (p_class_path.has(c.name)) { diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index fcf79a80a7..0840c3b6a8 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -473,8 +473,8 @@ void EditorAutoloadSettings::update_autoload() { } // Remove deleted/changed autoloads - for (Map<String, AutoLoadInfo>::Element *E = to_remove.front(); E; E = E->next()) { - AutoLoadInfo &info = E->get(); + for (KeyValue<String, AutoLoadInfo> &E : to_remove) { + AutoLoadInfo &info = E.value; if (info.is_singleton) { for (int i = 0; i < ScriptServer::get_language_count(); i++) { ScriptServer::get_language(i)->remove_named_global_constant(info.name); diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 5e50835ef2..aee9c21007 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -554,7 +554,7 @@ void EditorData::remove_scene(int p_idx) { ERR_FAIL_INDEX(p_idx, edited_scene.size()); if (edited_scene[p_idx].root) { for (int i = 0; i < editor_plugins.size(); i++) { - editor_plugins[i]->notify_scene_closed(edited_scene[p_idx].root->get_filename()); + editor_plugins[i]->notify_scene_closed(edited_scene[p_idx].root->get_scene_file_path()); } memdelete(edited_scene[p_idx].root); @@ -583,7 +583,7 @@ bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, Set<String> if (p_node == p_root) { ss = p_node->get_scene_inherited_state(); - } else if (p_node->get_filename() != String()) { + } else if (p_node->get_scene_file_path() != String()) { ss = p_node->get_scene_instance_state(); } @@ -643,12 +643,12 @@ bool EditorData::check_and_update_scene(int p_idx) { } } - new_scene->set_filename(edited_scene[p_idx].root->get_filename()); + new_scene->set_scene_file_path(edited_scene[p_idx].root->get_scene_file_path()); memdelete(edited_scene[p_idx].root); edited_scene.write[p_idx].root = new_scene; - if (new_scene->get_filename() != "") { - edited_scene.write[p_idx].path = new_scene->get_filename(); + if (new_scene->get_scene_file_path() != "") { + edited_scene.write[p_idx].path = new_scene->get_scene_file_path(); } edited_scene.write[p_idx].selection = new_selection; @@ -682,10 +682,10 @@ void EditorData::set_edited_scene_root(Node *p_root) { ERR_FAIL_INDEX(current_edited_scene, edited_scene.size()); edited_scene.write[current_edited_scene].root = p_root; if (p_root) { - if (p_root->get_filename() != "") { - edited_scene.write[current_edited_scene].path = p_root->get_filename(); + if (p_root->get_scene_file_path() != "") { + edited_scene.write[current_edited_scene].path = p_root->get_scene_file_path(); } else { - p_root->set_filename(edited_scene[current_edited_scene].path); + p_root->set_scene_file_path(edited_scene[current_edited_scene].path); } } @@ -764,7 +764,7 @@ Ref<Script> EditorData::get_scene_root_script(int p_idx) const { Ref<Script> s = edited_scene[p_idx].root->get_script(); if (!s.is_valid() && edited_scene[p_idx].root->get_child_count()) { Node *n = edited_scene[p_idx].root->get_child(0); - while (!s.is_valid() && n && n->get_filename() == String()) { + while (!s.is_valid() && n && n->get_scene_file_path() == String()) { s = n->get_script(); n = n->get_parent(); } @@ -777,11 +777,11 @@ String EditorData::get_scene_title(int p_idx, bool p_always_strip_extension) con if (!edited_scene[p_idx].root) { return TTR("[empty]"); } - if (edited_scene[p_idx].root->get_filename() == "") { + if (edited_scene[p_idx].root->get_scene_file_path() == "") { return TTR("[unsaved]"); } - const String filename = edited_scene[p_idx].root->get_filename().get_file(); + const String filename = edited_scene[p_idx].root->get_scene_file_path().get_file(); const String basename = filename.get_basename(); if (p_always_strip_extension) { @@ -795,7 +795,7 @@ String EditorData::get_scene_title(int p_idx, bool p_always_strip_extension) con continue; } - if (edited_scene[i].root && basename == edited_scene[i].root->get_filename().get_file().get_basename()) { + if (edited_scene[i].root && basename == edited_scene[i].root->get_scene_file_path().get_file().get_basename()) { return filename; } } @@ -811,17 +811,17 @@ void EditorData::set_scene_path(int p_idx, const String &p_path) { if (!edited_scene[p_idx].root) { return; } - edited_scene[p_idx].root->set_filename(p_path); + edited_scene[p_idx].root->set_scene_file_path(p_path); } String EditorData::get_scene_path(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String()); if (edited_scene[p_idx].root) { - if (edited_scene[p_idx].root->get_filename() == "") { - edited_scene[p_idx].root->set_filename(edited_scene[p_idx].path); + if (edited_scene[p_idx].root->get_scene_file_path() == "") { + edited_scene[p_idx].root->set_scene_file_path(edited_scene[p_idx].path); } else { - return edited_scene[p_idx].root->get_filename(); + return edited_scene[p_idx].root->get_scene_file_path(); } } @@ -1105,8 +1105,8 @@ Array EditorSelection::_get_transformable_selected_nodes() { TypedArray<Node> EditorSelection::get_selected_nodes() { TypedArray<Node> ret; - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + ret.push_back(E.key); } return ret; @@ -1133,8 +1133,8 @@ void EditorSelection::_update_nl() { selected_node_list.clear(); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - Node *parent = E->key(); + for (const KeyValue<Node *, Object *> &E : selection) { + Node *parent = E.key; parent = parent->get_parent(); bool skip = false; while (parent) { @@ -1148,7 +1148,7 @@ void EditorSelection::_update_nl() { if (skip) { continue; } - selected_node_list.push_back(E->key()); + selected_node_list.push_back(E.key); } nl_changed = true; @@ -1183,8 +1183,8 @@ List<Node *> &EditorSelection::get_selected_node_list() { List<Node *> EditorSelection::get_full_selected_node_list() { List<Node *> node_list; - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - node_list.push_back(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + node_list.push_back(E.key); } return node_list; diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 10ed76673e..a88adf3634 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -451,6 +451,9 @@ void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_d } for (int i = 0; i < p_dir->get_file_count(); i++) { + if (p_dir->get_file_type(i) == "TextFile") { + continue; + } p_paths.insert(p_dir->get_file_path(i)); } } @@ -1814,9 +1817,9 @@ bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, List<String> EditorExportPlatformPC::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { List<String> list; - for (Map<String, String>::Element *E = extensions.front(); E; E = E->next()) { - if (p_preset->get(E->key())) { - list.push_back(extensions[E->key()]); + for (const KeyValue<String, String> &E : extensions) { + if (p_preset->get(E.key)) { + list.push_back(extensions[E.key]); return list; } } diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index 84a9237a96..2222a5e5d3 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -179,9 +179,9 @@ Error EditorFeatureProfile::save_to_file(const String &p_path) { Array dis_props; - for (Map<StringName, Set<StringName>>::Element *E = disabled_properties.front(); E; E = E->next()) { - for (Set<StringName>::Element *F = E->get().front(); F; F = F->next()) { - dis_props.push_back(String(E->key()) + ":" + String(F->get())); + for (KeyValue<StringName, Set<StringName>> &E : disabled_properties) { + for (Set<StringName>::Element *F = E.value.front(); F; F = F->next()) { + dis_props.push_back(String(E.key) + ":" + String(F->get())); } } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 8523833d52..0882b525d7 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -862,6 +862,9 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess } else { //new or modified time fi->type = ResourceLoader::get_resource_type(path); + if (fi->type == "" && textfile_extensions.has(ext)) { + fi->type = "TextFile"; + } fi->uid = ResourceLoader::get_resource_uid(path); fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path); fi->deps = _get_dependencies(path); @@ -984,6 +987,9 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const fi->modified_time = FileAccess::get_modified_time(path); fi->import_modified_time = 0; fi->type = ResourceLoader::get_resource_type(path); + if (fi->type == "" && textfile_extensions.has(ext)) { + fi->type = "TextFile"; + } fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path); fi->import_valid = ResourceLoader::is_import_valid(path); fi->import_group_file = ResourceLoader::get_import_group_file(path); @@ -1539,6 +1545,9 @@ void EditorFileSystem::update_file(const String &p_file) { } String type = ResourceLoader::get_resource_type(p_file); + if (type == "" && textfile_extensions.has(p_file.get_extension())) { + type = "TextFile"; + } ResourceUID::ID uid = ResourceLoader::get_resource_uid(p_file); if (cpos == -1) { @@ -1556,7 +1565,7 @@ void EditorFileSystem::update_file(const String &p_file) { EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo); fi->file = file_name; fi->import_modified_time = 0; - fi->import_valid = ResourceLoader::is_import_valid(p_file); + fi->import_valid = type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file); if (idx == fs->files.size()) { fs->files.push_back(fi); @@ -1577,7 +1586,7 @@ void EditorFileSystem::update_file(const String &p_file) { fs->files[cpos]->import_group_file = ResourceLoader::get_import_group_file(p_file); fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file); fs->files[cpos]->deps = _get_dependencies(p_file); - fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); + fs->files[cpos]->import_valid = type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file); if (uid != ResourceUID::INVALID_ID) { if (ResourceUID::get_singleton()->has_id(uid)) { @@ -1654,8 +1663,8 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector Error err = importer->import_group_file(p_group_file, source_file_options, base_paths); //all went well, overwrite config files with proper remaps and md5s - for (Map<String, Map<StringName, Variant>>::Element *E = source_file_options.front(); E; E = E->next()) { - const String &file = E->key(); + for (const KeyValue<String, Map<StringName, Variant>> &E : source_file_options) { + const String &file = E.key; String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(file); FileAccessRef f = FileAccess::open(file + ".import", FileAccess::WRITE); ERR_FAIL_COND_V_MSG(!f, ERR_FILE_CANT_OPEN, "Cannot open import file '" + file + ".import'."); @@ -1740,6 +1749,9 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(file + ".import"); fs->files[cpos]->deps = _get_dependencies(file); fs->files[cpos]->type = importer->get_resource_type(); + if (fs->files[cpos]->type == "" && textfile_extensions.has(file.get_extension())) { + fs->files[cpos]->type = "TextFile"; + } fs->files[cpos]->import_valid = err == OK; //if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it @@ -2121,10 +2133,10 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { if (groups_to_reimport.size()) { Map<String, Vector<String>> group_files; _find_group_files(filesystem, group_files, groups_to_reimport); - for (Map<String, Vector<String>>::Element *E = group_files.front(); E; E = E->next()) { - Error err = _reimport_group(E->key(), E->get()); + for (const KeyValue<String, Vector<String>> &E : group_files) { + Error err = _reimport_group(E.key, E.value); if (err == OK) { - _reimport_file(E->key()); + _reimport_file(E.key); } } } @@ -2329,6 +2341,7 @@ void EditorFileSystem::_bind_methods() { void EditorFileSystem::_update_extensions() { valid_extensions.clear(); import_extensions.clear(); + textfile_extensions.clear(); List<String> extensionsl; ResourceLoader::get_recognized_extensions_for_type("", &extensionsl); @@ -2336,6 +2349,15 @@ void EditorFileSystem::_update_extensions() { valid_extensions.insert(E); } + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (const String &E : textfile_ext) { + if (valid_extensions.has(E)) { + continue; + } + valid_extensions.insert(E); + textfile_extensions.insert(E); + } + extensionsl.clear(); ResourceFormatImporter::get_singleton()->get_recognized_extensions(&extensionsl); for (const String &E : extensionsl) { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index b47cf5523a..feadd0f2b2 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -190,6 +190,7 @@ class EditorFileSystem : public Node { void _delete_internal_files(String p_file); + Set<String> textfile_extensions; Set<String> valid_extensions; Set<String> import_extensions; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index fff9e5e908..c049db8ef6 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -394,8 +394,8 @@ void EditorHelp::_update_doc() { bool prev = false; class_desc->push_font(doc_font); - for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { - if (E->get().inherits == cd.name) { + for (const KeyValue<String, DocData::ClassDoc> &E : doc->class_list) { + if (E.value.inherits == cd.name) { if (!found) { class_desc->push_color(title_color); class_desc->add_text(TTR("Inherited by:") + " "); @@ -406,7 +406,7 @@ void EditorHelp::_update_doc() { class_desc->add_text(" , "); } - _add_type(E->get().name); + _add_type(E.value.name); prev = true; } } @@ -876,14 +876,14 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); - for (Map<String, Vector<DocData::ConstantDoc>>::Element *E = enums.front(); E; E = E->next()) { - enum_line[E->key()] = class_desc->get_line_count() - 2; + for (KeyValue<String, Vector<DocData::ConstantDoc>> &E : enums) { + enum_line[E.key] = class_desc->get_line_count() - 2; class_desc->push_font(doc_code_font); class_desc->push_color(title_color); class_desc->add_text("enum "); class_desc->pop(); - String e = E->key(); + String e = E.key; if ((e.get_slice_count(".") > 1) && (e.get_slice(".", 0) == edited_class)) { e = e.get_slice(".", 1); } @@ -913,10 +913,10 @@ void EditorHelp::_update_doc() { } class_desc->push_indent(1); - Vector<DocData::ConstantDoc> enum_list = E->get(); + Vector<DocData::ConstantDoc> enum_list = E.value; Map<String, int> enumValuesContainer; - int enumStartingLine = enum_line[E->key()]; + int enumStartingLine = enum_line[E.key]; for (int i = 0; i < enum_list.size(); i++) { if (cd.name == "@GlobalScope") { @@ -955,7 +955,7 @@ void EditorHelp::_update_doc() { } if (cd.name == "@GlobalScope") { - enum_values_line[E->key()] = enumValuesContainer; + enum_values_line[E.key] = enumValuesContainer; } class_desc->pop(); @@ -1922,7 +1922,7 @@ void FindBar::_update_results_count() { return; } - String full_text = rich_text_label->get_text(); + String full_text = rich_text_label->get_parsed_text(); int from_pos = 0; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 4832cd6994..4d0f27c5d4 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -842,10 +842,10 @@ void EditorProperty::set_bottom_editor(Control *p_control) { bool EditorProperty::is_cache_valid() const { if (object) { - for (Map<StringName, Variant>::Element *E = cache.front(); E; E = E->next()) { + for (const KeyValue<StringName, Variant> &E : cache) { bool valid; - Variant value = object->get(E->key(), &valid); - if (!valid || value != E->get()) { + Variant value = object->get(E.key, &valid); + if (!valid || value != E.value) { return false; } } @@ -3029,8 +3029,8 @@ void EditorInspector::collapse_all_folding() { E->fold(); } - for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { - for (EditorProperty *E : F->get()) { + for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) { + for (EditorProperty *E : F.value) { E->collapse_all_folding(); } } @@ -3040,8 +3040,8 @@ void EditorInspector::expand_all_folding() { for (EditorInspectorSection *E : sections) { E->unfold(); } - for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { - for (EditorProperty *E : F->get()) { + for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) { + for (EditorProperty *E : F.value) { E->expand_all_folding(); } } @@ -3306,11 +3306,11 @@ void EditorInspector::_property_selected(const String &p_path, int p_focusable) property_selected = p_path; property_focusable = p_focusable; //deselect the others - for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { - if (F->key() == property_selected) { + for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) { + if (F.key == property_selected) { continue; } - for (EditorProperty *E : F->get()) { + for (EditorProperty *E : F.value) { if (E->is_selected()) { E->deselect(); } @@ -3368,8 +3368,8 @@ void EditorInspector::_notification(int p_what) { if (refresh_countdown > 0) { refresh_countdown -= get_process_delta_time(); if (refresh_countdown <= 0) { - for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) { - for (EditorProperty *E : F->get()) { + for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) { + for (EditorProperty *E : F.value) { if (!E->is_cache_valid()) { E->update_property(); E->update_reload_status(); diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index f91cb7f607..346b93a87c 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -116,8 +116,8 @@ void EditorLog::_save_state() { config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); const String section = "editor_log"; - for (Map<MessageType, LogFilter *>::Element *E = type_filter_map.front(); E; E = E->next()) { - config->set_value(section, "log_filter_" + itos(E->key()), E->get()->is_active()); + for (const KeyValue<MessageType, LogFilter *> &E : type_filter_map) { + config->set_value(section, "log_filter_" + itos(E.key), E.value->is_active()); } config->set_value(section, "collapse", collapse); @@ -135,8 +135,8 @@ void EditorLog::_load_state() { // Run the below code even if config->load returns an error, since we want the defaults to be set even if the file does not exist yet. const String section = "editor_log"; - for (Map<MessageType, LogFilter *>::Element *E = type_filter_map.front(); E; E = E->next()) { - E->get()->set_active(config->get_value(section, "log_filter_" + itos(E->key()), true)); + for (const KeyValue<MessageType, LogFilter *> &E : type_filter_map) { + E.value->set_active(config->get_value(section, "log_filter_" + itos(E.key), true)); } collapse = config->get_value(section, "collapse", false); @@ -306,8 +306,8 @@ void EditorLog::_search_changed(const String &p_text) { } void EditorLog::_reset_message_counts() { - for (Map<MessageType, LogFilter *>::Element *E = type_filter_map.front(); E; E = E->next()) { - E->value()->set_message_count(0); + for (const KeyValue<MessageType, LogFilter *> &E : type_filter_map) { + E.value->set_message_count(0); } } @@ -441,7 +441,7 @@ void EditorLog::deinit() { } EditorLog::~EditorLog() { - for (Map<MessageType, LogFilter *>::Element *E = type_filter_map.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<MessageType, LogFilter *> &E : type_filter_map) { + memdelete(E.value); } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 9a79e1f942..8bc87b7f81 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -394,7 +394,7 @@ void EditorNode::_version_control_menu_option(int p_idx) { void EditorNode::_update_title() { const String appname = ProjectSettings::get_singleton()->get("application/config/name"); String title = (appname.is_empty() ? "Unnamed Project" : appname) + String(" - ") + VERSION_NAME; - const String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String(); + const String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_scene_file_path() : String(); if (!edited.is_empty()) { // Display the edited scene name before the program name so that it can be seen in the OS task bar. title = vformat("%s - %s", edited.get_file(), title); @@ -741,6 +741,21 @@ void EditorNode::_notification(int p_what) { main_editor_buttons.write[i]->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("main_button_font_size"), SNAME("EditorFonts"))); } + Set<String> updated_textfile_extensions; + bool extensions_match = true; + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (const String &E : textfile_ext) { + updated_textfile_extensions.insert(E); + if (extensions_match && !textfile_extensions.has(E)) { + extensions_match = false; + } + } + + if (!extensions_match || updated_textfile_extensions.size() < textfile_extensions.size()) { + textfile_extensions = updated_textfile_extensions; + EditorFileSystem::get_singleton()->scan(); + } + _update_update_spinner(); } break; @@ -1114,7 +1129,13 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d dependency_errors.clear(); Error err; - RES res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + + RES res; + if (ResourceLoader::exists(p_resource, "")) { + res = ResourceLoader::load(p_resource, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err); + } else if (textfile_extensions.has(p_resource.get_extension())) { + res = ScriptEditor::get_singleton()->open_file(p_resource); + } ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN); if (!p_ignore_broken_deps && dependency_errors.has(p_resource)) { @@ -1175,7 +1196,7 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String int srpos = path.find("::"); if (srpos != -1) { String base = path.substr(0, srpos); - if (!get_edited_scene() || get_edited_scene()->get_filename() != base) { + if (!get_edited_scene() || get_edited_scene()->get_scene_file_path() != base) { show_warning(TTR("This resource can't be saved because it does not belong to the edited scene. Make it unique first.")); return; } @@ -1549,7 +1570,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_node) { for (int i = 0; i < p_node->get_child_count(); i++) { Node *child = p_node->get_child(i); - if (child->get_filename() == p_filename) { + if (child->get_scene_file_path() == p_filename) { return true; } @@ -1645,7 +1666,7 @@ void EditorNode::_save_scene(String p_file, int idx) { return; } - if (scene->get_filename() != String() && _validate_scene_recursive(scene->get_filename(), scene)) { + if (scene->get_scene_file_path() != String() && _validate_scene_recursive(scene->get_scene_file_path(), scene)) { show_accept(TTR("This scene can't be saved because there is a cyclic instancing inclusion.\nPlease resolve it and then attempt to save again."), TTR("OK")); return; } @@ -1699,7 +1720,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } if (err == OK) { - scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_file)); + scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(p_file)); if (idx < 0 || idx == editor_data.get_edited_scene()) { set_current_version(editor_data.get_undo_redo().get_version()); } else { @@ -1727,8 +1748,8 @@ void EditorNode::save_scene_list(Vector<String> p_scene_filenames) { for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { Node *scene = editor_data.get_edited_scene_root(i); - if (scene && (p_scene_filenames.find(scene->get_filename()) >= 0)) { - _save_scene(scene->get_filename(), i); + if (scene && (p_scene_filenames.find(scene->get_scene_file_path()) >= 0)) { + _save_scene(scene->get_scene_file_path(), i); } } } @@ -1738,7 +1759,7 @@ void EditorNode::restart_editor() { String to_reopen; if (get_tree()->get_edited_scene_root()) { - to_reopen = get_tree()->get_edited_scene_root()->get_filename(); + to_reopen = get_tree()->get_edited_scene_root()->get_scene_file_path(); } _exit_editor(); @@ -1757,11 +1778,11 @@ void EditorNode::restart_editor() { void EditorNode::_save_all_scenes() { for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { Node *scene = editor_data.get_edited_scene_root(i); - if (scene && scene->get_filename() != "" && DirAccess::exists(scene->get_filename().get_base_dir())) { + if (scene && scene->get_scene_file_path() != "" && DirAccess::exists(scene->get_scene_file_path().get_base_dir())) { if (i != editor_data.get_edited_scene()) { - _save_scene(scene->get_filename(), i); + _save_scene(scene->get_scene_file_path(), i); } else { - _save_scene_with_preview(scene->get_filename()); + _save_scene_with_preview(scene->get_scene_file_path()); } } else { show_warning(TTR("Could not save one or more scenes!"), TTR("Save All Scenes")); @@ -1778,7 +1799,7 @@ void EditorNode::_mark_unsaved_scenes() { continue; } - String path = node->get_filename(); + String path = node->get_scene_file_path(); if (!(path == String() || FileAccess::exists(path))) { if (i == editor_data.get_edited_scene()) { set_current_version(-1); @@ -2130,7 +2151,7 @@ void EditorNode::_edit_current() { if (FileAccess::exists(base_path + ".import")) { editable_warning = TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } else { - if ((!get_edited_scene() || get_edited_scene()->get_filename() != base_path) && ResourceLoader::get_resource_type(base_path) == "PackedScene") { + if ((!get_edited_scene() || get_edited_scene()->get_scene_file_path() != base_path) && ResourceLoader::get_resource_type(base_path) == "PackedScene") { editable_warning = TTR("This resource belongs to a scene that was instantiated or inherited.\nChanges to it won't be kept when saving the current scene."); } } @@ -2154,8 +2175,8 @@ void EditorNode::_edit_current() { inspector_dock->update(nullptr); } - if (get_edited_scene() && get_edited_scene()->get_filename() != String()) { - String source_scene = get_edited_scene()->get_filename(); + if (get_edited_scene() && get_edited_scene()->get_scene_file_path() != String()) { + String source_scene = get_edited_scene()->get_scene_file_path(); if (FileAccess::exists(source_scene + ".import")) { editable_warning = TTR("This scene was imported, so changes to it won't be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow."); } @@ -2278,7 +2299,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { String args; bool skip_breakpoints; - if (p_current || (editor_data.get_edited_scene_root() && p_custom != String() && p_custom == editor_data.get_edited_scene_root()->get_filename())) { + if (p_current || (editor_data.get_edited_scene_root() && p_custom != String() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) { Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -2286,7 +2307,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { return; } - if (scene->get_filename() == "") { + if (scene->get_scene_file_path() == "") { current_option = -1; _menu_option(FILE_SAVE_AS_SCENE); // Set the option to save and run so when the dialog is accepted, the scene runs. @@ -2295,7 +2316,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) { return; } - run_filename = scene->get_filename(); + run_filename = scene->get_scene_file_path(); } else if (p_custom != "") { run_filename = p_custom; } @@ -2311,8 +2332,8 @@ void EditorNode::_run(bool p_current, const String &p_custom) { if (unsaved_cache) { Node *scene = editor_data.get_edited_scene_root(); - if (scene && scene->get_filename() != "") { // Only autosave if there is a scene and if it has a path. - _save_scene_with_preview(scene->get_filename()); + if (scene && scene->get_scene_file_path() != "") { // Only autosave if there is a scene and if it has a path. + _save_scene_with_preview(scene->get_scene_file_path()); } } _menu_option(FILE_SAVE_ALL_SCENES); @@ -2405,7 +2426,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { Node *scene = editor_data.get_edited_scene_root(); if (scene) { - file->set_current_path(scene->get_filename()); + file->set_current_path(scene->get_scene_file_path()); }; file->set_title(p_option == FILE_OPEN_SCENE ? TTR("Open Scene") : TTR("Open Base Scene")); file->popup_file_dialog(); @@ -2467,7 +2488,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { if (unsaved_cache || p_option == FILE_CLOSE_ALL_AND_QUIT || p_option == FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER) { Node *scene_root = editor_data.get_edited_scene_root(tab_closing); if (scene_root) { - String scene_filename = scene_root->get_filename(); + String scene_filename = scene_root->get_scene_file_path(); save_confirmation->get_ok_button()->set_text(TTR("Save & Close")); save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene_filename != "" ? scene_filename : "unsaved scene")); save_confirmation->popup_centered(); @@ -2487,12 +2508,12 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { case FILE_SAVE_SCENE: { int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing; Node *scene = editor_data.get_edited_scene_root(scene_idx); - if (scene && scene->get_filename() != "") { - if (DirAccess::exists(scene->get_filename().get_base_dir())) { + if (scene && scene->get_scene_file_path() != "") { + if (DirAccess::exists(scene->get_scene_file_path().get_base_dir())) { if (scene_idx != editor_data.get_edited_scene()) { - _save_scene_with_preview(scene->get_filename(), scene_idx); + _save_scene_with_preview(scene->get_scene_file_path(), scene_idx); } else { - _save_scene_with_preview(scene->get_filename()); + _save_scene_with_preview(scene->get_scene_file_path()); } if (scene_idx != -1) { @@ -2500,7 +2521,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } save_layout(); } else { - show_save_accept(vformat(TTR("%s no longer exists! Please specify a new save location."), scene->get_filename().get_base_dir()), TTR("OK")); + show_save_accept(vformat(TTR("%s no longer exists! Please specify a new save location."), scene->get_scene_file_path().get_base_dir()), TTR("OK")); } break; } @@ -2543,8 +2564,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); } - if (scene->get_filename() != "") { - String path = scene->get_filename(); + if (scene->get_scene_file_path() != "") { + String path = scene->get_scene_file_path(); file->set_current_path(path); if (extensions.size()) { String ext = path.get_extension().to_lower(); @@ -2642,7 +2663,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { break; } - String filename = scene->get_filename(); + String filename = scene->get_scene_file_path(); if (filename == String()) { show_warning(TTR("Can't reload a scene that was never saved.")); @@ -2764,7 +2785,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { String unsaved_scenes; int i = _next_unsaved_scene(true, 0); while (i != -1) { - unsaved_scenes += "\n " + editor_data.get_edited_scene_root(i)->get_filename(); + unsaved_scenes += "\n " + editor_data.get_edited_scene_root(i)->get_scene_file_path(); i = _next_unsaved_scene(true, ++i); } @@ -2839,7 +2860,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { Node *scene = editor_data.get_edited_scene_root(); if (scene) { - file->set_current_path(scene->get_filename()); + file->set_current_path(scene->get_scene_file_path()); }; file->set_title(TTR("Pick a Main Scene")); file->popup_file_dialog(); @@ -2941,7 +2962,7 @@ int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) { int current = editor_data.get_edited_scene(); bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0; if (unsaved) { - String scene_filename = editor_data.get_edited_scene_root(i)->get_filename(); + String scene_filename = editor_data.get_edited_scene_root(i)->get_scene_file_path(); if (p_valid_filename && scene_filename.length() == 0) { continue; } @@ -2973,7 +2994,7 @@ void EditorNode::_discard_changes(const String &p_str) { case SCENE_TAB_CLOSE: { Node *scene = editor_data.get_edited_scene_root(tab_closing); if (scene != nullptr) { - String scene_filename = scene->get_filename(); + String scene_filename = scene->get_scene_file_path(); if (scene_filename != "") { previous_scenes.push_back(scene_filename); } @@ -3181,8 +3202,8 @@ void EditorNode::_update_addon_config() { Vector<String> enabled_addons; - for (Map<String, EditorPlugin *>::Element *E = plugin_addons.front(); E; E = E->next()) { - enabled_addons.push_back(E->key()); + for (const KeyValue<String, EditorPlugin *> &E : plugin_addons) { + enabled_addons.push_back(E.key); } if (enabled_addons.size() == 0) { @@ -3564,9 +3585,9 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b dependency_errors.erase(lpath); //at least not self path - for (Map<String, Set<String>>::Element *E = dependency_errors.front(); E; E = E->next()) { - String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E->key()) + "\n"; - for (Set<String>::Element *F = E->get().front(); F; F = F->next()) { + for (KeyValue<String, Set<String>> &E : dependency_errors) { + String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E.key) + "\n"; + for (Set<String>::Element *F = E.value.front(); F; F = F->next()) { txt += "\t" + F->get() + "\n"; } add_io_error(txt); @@ -3602,7 +3623,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b Ref<SceneState> state = sdata->get_state(); state->set_path(lpath); new_scene->set_scene_inherited_state(state); - new_scene->set_filename(String()); + new_scene->set_scene_file_path(String()); } new_scene->set_scene_instance_state(Ref<SceneState>()); @@ -3775,7 +3796,7 @@ void EditorNode::_load_error_notify(void *p_ud, const String &p_text) { } bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const { - if (p_node->get_filename() == p_path) { + if (p_node->get_scene_file_path() == p_path) { return true; } @@ -3953,7 +3974,7 @@ void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_na pick_main_scene->hide(); current_option = SETTINGS_PICK_MAIN_SCENE; - _dialog_action(scene->get_filename()); + _dialog_action(scene->get_scene_file_path()); } } @@ -4029,8 +4050,8 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p } const Map<String, Vector<EditorData::CustomType>> &p_map = EditorNode::get_editor_data().get_custom_types(); - for (const Map<String, Vector<EditorData::CustomType>>::Element *E = p_map.front(); E; E = E->next()) { - const Vector<EditorData::CustomType> &ct = E->value(); + for (const KeyValue<String, Vector<EditorData::CustomType>> &E : p_map) { + const Vector<EditorData::CustomType> &ct = E.value; for (int i = 0; i < ct.size(); ++i) { if (ct[i].name == p_class) { if (ct[i].icon.is_valid()) { @@ -4943,7 +4964,7 @@ void EditorNode::_scene_tab_closed(int p_tab, int option) { editor_data.get_scene_version(p_tab) != 0; if (unsaved) { save_confirmation->get_ok_button()->set_text(TTR("Save & Close")); - save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_filename() != "" ? scene->get_filename() : "unsaved scene")); + save_confirmation->set_text(vformat(TTR("Save changes to '%s' before closing?"), scene->get_scene_file_path() != "" ? scene->get_scene_file_path() : "unsaved scene")); save_confirmation->popup_centered(); } else { _discard_changes(); @@ -5995,6 +6016,11 @@ EditorNode::EditorNode() { EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT)); EDITOR_DEF("run/auto_save/save_before_running", true); + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (const String &E : textfile_ext) { + textfile_extensions.insert(E); + } + theme_base = memnew(Control); add_child(theme_base); theme_base->set_anchors_and_offsets_preset(Control::PRESET_WIDE); @@ -6195,12 +6221,12 @@ EditorNode::EditorNode() { scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE); scene_tabs->set_drag_to_rearrange_enabled(true); scene_tabs->connect("tab_changed", callable_mp(this, &EditorNode::_scene_tab_changed)); - scene_tabs->connect("right_button_pressed", callable_mp(this, &EditorNode::_scene_tab_script_edited)); + scene_tabs->connect("tab_rmb_clicked", callable_mp(this, &EditorNode::_scene_tab_script_edited)); scene_tabs->connect("tab_closed", callable_mp(this, &EditorNode::_scene_tab_closed), varray(SCENE_TAB_CLOSE)); scene_tabs->connect("tab_hovered", callable_mp(this, &EditorNode::_scene_tab_hovered)); scene_tabs->connect("mouse_exited", callable_mp(this, &EditorNode::_scene_tab_exit)); scene_tabs->connect("gui_input", callable_mp(this, &EditorNode::_scene_tab_input)); - scene_tabs->connect("reposition_active_tab_request", callable_mp(this, &EditorNode::_reposition_active_tab)); + scene_tabs->connect("active_tab_rearranged", callable_mp(this, &EditorNode::_reposition_active_tab)); scene_tabs->connect("resized", callable_mp(this, &EditorNode::_update_scene_tabs)); tabbar_container = memnew(HBoxContainer); diff --git a/editor/editor_node.h b/editor/editor_node.h index d1f4cf8452..07c834eeca 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -542,6 +542,7 @@ private: String import_reload_fn; + Set<String> textfile_extensions; Set<FileDialog *> file_dialogs; Set<EditorFileDialog *> editor_file_dialogs; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 99b917107e..7afc8d4c83 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -219,7 +219,7 @@ Array EditorInterface::get_open_scenes() const { if (scenes[idx_scn].root == nullptr) { continue; } - ret.push_back(scenes[idx_scn].root->get_filename()); + ret.push_back(scenes[idx_scn].root->get_scene_file_path()); } return ret; } @@ -291,11 +291,11 @@ Error EditorInterface::save_scene() { if (!get_edited_scene_root()) { return ERR_CANT_CREATE; } - if (get_edited_scene_root()->get_filename() == String()) { + if (get_edited_scene_root()->get_scene_file_path() == String()) { return ERR_CANT_CREATE; } - save_scene_as(get_edited_scene_root()->get_filename()); + save_scene_as(get_edited_scene_root()->get_scene_file_path()); return OK; } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index c0dadc4484..2d4a3ac788 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -3574,7 +3574,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ case Variant::PACKED_COLOR_ARRAY: { EditorPropertyArray *editor = memnew(EditorPropertyArray); editor->setup(Variant::PACKED_COLOR_ARRAY); - + return editor; } break; default: { } diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 9cecb62c66..9b5dc8851c 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -429,6 +429,12 @@ void EditorPropertyArray::_button_draw() { bool EditorPropertyArray::_is_drop_valid(const Dictionary &p_drag_data) const { String allowed_type = Variant::get_type_name(subtype); + // When the subtype is of type Object, an additional subtype may be specified in the hint string + // (e.g. Resource, Texture2D, ShaderMaterial, etc). We want the allowed type to be that, not just "Object". + if (subtype == Variant::OBJECT && subtype_hint_string != "") { + allowed_type = subtype_hint_string; + } + Dictionary drag_data = p_drag_data; if (drag_data.has("type") && String(drag_data["type"]) == "files") { diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 5828549bdc..74ebffc404 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -66,9 +66,9 @@ void EditorRunNative::_notification(int p_what) { bool changed = EditorExport::get_singleton()->poll_export_platforms() || first; if (changed) { - for (Map<int, MenuButton *>::Element *E = menus.front(); E; E = E->next()) { - Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(E->key()); - MenuButton *mb = E->get(); + for (KeyValue<int, MenuButton *> &E : menus) { + Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(E.key); + MenuButton *mb = E.value; int dc = eep->get_options_count(); if (dc == 0) { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 70f43e01cf..f0e97a7787 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -73,14 +73,15 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) if (p_name == "shortcuts") { Array arr = p_value; - ERR_FAIL_COND_V(arr.size() && arr.size() & 1, true); - for (int i = 0; i < arr.size(); i += 2) { - String name = arr[i]; - Ref<InputEvent> shortcut = arr[i + 1]; + for (int i = 0; i < arr.size(); i++) { + Dictionary dict = arr[i]; + String name = dict["name"]; + + Array shortcut_events = dict["shortcuts"]; Ref<Shortcut> sc; sc.instantiate(); - sc->set_event(shortcut); + sc->set_events(shortcut_events); add_shortcut(name, sc); } @@ -138,11 +139,11 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { _THREAD_SAFE_METHOD_ if (p_name == "shortcuts") { - Array arr; - for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) { - Ref<Shortcut> sc = E->get(); + Array save_array; + for (const KeyValue<String, Ref<Shortcut>> &shortcut_definition : shortcuts) { + Ref<Shortcut> sc = shortcut_definition.value; - if (builtin_action_overrides.has(E->key())) { + if (builtin_action_overrides.has(shortcut_definition.key)) { // This shortcut was auto-generated from built in actions: don't save. continue; } @@ -151,34 +152,57 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { if (!sc->has_meta("original")) { continue; //this came from settings but is not any longer used } + } - Ref<InputEvent> original = sc->get_meta("original"); - if (sc->matches_event(original) || (original.is_null() && sc->get_event().is_null())) { - continue; //not changed from default, don't save - } + Array original_events = sc->get_meta("original"); + Array shortcut_events = sc->get_events(); + + bool is_same = Shortcut::is_event_array_equal(original_events, shortcut_events); + if (is_same) { + continue; // Not changed from default; don't save. } - arr.push_back(E->key()); - arr.push_back(sc->get_event()); + Dictionary dict; + dict["name"] = shortcut_definition.key; + dict["shortcuts"] = shortcut_events; + + save_array.push_back(dict); } - r_ret = arr; + r_ret = save_array; return true; } else if (p_name == "builtin_action_overrides") { Array actions_arr; - for (Map<String, List<Ref<InputEvent>>>::Element *E = builtin_action_overrides.front(); E; E = E->next()) { - List<Ref<InputEvent>> events = E->get(); + for (const KeyValue<String, List<Ref<InputEvent>>> &action_override : builtin_action_overrides) { + List<Ref<InputEvent>> events = action_override.value; - // TODO: skip actions which are the same as the builtin. Dictionary action_dict; - action_dict["name"] = E->key(); + action_dict["name"] = action_override.key; + // Convert the list to an array, and only keep key events as this is for the editor. Array events_arr; - for (List<Ref<InputEvent>>::Element *I = events.front(); I; I = I->next()) { - events_arr.push_back(I->get()); + for (const Ref<InputEvent> &ie : events) { + Ref<InputEventKey> iek = ie; + if (iek.is_valid()) { + events_arr.append(iek); + } } - action_dict["events"] = events_arr; + Array defaults_arr; + List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins()[action_override.key]; + for (const Ref<InputEvent> &default_input_event : defaults) { + if (default_input_event.is_valid()) { + defaults_arr.append(default_input_event); + } + } + + bool same = Shortcut::is_event_array_equal(events_arr, defaults_arr); + // Don't save if same as default. + if (same) { + continue; + } + + action_dict["events"] = events_arr; actions_arr.push_back(action_dict); } @@ -460,6 +484,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // FileSystem EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "docks/filesystem/thumbnail_size", 64, "32,128,16") _initial_set("docks/filesystem/always_show_folders", true); + _initial_set("docks/filesystem/textfile_extensions", "txt,md,cfg,ini,log,json,yml,yaml,toml"); // Property editor _initial_set("docks/property_editor/auto_refresh_interval", 0.2); //update 5 times per second by default @@ -1404,7 +1429,7 @@ Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const { const Map<String, List<Ref<InputEvent>>>::Element *builtin_override = builtin_action_overrides.find(p_name); if (builtin_override) { sc.instantiate(); - sc->set_event(builtin_override->get().front()->get()); + sc->set_events_list(&builtin_override->get()); sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name)); } @@ -1413,7 +1438,7 @@ Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const { const OrderedHashMap<String, List<Ref<InputEvent>>>::ConstElement builtin_default = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied().find(p_name); if (builtin_default) { sc.instantiate(); - sc->set_event(builtin_default.get().front()->get()); + sc->set_events_list(&builtin_default.get()); sc->set_name(InputMap::get_singleton()->get_builtin_display_name(p_name)); } } @@ -1428,8 +1453,8 @@ Ref<Shortcut> EditorSettings::get_shortcut(const String &p_name) const { } void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) { - for (const Map<String, Ref<Shortcut>>::Element *E = shortcuts.front(); E; E = E->next()) { - r_shortcuts->push_back(E->key()); + for (const KeyValue<String, Ref<Shortcut>> &E : shortcuts) { + r_shortcuts->push_back(E.key); } } @@ -1449,52 +1474,91 @@ void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_k Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); ERR_FAIL_COND_MSG(!sc.is_valid(), "Used ED_SHORTCUT_OVERRIDE with invalid shortcut: " + p_path + "."); + PackedInt32Array arr; + arr.push_back(p_keycode); + + ED_SHORTCUT_OVERRIDE_ARRAY(p_path, p_feature, arr); +} + +void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, const PackedInt32Array &p_keycodes) { + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); + ERR_FAIL_COND_MSG(!sc.is_valid(), "Used ED_SHORTCUT_OVERRIDE_ARRAY with invalid shortcut: " + p_path + "."); + // Only add the override if the OS supports the provided feature. - if (OS::get_singleton()->has_feature(p_feature)) { - Ref<InputEventKey> ie; - if (p_keycode) { - ie = InputEventKey::create_reference(p_keycode); + if (!OS::get_singleton()->has_feature(p_feature)) { + return; + } + + Array events; + + for (int i = 0; i < p_keycodes.size(); i++) { + Key keycode = (Key)p_keycodes[i]; + +#ifdef OSX_ENABLED + // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS + if (keycode == KEY_DELETE) { + keycode = KEY_MASK_CMD | KEY_BACKSPACE; } +#endif - // Directly override the existing shortcut. - sc->set_event(ie); - sc->set_meta("original", ie); + Ref<InputEventKey> ie; + if (keycode) { + ie = InputEventKey::create_reference(keycode); + events.push_back(ie); + } } + + // Directly override the existing shortcut. + sc->set_events(events); + sc->set_meta("original", events); } Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, Key p_keycode) { + PackedInt32Array arr; + arr.push_back(p_keycode); + return ED_SHORTCUT_ARRAY(p_path, p_name, arr); +} + +Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, const PackedInt32Array &p_keycodes) { + Array events; + + for (int i = 0; i < p_keycodes.size(); i++) { + Key keycode = (Key)p_keycodes[i]; + #ifdef OSX_ENABLED - // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS - if (p_keycode == KEY_DELETE) { - p_keycode = KEY_MASK_CMD | KEY_BACKSPACE; - } + // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS + if (keycode == KEY_DELETE) { + keycode = KEY_MASK_CMD | KEY_BACKSPACE; + } #endif - Ref<InputEventKey> ie; - if (p_keycode) { - ie = InputEventKey::create_reference(p_keycode); + Ref<InputEventKey> ie; + if (keycode) { + ie = InputEventKey::create_reference(keycode); + events.push_back(ie); + } } if (!EditorSettings::get_singleton()) { Ref<Shortcut> sc; sc.instantiate(); sc->set_name(p_name); - sc->set_event(ie); - sc->set_meta("original", ie); + sc->set_events(events); + sc->set_meta("original", events); return sc; } Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path); if (sc.is_valid()) { sc->set_name(p_name); //keep name (the ones that come from disk have no name) - sc->set_meta("original", ie); //to compare against changes + sc->set_meta("original", events); //to compare against changes return sc; } sc.instantiate(); sc->set_name(p_name); - sc->set_event(ie); - sc->set_meta("original", ie); //to compare against changes + sc->set_events(events); + sc->set_meta("original", events); //to compare against changes EditorSettings::get_singleton()->add_shortcut(p_path, sc); return sc; @@ -1549,7 +1613,7 @@ void EditorSettings::set_builtin_action_override(const String &p_name, const Arr // Update the shortcut (if it is used somewhere in the editor) to be the first event of the new list. if (shortcuts.has(p_name)) { - shortcuts[p_name]->set_event(event_list.front()->get()); + shortcuts[p_name]->set_events_list(&event_list); } } diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 9067539e29..04e227bc5c 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -201,7 +201,9 @@ Variant _EDITOR_GET(const String &p_setting); #define ED_IS_SHORTCUT(p_name, p_ev) (EditorSettings::get_singleton()->is_shortcut(p_name, p_ev)) Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, Key p_keycode = KEY_NONE); +Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, const PackedInt32Array &p_keycodes); void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_keycode = KEY_NONE); +void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, const PackedInt32Array &p_keycodes); Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path); #endif // EDITOR_SETTINGS_H diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 1890814da9..ec90af1bcc 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -330,9 +330,8 @@ void EditorSpinSlider::_draw_spin_slider() { float text_start = rtl ? Math::round(sb->get_offset().x) : Math::round(sb->get_offset().x + label_width + sep); Vector2 text_ofs = rtl ? Vector2(text_start + (number_width - TS->shaped_text_get_width(num_rid)), vofs) : Vector2(text_start, vofs); - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(num_rid); - int v_size = visual.size(); - const TextServer::Glyph *glyphs = visual.ptr(); + int v_size = TS->shaped_text_get_glyph_count(num_rid); + const Glyph *glyphs = TS->shaped_text_get_glyphs(num_rid); for (int i = 0; i < v_size; i++) { for (int j = 0; j < glyphs[i].repeat; j++) { if (text_ofs.x >= text_start && (text_ofs.x + glyphs[i].advance) <= (text_start + number_width)) { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 6e5b94dc07..0579fb4cbd 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -962,8 +962,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected); theme->set_stylebox("SceneTabBG", "EditorStyles", style_tab_unselected); theme->set_icon("close", "Tabs", theme->get_icon("GuiClose", "EditorIcons")); - theme->set_stylebox("button_pressed", "Tabs", style_menu); - theme->set_stylebox("button", "Tabs", style_menu); + theme->set_stylebox("close_bg_pressed", "Tabs", style_menu); + theme->set_stylebox("close_bg_highlight", "Tabs", style_menu); theme->set_icon("increment", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); theme->set_icon("decrement", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); theme->set_icon("increment", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); @@ -1084,6 +1084,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("folded", "CodeEdit", theme->get_icon("GuiTreeArrowRight", "EditorIcons")); theme->set_icon("can_fold", "CodeEdit", theme->get_icon("GuiTreeArrowDown", "EditorIcons")); theme->set_icon("executing_line", "CodeEdit", theme->get_icon("MainPlay", "EditorIcons")); + theme->set_icon("breakpoint", "CodeEdit", theme->get_icon("Breakpoint", "EditorIcons")); theme->set_constant("line_spacing", "CodeEdit", EDITOR_DEF("text_editor/appearance/whitespace/line_spacing", 6)); // H/VSplitContainer diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 5dd5c050e0..1d1976d7e5 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -106,7 +106,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory List<FileInfo> file_list; for (int i = 0; i < p_dir->get_file_count(); i++) { String file_type = p_dir->get_file_type(i); - if (_is_file_type_disabled_by_feature_profile(file_type)) { + if (file_type != "TextFile" && _is_file_type_disabled_by_feature_profile(file_type)) { // If type is disabled, file won't be displayed. continue; } @@ -1175,7 +1175,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ EditorData *ed = &editor->get_editor_data(); for (int j = 0; j < ed->get_edited_scene_count(); j++) { if (ed->get_scene_path(j) == file_changed_paths[i]) { - ed->get_edited_scene_root(j)->set_filename(new_item_path); + ed->get_edited_scene_root(j)->set_scene_file_path(new_item_path); editor->save_layout(); break; } @@ -1260,7 +1260,7 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> continue; } - path = get_tree()->get_edited_scene_root()->get_filename(); + path = get_tree()->get_edited_scene_root()->get_scene_file_path(); } else { path = EditorNode::get_editor_data().get_scene_path(i); } @@ -1270,7 +1270,7 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> } if (i == EditorNode::get_editor_data().get_edited_scene()) { - get_tree()->get_edited_scene_root()->set_filename(path); + get_tree()->get_edited_scene_root()->set_scene_file_path(path); } else { EditorNode::get_editor_data().set_scene_path(i, path); } @@ -1301,11 +1301,11 @@ void FileSystemDock::_update_dependencies_after_move(const Map<String, String> & void FileSystemDock::_update_project_settings_after_move(const Map<String, String> &p_renames) const { // Find all project settings of type FILE and replace them if needed. const Map<StringName, PropertyInfo> prop_info = ProjectSettings::get_singleton()->get_custom_property_info(); - for (const Map<StringName, PropertyInfo>::Element *E = prop_info.front(); E; E = E->next()) { - if (E->get().hint == PROPERTY_HINT_FILE) { - String old_path = GLOBAL_GET(E->key()); + for (const KeyValue<StringName, PropertyInfo> &E : prop_info) { + if (E.value.hint == PROPERTY_HINT_FILE) { + String old_path = GLOBAL_GET(E.key); if (p_renames.has(old_path)) { - ProjectSettings::get_singleton()->set_setting(E->key(), p_renames[old_path]); + ProjectSettings::get_singleton()->set_setting(E.key, p_renames[old_path]); } }; } @@ -1954,6 +1954,13 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected case FILE_NEW_RESOURCE: { new_resource_dialog->popup_create(true); } break; + case FILE_NEW_TEXTFILE: { + String fpath = path; + if (!fpath.ends_with("/")) { + fpath = fpath.get_base_dir(); + } + ScriptEditor::get_singleton()->open_text_file_create_dialog(fpath); + } break; } } @@ -2473,6 +2480,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str p_popup->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("New Scene..."), FILE_NEW_SCENE); p_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT); p_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE); + p_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE); p_popup->add_separator(); } @@ -2513,6 +2521,7 @@ void FileSystemDock::_tree_rmb_empty(const Vector2 &p_pos) { tree_popup->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("New Scene..."), FILE_NEW_SCENE); tree_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT); tree_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE); + tree_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE); tree_popup->set_position(tree->get_global_position() + p_pos); tree_popup->popup(); } @@ -2558,6 +2567,7 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { file_list_popup->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("New Scene..."), FILE_NEW_SCENE); file_list_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT); file_list_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE); + file_list_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE); file_list_popup->add_separator(); file_list_popup->add_icon_item(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), TTR("Open in File Manager"), FILE_SHOW_IN_EXPLORER); file_list_popup->set_position(files->get_global_position() + p_pos); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 21a7abe622..73bdd685b7 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -101,6 +101,7 @@ private: FILE_SHOW_IN_EXPLORER, FILE_COPY_PATH, FILE_NEW_RESOURCE, + FILE_NEW_TEXTFILE, FOLDER_EXPAND_ALL, FOLDER_COLLAPSE_ALL, }; diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index 9444706fd2..380b269675 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -840,8 +840,8 @@ void FindInFilesPanel::_on_replace_all_clicked() { PackedStringArray modified_files; - for (Map<String, TreeItem *>::Element *E = _file_items.front(); E; E = E->next()) { - TreeItem *file_item = E->value(); + for (KeyValue<String, TreeItem *> &E : _file_items) { + TreeItem *file_item = E.value; String fpath = file_item->get_metadata(0); Vector<Result> locations; diff --git a/editor/icons/Breakpoint.svg b/editor/icons/Breakpoint.svg new file mode 100644 index 0000000000..b95c2b511e --- /dev/null +++ b/editor/icons/Breakpoint.svg @@ -0,0 +1 @@ +<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 8c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7" fill="#e1e1e1"/><pathd="m12 8c0 2.209-1.791 4-4 4s-4-1.791-4-4 1.791-4 4-4 4 1.791 4 4" fill="#f6f6f6"/></svg> diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp index b6d0927ce6..4cd9066350 100644 --- a/editor/import/collada.cpp +++ b/editor/import/collada.cpp @@ -2095,19 +2095,19 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) { } void Collada::_merge_skeletons2(VisualScene *p_vscene) { - for (Map<String, SkinControllerData>::Element *E = state.skin_controller_data_map.front(); E; E = E->next()) { - SkinControllerData &cd = E->get(); + for (KeyValue<String, SkinControllerData> &E : state.skin_controller_data_map) { + SkinControllerData &cd = E.value; NodeSkeleton *skeleton = nullptr; - for (Map<String, Transform3D>::Element *F = cd.bone_rest_map.front(); F; F = F->next()) { + for (const KeyValue<String, Transform3D> &F : cd.bone_rest_map) { String name; - if (!state.sid_to_node_map.has(F->key())) { + if (!state.sid_to_node_map.has(F.key)) { continue; } - name = state.sid_to_node_map[F->key()]; + name = state.sid_to_node_map[F.key]; ERR_CONTINUE(!state.scene_map.has(name)); @@ -2248,9 +2248,9 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L p_node->default_transform = skel_inv * (skin.bind_shape /* p_node->get_global_transform()*/); // i honestly have no idea what to do with a previous model xform.. most exporters ignore it //make rests relative to the skeleton (they seem to be always relative to world) - for (Map<String, Transform3D>::Element *E = skin.bone_rest_map.front(); E; E = E->next()) { - E->get() = skel_inv * E->get(); //make the bone rest local to the skeleton - state.bone_rest_map[E->key()] = E->get(); // make it remember where the bone is globally, now that it's relative + for (KeyValue<String, Transform3D> &E : skin.bone_rest_map) { + E.value = skel_inv * E.value; //make the bone rest local to the skeleton + state.bone_rest_map[E.key] = E.value; // make it remember where the bone is globally, now that it's relative } //but most exporters seem to work only if i do this.. @@ -2302,8 +2302,8 @@ void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) { } void Collada::_optimize() { - for (Map<String, VisualScene>::Element *E = state.visual_scene_map.front(); E; E = E->next()) { - VisualScene &vs = E->get(); + for (KeyValue<String, VisualScene> &E : state.visual_scene_map) { + VisualScene &vs = E.value; for (int i = 0; i < vs.root_nodes.size(); i++) { _create_skeletons(&vs.root_nodes.write[i]); } diff --git a/editor/import/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp index 9a8abfa5c6..474c9d5296 100644 --- a/editor/import/dynamicfont_import_settings.cpp +++ b/editor/import/dynamicfont_import_settings.cpp @@ -1011,9 +1011,10 @@ void DynamicFontImportSettings::_glyph_text_selected() { if (text_rid.is_valid()) { TS->shaped_text_add_string(text_rid, text_edit->get_text(), font_main->get_rids(), 16, ftrs, text_edit->get_language()); TS->shaped_text_shape(text_rid); - const Vector<TextServer::Glyph> &gl = TS->shaped_text_get_glyphs(text_rid); + const Glyph *gl = TS->shaped_text_get_glyphs(text_rid); + const int gl_size = TS->shaped_text_get_glyph_count(text_rid); - for (int i = 0; i < gl.size(); i++) { + for (int i = 0; i < gl_size; i++) { if (gl[i].font_rid.is_valid() && gl[i].index != 0) { selected_glyphs.insert(gl[i].index); } diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 7ab80ac3b4..3de7426302 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -1314,8 +1314,8 @@ Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_t } void ColladaImport::_fix_param_animation_tracks() { - for (Map<String, Collada::Node *>::Element *E = collada.state.scene_map.front(); E; E = E->next()) { - Collada::Node *n = E->get(); + for (KeyValue<String, Collada::Node *> &E : collada.state.scene_map) { + Collada::Node *n = E.value; switch (n->type) { case Collada::Node::TYPE_NODE: { // ? do nothing @@ -1363,7 +1363,7 @@ void ColladaImport::_fix_param_animation_tracks() { for (int rti = 0; rti < rt.size(); rti++) { Collada::AnimationTrack *at = &collada.state.animation_tracks.write[rt[rti]]; - at->target = E->key(); + at->target = E.key; at->param = "morph/" + collada.state.mesh_name_map[mesh_name]; at->property = true; //at->param @@ -1431,11 +1431,11 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones animation->set_name(collada.state.animation_clips[p_clip].name); } - for (Map<String, NodeMap>::Element *E = node_map.front(); E; E = E->next()) { - if (E->get().bone < 0) { + for (const KeyValue<String, NodeMap> &E : node_map) { + if (E.value.bone < 0) { continue; } - bones_with_animation[E->key()] = false; + bones_with_animation[E.key] = false; } //store and validate tracks @@ -1626,19 +1626,19 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones if (p_make_tracks_in_all_bones) { //some bones may lack animation, but since we don't store pose as a property, we must add keyframes! - for (Map<String, bool>::Element *E = bones_with_animation.front(); E; E = E->next()) { - if (E->get()) { + for (const KeyValue<String, bool> &E : bones_with_animation) { + if (E.value) { continue; } - NodeMap &nm = node_map[E->key()]; + NodeMap &nm = node_map[E.key]; String path = scene->get_path_to(nm.node); ERR_CONTINUE(nm.bone < 0); Skeleton3D *sk = static_cast<Skeleton3D *>(nm.node); String name = sk->get_bone_name(nm.bone); path = path + ":" + name; - Collada::Node *cn = collada.state.scene_map[E->key()]; + Collada::Node *cn = collada.state.scene_map[E.key]; if (cn->ignore_anim) { WARN_PRINT("Collada: Ignoring animation on node: " + path); continue; diff --git a/editor/import/editor_importer_bake_reset.cpp b/editor/import/editor_importer_bake_reset.cpp index 00dce6850e..fb5de941ae 100644 --- a/editor/import/editor_importer_bake_reset.cpp +++ b/editor/import/editor_importer_bake_reset.cpp @@ -122,14 +122,14 @@ void BakeReset::_align_animations(AnimationPlayer *p_ap, const Map<StringName, B for (List<StringName>::Element *anim_i = anim_names.front(); anim_i; anim_i = anim_i->next()) { Ref<Animation> a = p_ap->get_animation(anim_i->get()); ERR_CONTINUE(a.is_null()); - for (Map<StringName, BakeResetRestBone>::Element *rest_bone_i = r_rest_bones.front(); rest_bone_i; rest_bone_i = rest_bone_i->next()) { - int track = a->find_track(NodePath(rest_bone_i->key())); + for (const KeyValue<StringName, BakeResetRestBone> &rest_bone_i : r_rest_bones) { + int track = a->find_track(NodePath(rest_bone_i.key)); if (track == -1) { continue; } int new_track = a->add_track(Animation::TYPE_TRANSFORM3D); - NodePath new_path = NodePath(rest_bone_i->key()); - BakeResetRestBone rest_bone = rest_bone_i->get(); + NodePath new_path = NodePath(rest_bone_i.key); + const BakeResetRestBone rest_bone = rest_bone_i.value; a->track_set_path(new_track, new_path); for (int key_i = 0; key_i < a->track_get_key_count(track); key_i++) { Vector3 loc; diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index c48d9bb117..2c9bc7dadf 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -980,6 +980,8 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/shadow_meshes", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lightmap_uv", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lods", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "lods/normal_split_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), 25.0f)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "lods/normal_merge_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), 60.0f)); } break; case INTERNAL_IMPORT_CATEGORY_MATERIAL: { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "use_external/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); @@ -1259,6 +1261,8 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m //do mesh processing bool generate_lods = p_generate_lods; + float split_angle = 25.0f; + float merge_angle = 60.0f; bool create_shadow_meshes = p_create_shadow_meshes; bool bake_lightmaps = p_light_bake_mode == LIGHT_BAKE_STATIC_LIGHTMAPS; String save_to_file; @@ -1301,6 +1305,14 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } } + if (mesh_settings.has("lods/normal_split_angle")) { + split_angle = mesh_settings["lods/normal_split_angle"]; + } + + if (mesh_settings.has("lods/normal_merge_angle")) { + merge_angle = mesh_settings["lods/normal_merge_angle"]; + } + if (mesh_settings.has("save_to_file/enabled") && bool(mesh_settings["save_to_file/enabled"]) && mesh_settings.has("save_to_file/path")) { save_to_file = mesh_settings["save_to_file/path"]; if (!save_to_file.is_resource_file()) { @@ -1310,8 +1322,9 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } if (generate_lods) { - src_mesh_node->get_mesh()->generate_lods(); + src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle); } + if (create_shadow_meshes) { src_mesh_node->get_mesh()->create_shadow_mesh(); } diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 61745cb6ee..96a53b3257 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -86,28 +86,28 @@ void ResourceImporterTexture::update_imports() { return; } - for (Map<StringName, MakeInfo>::Element *E = make_flags.front(); E; E = E->next()) { + for (const KeyValue<StringName, MakeInfo> &E : make_flags) { Ref<ConfigFile> cf; cf.instantiate(); - String src_path = String(E->key()) + ".import"; + String src_path = String(E.key) + ".import"; Error err = cf->load(src_path); ERR_CONTINUE(err != OK); bool changed = false; - if (E->get().flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { + if (E.value.flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { cf->set_value("params", "compress/normal_map", 1); changed = true; } - if (E->get().flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) { - cf->set_value("params", "roughness/mode", E->get().channel_for_roughness + 2); - cf->set_value("params", "roughness/src_normal", E->get().normal_path_for_roughness); + if (E.value.flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) { + cf->set_value("params", "roughness/mode", E.value.channel_for_roughness + 2); + cf->set_value("params", "roughness/src_normal", E.value.normal_path_for_roughness); changed = true; } - if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { + if (E.value.flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { int compress_to = cf->get_value("params", "detect_3d/compress_to"); cf->set_value("params", "detect_3d/compress_to", 0); if (compress_to == 1) { @@ -121,7 +121,7 @@ void ResourceImporterTexture::update_imports() { if (changed) { cf->save(src_path); - to_reimport.push_back(E->key()); + to_reimport.push_back(E.key); } } diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index f99ab9888a..7ab5308a47 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -771,52 +771,52 @@ void SceneImportSettings::_re_import() { Dictionary subresources; - for (Map<String, NodeData>::Element *E = node_map.front(); E; E = E->next()) { - if (E->get().settings.size()) { + for (KeyValue<String, NodeData> &E : node_map) { + if (E.value.settings.size()) { Dictionary d; - for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) { - d[String(F->key())] = F->get(); + for (const KeyValue<StringName, Variant> &F : E.value.settings) { + d[String(F.key)] = F.value; } - nodes[E->key()] = d; + nodes[E.key] = d; } } if (nodes.size()) { subresources["nodes"] = nodes; } - for (Map<String, MaterialData>::Element *E = material_map.front(); E; E = E->next()) { - if (E->get().settings.size()) { + for (KeyValue<String, MaterialData> &E : material_map) { + if (E.value.settings.size()) { Dictionary d; - for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) { - d[String(F->key())] = F->get(); + for (const KeyValue<StringName, Variant> &F : E.value.settings) { + d[String(F.key)] = F.value; } - materials[E->key()] = d; + materials[E.key] = d; } } if (materials.size()) { subresources["materials"] = materials; } - for (Map<String, MeshData>::Element *E = mesh_map.front(); E; E = E->next()) { - if (E->get().settings.size()) { + for (KeyValue<String, MeshData> &E : mesh_map) { + if (E.value.settings.size()) { Dictionary d; - for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) { - d[String(F->key())] = F->get(); + for (const KeyValue<StringName, Variant> &F : E.value.settings) { + d[String(F.key)] = F.value; } - meshes[E->key()] = d; + meshes[E.key] = d; } } if (meshes.size()) { subresources["meshes"] = meshes; } - for (Map<String, AnimationData>::Element *E = animation_map.front(); E; E = E->next()) { - if (E->get().settings.size()) { + for (KeyValue<String, AnimationData> &E : animation_map) { + if (E.value.settings.size()) { Dictionary d; - for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) { - d[String(F->key())] = F->get(); + for (const KeyValue<StringName, Variant> &F : E.value.settings) { + d[String(F.key)] = F.value; } - animations[E->key()] = d; + animations[E.key] = d; } } if (animations.size()) { @@ -889,8 +889,8 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { switch (current_action) { case ACTION_EXTRACT_MATERIALS: { - for (Map<String, MaterialData>::Element *E = material_map.front(); E; E = E->next()) { - MaterialData &md = material_map[E->key()]; + for (const KeyValue<String, MaterialData> &E : material_map) { + MaterialData &md = material_map[E.key]; TreeItem *item = external_path_tree->create_item(root); @@ -905,7 +905,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { item->set_text(2, "Already External"); item->set_tooltip(2, TTR("This material already references an external file, no action will be taken.\nDisable the external property for it to be extracted again.")); } else { - item->set_metadata(0, E->key()); + item->set_metadata(0, E.key); item->set_editable(0, true); item->set_checked(0, true); String path = p_path.plus_file(name); @@ -942,8 +942,8 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { external_paths->get_ok_button()->set_text(TTR("Extract")); } break; case ACTION_CHOOSE_MESH_SAVE_PATHS: { - for (Map<String, MeshData>::Element *E = mesh_map.front(); E; E = E->next()) { - MeshData &md = mesh_map[E->key()]; + for (const KeyValue<String, MeshData> &E : mesh_map) { + MeshData &md = mesh_map[E.key]; TreeItem *item = external_path_tree->create_item(root); @@ -958,7 +958,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { item->set_text(2, "Already Saving"); item->set_tooltip(2, TTR("This mesh already saves to an external resource, no action will be taken.")); } else { - item->set_metadata(0, E->key()); + item->set_metadata(0, E.key); item->set_editable(0, true); item->set_checked(0, true); String path = p_path.plus_file(name); @@ -995,8 +995,8 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { external_paths->get_ok_button()->set_text(TTR("Set Paths")); } break; case ACTION_CHOOSE_ANIMATION_SAVE_PATHS: { - for (Map<String, AnimationData>::Element *E = animation_map.front(); E; E = E->next()) { - AnimationData &ad = animation_map[E->key()]; + for (const KeyValue<String, AnimationData> &E : animation_map) { + AnimationData &ad = animation_map[E.key]; TreeItem *item = external_path_tree->create_item(root); @@ -1010,7 +1010,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) { item->set_text(2, "Already Saving"); item->set_tooltip(2, TTR("This animation already saves to an external resource, no action will be taken.")); } else { - item->set_metadata(0, E->key()); + item->set_metadata(0, E.key); item->set_editable(0, true); item->set_checked(0, true); String path = p_path.plus_file(name); diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index 5e6dd08e79..370394b475 100644 --- a/editor/import/scene_importer_mesh.cpp +++ b/editor/import/scene_importer_mesh.cpp @@ -30,11 +30,99 @@ #include "scene_importer_mesh.h" -#include "core/math/math_defs.h" +#include "core/math/random_pcg.h" +#include "core/math/static_raycaster.h" #include "scene/resources/surface_tool.h" #include <cstdint> +void EditorSceneImporterMesh::Surface::split_normals(const LocalVector<int> &p_indices, const LocalVector<Vector3> &p_normals) { + ERR_FAIL_COND(arrays.size() != RS::ARRAY_MAX); + + const PackedVector3Array &vertices = arrays[RS::ARRAY_VERTEX]; + int current_vertex_count = vertices.size(); + int new_vertex_count = p_indices.size(); + int final_vertex_count = current_vertex_count + new_vertex_count; + const int *indices_ptr = p_indices.ptr(); + + for (int i = 0; i < arrays.size(); i++) { + if (i == RS::ARRAY_INDEX) { + continue; + } + + if (arrays[i].get_type() == Variant::NIL) { + continue; + } + + switch (arrays[i].get_type()) { + case Variant::PACKED_VECTOR3_ARRAY: { + PackedVector3Array data = arrays[i]; + data.resize(final_vertex_count); + Vector3 *data_ptr = data.ptrw(); + if (i == RS::ARRAY_NORMAL) { + const Vector3 *normals_ptr = p_normals.ptr(); + memcpy(&data_ptr[current_vertex_count], normals_ptr, sizeof(Vector3) * new_vertex_count); + } else { + for (int j = 0; j < new_vertex_count; j++) { + data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; + } + } + arrays[i] = data; + } break; + case Variant::PACKED_VECTOR2_ARRAY: { + PackedVector2Array data = arrays[i]; + data.resize(final_vertex_count); + Vector2 *data_ptr = data.ptrw(); + for (int j = 0; j < new_vertex_count; j++) { + data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; + } + arrays[i] = data; + } break; + case Variant::PACKED_FLOAT32_ARRAY: { + PackedFloat32Array data = arrays[i]; + int elements = data.size() / current_vertex_count; + data.resize(final_vertex_count * elements); + float *data_ptr = data.ptrw(); + for (int j = 0; j < new_vertex_count; j++) { + memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(float) * elements); + } + arrays[i] = data; + } break; + case Variant::PACKED_INT32_ARRAY: { + PackedInt32Array data = arrays[i]; + int elements = data.size() / current_vertex_count; + data.resize(final_vertex_count * elements); + int32_t *data_ptr = data.ptrw(); + for (int j = 0; j < new_vertex_count; j++) { + memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(int32_t) * elements); + } + arrays[i] = data; + } break; + case Variant::PACKED_BYTE_ARRAY: { + PackedByteArray data = arrays[i]; + int elements = data.size() / current_vertex_count; + data.resize(final_vertex_count * elements); + uint8_t *data_ptr = data.ptrw(); + for (int j = 0; j < new_vertex_count; j++) { + memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(uint8_t) * elements); + } + arrays[i] = data; + } break; + case Variant::PACKED_COLOR_ARRAY: { + PackedColorArray data = arrays[i]; + data.resize(final_vertex_count); + Color *data_ptr = data.ptrw(); + for (int j = 0; j < new_vertex_count; j++) { + data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; + } + } break; + default: { + ERR_FAIL_MSG("Uhandled array type."); + } break; + } + } +} + void EditorSceneImporterMesh::add_blend_shape(const String &p_name) { ERR_FAIL_COND(surfaces.size() > 0); blend_shapes.push_back(p_name); @@ -157,29 +245,14 @@ void EditorSceneImporterMesh::set_surface_material(int p_surface, const Ref<Mate mesh.unref(); } -Basis EditorSceneImporterMesh::compute_rotation_matrix_from_ortho_6d(Vector3 p_x_raw, Vector3 p_y_raw) { - Vector3 x = p_x_raw.normalized(); - Vector3 z = x.cross(p_y_raw); - z = z.normalized(); - Vector3 y = z.cross(x); - Basis basis; - basis.set_axis(Vector3::AXIS_X, x); - basis.set_axis(Vector3::AXIS_Y, y); - basis.set_axis(Vector3::AXIS_Z, z); - return basis; -} - -void EditorSceneImporterMesh::generate_lods() { - if (!SurfaceTool::simplify_func) { - return; - } +void EditorSceneImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_split_angle) { if (!SurfaceTool::simplify_scale_func) { return; } - if (!SurfaceTool::simplify_sloppy_func) { + if (!SurfaceTool::simplify_with_attrib_func) { return; } - if (!SurfaceTool::simplify_with_attrib_func) { + if (!SurfaceTool::optimize_vertex_cache_func) { return; } @@ -190,67 +263,343 @@ void EditorSceneImporterMesh::generate_lods() { surfaces.write[i].lods.clear(); Vector<Vector3> vertices = surfaces[i].arrays[RS::ARRAY_VERTEX]; - Vector<int> indices = surfaces[i].arrays[RS::ARRAY_INDEX]; - if (indices.size() == 0) { + PackedInt32Array indices = surfaces[i].arrays[RS::ARRAY_INDEX]; + Vector<Vector3> normals = surfaces[i].arrays[RS::ARRAY_NORMAL]; + Vector<Vector2> uvs = surfaces[i].arrays[RS::ARRAY_TEX_UV]; + + unsigned int index_count = indices.size(); + unsigned int vertex_count = vertices.size(); + + if (index_count == 0) { continue; //no lods if no indices } - Vector<Vector3> normals = surfaces[i].arrays[RS::ARRAY_NORMAL]; - uint32_t vertex_count = vertices.size(); + const Vector3 *vertices_ptr = vertices.ptr(); - Vector<float> attributes; - Vector<float> normal_weights; - int32_t attribute_count = 6; - if (normals.size()) { - attributes.resize(normals.size() * attribute_count); - for (int32_t normal_i = 0; normal_i < normals.size(); normal_i++) { - Basis basis; - basis.set_euler(normals[normal_i]); - Vector3 basis_x = basis.get_axis(0); - Vector3 basis_y = basis.get_axis(1); - basis = compute_rotation_matrix_from_ortho_6d(basis_x, basis_y); - basis_x = basis.get_axis(0); - basis_y = basis.get_axis(1); - attributes.write[normal_i * attribute_count + 0] = basis_x.x; - attributes.write[normal_i * attribute_count + 1] = basis_x.y; - attributes.write[normal_i * attribute_count + 2] = basis_x.z; - attributes.write[normal_i * attribute_count + 3] = basis_y.x; - attributes.write[normal_i * attribute_count + 4] = basis_y.y; - attributes.write[normal_i * attribute_count + 5] = basis_y.z; - } - normal_weights.resize(vertex_count); - for (int32_t weight_i = 0; weight_i < normal_weights.size(); weight_i++) { - normal_weights.write[weight_i] = 1.0; + const int *indices_ptr = indices.ptr(); + + if (normals.is_empty()) { + normals.resize(vertices.size()); + Vector3 *n_ptr = normals.ptrw(); + for (unsigned int j = 0; j < index_count; j += 3) { + const Vector3 &v0 = vertices_ptr[indices_ptr[j + 0]]; + const Vector3 &v1 = vertices_ptr[indices_ptr[j + 1]]; + const Vector3 &v2 = vertices_ptr[indices_ptr[j + 2]]; + Vector3 n = vec3_cross(v0 - v2, v0 - v1).normalized(); + n_ptr[j + 0] = n; + n_ptr[j + 1] = n; + n_ptr[j + 2] = n; } - } else { - attribute_count = 0; } - const int min_indices = 10; - const float error_tolerance = 1.44224'95703; // Cube root of 3 - const float threshold = 1.0 / error_tolerance; - int index_target = indices.size() * threshold; - float max_mesh_error_percentage = 1e0f; + + float normal_merge_threshold = Math::cos(Math::deg2rad(p_normal_merge_angle)); + float normal_pre_split_threshold = Math::cos(Math::deg2rad(MIN(180.0f, p_normal_split_angle * 2.0f))); + float normal_split_threshold = Math::cos(Math::deg2rad(p_normal_split_angle)); + const Vector3 *normals_ptr = normals.ptr(); + + Map<Vector3, LocalVector<Pair<int, int>>> unique_vertices; + + LocalVector<int> vertex_remap; + LocalVector<int> vertex_inverse_remap; + LocalVector<Vector3> merged_vertices; + LocalVector<Vector3> merged_normals; + LocalVector<int> merged_normals_counts; + const Vector2 *uvs_ptr = uvs.ptr(); + + for (unsigned int j = 0; j < vertex_count; j++) { + const Vector3 &v = vertices_ptr[j]; + const Vector3 &n = normals_ptr[j]; + + Map<Vector3, LocalVector<Pair<int, int>>>::Element *E = unique_vertices.find(v); + + if (E) { + const LocalVector<Pair<int, int>> &close_verts = E->get(); + + bool found = false; + for (unsigned int k = 0; k < close_verts.size(); k++) { + const Pair<int, int> &idx = close_verts[k]; + + // TODO check more attributes? + if ((!uvs_ptr || uvs_ptr[j].distance_squared_to(uvs_ptr[idx.second]) < CMP_EPSILON2) && normals[idx.second].dot(n) > normal_merge_threshold) { + vertex_remap.push_back(idx.first); + merged_normals[idx.first] += normals[idx.second]; + merged_normals_counts[idx.first]++; + found = true; + break; + } + } + + if (!found) { + int vcount = merged_vertices.size(); + unique_vertices[v].push_back(Pair<int, int>(vcount, j)); + vertex_inverse_remap.push_back(j); + merged_vertices.push_back(v); + vertex_remap.push_back(vcount); + merged_normals.push_back(normals_ptr[j]); + merged_normals_counts.push_back(1); + } + } else { + int vcount = merged_vertices.size(); + unique_vertices[v] = LocalVector<Pair<int, int>>(); + unique_vertices[v].push_back(Pair<int, int>(vcount, j)); + vertex_inverse_remap.push_back(j); + merged_vertices.push_back(v); + vertex_remap.push_back(vcount); + merged_normals.push_back(normals_ptr[j]); + merged_normals_counts.push_back(1); + } + } + + LocalVector<int> merged_indices; + merged_indices.resize(index_count); + for (unsigned int j = 0; j < index_count; j++) { + merged_indices[j] = vertex_remap[indices[j]]; + } + + unsigned int merged_vertex_count = merged_vertices.size(); + const Vector3 *merged_vertices_ptr = merged_vertices.ptr(); + const int32_t *merged_indices_ptr = merged_indices.ptr(); + + { + const int *counts_ptr = merged_normals_counts.ptr(); + Vector3 *merged_normals_ptrw = merged_normals.ptr(); + for (unsigned int j = 0; j < merged_vertex_count; j++) { + merged_normals_ptrw[j] /= counts_ptr[j]; + } + } + + LocalVector<float> normal_weights; + normal_weights.resize(merged_vertex_count); + for (unsigned int j = 0; j < merged_vertex_count; j++) { + normal_weights[j] = 2.0; // Give some weight to normal preservation, may be worth exposing as an import setting + } + + const float max_mesh_error = FLT_MAX; // We don't want to limit by error, just by index target + float scale = SurfaceTool::simplify_scale_func((const float *)merged_vertices_ptr, merged_vertex_count, sizeof(Vector3)); float mesh_error = 0.0f; - float scale = SurfaceTool::simplify_scale_func((const float *)vertices_ptr, vertex_count, sizeof(Vector3)); - while (index_target > min_indices) { - Vector<int> new_indices; - new_indices.resize(indices.size()); - size_t new_len = SurfaceTool::simplify_with_attrib_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, max_mesh_error_percentage, &mesh_error, (float *)attributes.ptrw(), normal_weights.ptrw(), attribute_count); - if ((int)new_len > (index_target * error_tolerance)) { - break; + + unsigned int index_target = 12; // Start with the smallest target, 4 triangles + unsigned int last_index_count = 0; + + int split_vertex_count = vertex_count; + LocalVector<Vector3> split_vertex_normals; + LocalVector<int> split_vertex_indices; + split_vertex_normals.reserve(index_count / 3); + split_vertex_indices.reserve(index_count / 3); + + RandomPCG pcg; + pcg.seed(123456789); // Keep seed constant across imports + + Ref<StaticRaycaster> raycaster = StaticRaycaster::create(); + if (raycaster.is_valid()) { + raycaster->add_mesh(vertices, indices, 0); + raycaster->commit(); + } + + while (index_target < index_count) { + PackedInt32Array new_indices; + new_indices.resize(index_count); + + size_t new_index_count = SurfaceTool::simplify_with_attrib_func((unsigned int *)new_indices.ptrw(), (const uint32_t *)merged_indices_ptr, index_count, (const float *)merged_vertices_ptr, merged_vertex_count, sizeof(Vector3), index_target, max_mesh_error, &mesh_error, (float *)merged_normals.ptr(), normal_weights.ptr(), 3); + + if (new_index_count < last_index_count * 1.5f) { + index_target = index_target * 1.5f; + continue; } - Surface::LOD lod; - lod.distance = mesh_error * scale; - if (Math::is_zero_approx(mesh_error)) { + + if (new_index_count <= 0 || (new_index_count >= (index_count * 0.75f))) { break; } - if (new_len <= 0) { - break; + + new_indices.resize(new_index_count); + + LocalVector<LocalVector<int>> vertex_corners; + vertex_corners.resize(vertex_count); + { + int *ptrw = new_indices.ptrw(); + for (unsigned int j = 0; j < new_index_count; j++) { + const int &remapped = vertex_inverse_remap[ptrw[j]]; + vertex_corners[remapped].push_back(j); + ptrw[j] = remapped; + } } - new_indices.resize(new_len); + + if (raycaster.is_valid()) { + float error_factor = 1.0f / (scale * MAX(mesh_error, 0.15)); + const float ray_bias = 0.05; + float ray_length = ray_bias + mesh_error * scale * 3.0f; + + Vector<StaticRaycaster::Ray> rays; + LocalVector<Vector2> ray_uvs; + + int32_t *new_indices_ptr = new_indices.ptrw(); + + int current_ray_count = 0; + for (unsigned int j = 0; j < new_index_count; j += 3) { + const Vector3 &v0 = vertices_ptr[new_indices_ptr[j + 0]]; + const Vector3 &v1 = vertices_ptr[new_indices_ptr[j + 1]]; + const Vector3 &v2 = vertices_ptr[new_indices_ptr[j + 2]]; + Vector3 face_normal = vec3_cross(v0 - v2, v0 - v1); + float face_area = face_normal.length(); // Actually twice the face area, since it's the same error_factor on all faces, we don't care + + Vector3 dir = face_normal / face_area; + int ray_count = CLAMP(5.0 * face_area * error_factor, 16, 64); + + rays.resize(current_ray_count + ray_count); + StaticRaycaster::Ray *rays_ptr = rays.ptrw(); + + ray_uvs.resize(current_ray_count + ray_count); + Vector2 *ray_uvs_ptr = ray_uvs.ptr(); + + for (int k = 0; k < ray_count; k++) { + float u = pcg.randf(); + float v = pcg.randf(); + + if (u + v >= 1.0f) { + u = 1.0f - u; + v = 1.0f - v; + } + + u = 0.9f * u + 0.05f / 3.0f; // Give barycentric coordinates some padding, we don't want to sample right on the edge + v = 0.9f * v + 0.05f / 3.0f; // v = (v - one_third) * 0.95f + one_third; + float w = 1.0f - u - v; + + Vector3 org = v0 * w + v1 * u + v2 * v; + org -= dir * ray_bias; + rays_ptr[current_ray_count + k] = StaticRaycaster::Ray(org, dir, 0.0f, ray_length); + rays_ptr[current_ray_count + k].id = j / 3; + ray_uvs_ptr[current_ray_count + k] = Vector2(u, v); + } + + current_ray_count += ray_count; + } + + raycaster->intersect(rays); + + LocalVector<Vector3> ray_normals; + LocalVector<float> ray_normal_weights; + + ray_normals.resize(new_index_count); + ray_normal_weights.resize(new_index_count); + + for (unsigned int j = 0; j < new_index_count; j++) { + ray_normal_weights[j] = 0.0f; + } + + const StaticRaycaster::Ray *rp = rays.ptr(); + for (int j = 0; j < rays.size(); j++) { + if (rp[j].geomID != 0) { // Ray missed + continue; + } + + if (rp[j].normal.normalized().dot(rp[j].dir) > 0.0f) { // Hit a back face. + continue; + } + + const float &u = rp[j].u; + const float &v = rp[j].v; + const float w = 1.0f - u - v; + + const unsigned int &hit_tri_id = rp[j].primID; + const unsigned int &orig_tri_id = rp[j].id; + + const Vector3 &n0 = normals_ptr[indices_ptr[hit_tri_id * 3 + 0]]; + const Vector3 &n1 = normals_ptr[indices_ptr[hit_tri_id * 3 + 1]]; + const Vector3 &n2 = normals_ptr[indices_ptr[hit_tri_id * 3 + 2]]; + Vector3 normal = n0 * w + n1 * u + n2 * v; + + Vector2 orig_uv = ray_uvs[j]; + float orig_bary[3] = { 1.0f - orig_uv.x - orig_uv.y, orig_uv.x, orig_uv.y }; + for (int k = 0; k < 3; k++) { + int idx = orig_tri_id * 3 + k; + float weight = orig_bary[k]; + ray_normals[idx] += normal * weight; + ray_normal_weights[idx] += weight; + } + } + + for (unsigned int j = 0; j < new_index_count; j++) { + if (ray_normal_weights[j] < 1.0f) { // Not enough data, the new normal would be just a bad guess + ray_normals[j] = Vector3(); + } else { + ray_normals[j] /= ray_normal_weights[j]; + } + } + + LocalVector<LocalVector<int>> normal_group_indices; + LocalVector<Vector3> normal_group_averages; + normal_group_indices.reserve(24); + normal_group_averages.reserve(24); + + for (unsigned int j = 0; j < vertex_count; j++) { + const LocalVector<int> &corners = vertex_corners[j]; + const Vector3 &vertex_normal = normals_ptr[j]; + + for (unsigned int k = 0; k < corners.size(); k++) { + const int &corner_idx = corners[k]; + const Vector3 &ray_normal = ray_normals[corner_idx]; + + if (ray_normal.length_squared() < CMP_EPSILON2) { + continue; + } + + bool found = false; + for (unsigned int l = 0; l < normal_group_indices.size(); l++) { + LocalVector<int> &group_indices = normal_group_indices[l]; + Vector3 n = normal_group_averages[l] / group_indices.size(); + if (n.dot(ray_normal) > normal_pre_split_threshold) { + found = true; + group_indices.push_back(corner_idx); + normal_group_averages[l] += ray_normal; + break; + } + } + + if (!found) { + LocalVector<int> new_group; + new_group.push_back(corner_idx); + normal_group_indices.push_back(new_group); + normal_group_averages.push_back(ray_normal); + } + } + + for (unsigned int k = 0; k < normal_group_indices.size(); k++) { + LocalVector<int> &group_indices = normal_group_indices[k]; + Vector3 n = normal_group_averages[k] / group_indices.size(); + + if (vertex_normal.dot(n) < normal_split_threshold) { + split_vertex_indices.push_back(j); + split_vertex_normals.push_back(n); + int new_idx = split_vertex_count++; + for (unsigned int l = 0; l < group_indices.size(); l++) { + new_indices_ptr[group_indices[l]] = new_idx; + } + } + } + + normal_group_indices.clear(); + normal_group_averages.clear(); + } + } + + Surface::LOD lod; + lod.distance = MAX(mesh_error * scale, CMP_EPSILON2); lod.indices = new_indices; - print_line("Lod " + itos(surfaces.write[i].lods.size()) + " begin with " + itos(indices.size() / 3) + " triangles and shoot for " + itos(index_target / 3) + " triangles. Got " + itos(new_len / 3) + " triangles. Lod screen ratio " + rtos(lod.distance)); surfaces.write[i].lods.push_back(lod); - index_target *= threshold; + index_target = MAX(new_index_count, index_target) * 2; + last_index_count = new_index_count; + + if (mesh_error == 0.0f) { + break; + } + } + + surfaces.write[i].split_normals(split_vertex_indices, split_vertex_normals); + surfaces.write[i].lods.sort_custom<Surface::LODComparator>(); + + for (int j = 0; j < surfaces.write[i].lods.size(); j++) { + Surface::LOD &lod = surfaces.write[i].lods.write[j]; + unsigned int *lod_indices_ptr = (unsigned int *)lod.indices.ptrw(); + SurfaceTool::optimize_vertex_cache_func(lod_indices_ptr, lod_indices_ptr, lod.indices.size(), split_vertex_count); } } } @@ -347,7 +696,7 @@ void EditorSceneImporterMesh::create_shadow_mesh() { Map<Vector3, int> unique_vertices; const Vector3 *vptr = vertices.ptr(); for (int j = 0; j < vertex_count; j++) { - Vector3 v = vptr[j]; + const Vector3 &v = vptr[j]; Map<Vector3, int>::Element *E = unique_vertices.find(v); @@ -397,9 +746,9 @@ void EditorSceneImporterMesh::create_shadow_mesh() { index_wptr = new_indices.ptrw(); for (int k = 0; k < index_count; k++) { - int index = index_rptr[j]; + int index = index_rptr[k]; ERR_FAIL_INDEX(index, vertex_count); - index_wptr[j] = vertex_remap[index]; + index_wptr[k] = vertex_remap[index]; } lods[surfaces[i].lods[j].distance] = new_indices; @@ -436,9 +785,9 @@ void EditorSceneImporterMesh::_set_data(const Dictionary &p_data) { if (s.has("lods")) { lods = s["lods"]; } - Array blend_shapes; - if (s.has("blend_shapes")) { - blend_shapes = s["blend_shapes"]; + Array b_shapes; + if (s.has("b_shapes")) { + b_shapes = s["b_shapes"]; } Ref<Material> material; if (s.has("material")) { @@ -448,7 +797,7 @@ void EditorSceneImporterMesh::_set_data(const Dictionary &p_data) { if (s.has("flags")) { flags = s["flags"]; } - add_surface(prim, arr, blend_shapes, lods, material, name, flags); + add_surface(prim, arr, b_shapes, lods, material, name, flags); } } } @@ -617,8 +966,8 @@ Ref<NavigationMesh> EditorSceneImporterMesh::create_navigation_mesh() { Vector<Vector3> vertices; vertices.resize(unique_vertices.size()); - for (Map<Vector3, int>::Element *E = unique_vertices.front(); E; E = E->next()) { - vertices.write[E->get()] = E->key(); + for (const KeyValue<Vector3, int> &E : unique_vertices) { + vertices.write[E.value] = E.key; } Ref<NavigationMesh> nm; diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h index d32b1fdf74..111b191cae 100644 --- a/editor/import/scene_importer_mesh.h +++ b/editor/import/scene_importer_mesh.h @@ -32,6 +32,7 @@ #define EDITOR_SCENE_IMPORTER_MESH_H #include "core/io/resource.h" +#include "core/templates/local_vector.h" #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" #include "scene/resources/mesh.h" @@ -55,12 +56,20 @@ class EditorSceneImporterMesh : public Resource { Vector<BlendShape> blend_shape_data; struct LOD { Vector<int> indices; - float distance; + float distance = 0.0f; }; Vector<LOD> lods; Ref<Material> material; String name; uint32_t flags = 0; + + struct LODComparator { + _FORCE_INLINE_ bool operator()(const LOD &l, const LOD &r) const { + return l.distance < r.distance; + } + }; + + void split_normals(const LocalVector<int> &p_indices, const LocalVector<Vector3> &p_normals); }; Vector<Surface> surfaces; Vector<String> blend_shapes; @@ -71,7 +80,6 @@ class EditorSceneImporterMesh : public Resource { Ref<EditorSceneImporterMesh> shadow_mesh; Size2i lightmap_size_hint; - Basis compute_rotation_matrix_from_ortho_6d(Vector3 p_x_raw, Vector3 y_raw); protected: void _set_data(const Dictionary &p_data); @@ -103,7 +111,7 @@ public: void set_surface_material(int p_surface, const Ref<Material> &p_material); - void generate_lods(); + void generate_lods(float p_normal_merge_angle, float p_normal_split_angle); void create_shadow_mesh(); Ref<EditorSceneImporterMesh> get_shadow_mesh() const; diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp index 25bca1d4f4..8300dcf555 100644 --- a/editor/import_defaults_editor.cpp +++ b/editor/import_defaults_editor.cpp @@ -86,9 +86,9 @@ void ImportDefaultsEditor::_save() { if (settings->importer.is_valid()) { Dictionary modified; - for (Map<StringName, Variant>::Element *E = settings->values.front(); E; E = E->next()) { - if (E->get() != settings->default_values[E->key()]) { - modified[E->key()] = E->get(); + for (const KeyValue<StringName, Variant> &E : settings->values) { + if (E.value != settings->default_values[E.key]) { + modified[E.key] = E.value; } } diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 04ddf3552b..a559f05785 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -204,11 +204,24 @@ void InspectorDock::_load_resource(const String &p_type) { load_resource_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); } + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (int i = 0; i < textfile_ext.size(); i++) { + load_resource_dialog->add_filter("*." + textfile_ext[i] + " ; " + textfile_ext[i].to_upper()); + } + load_resource_dialog->popup_file_dialog(); } void InspectorDock::_resource_file_selected(String p_file) { - RES res = ResourceLoader::load(p_file); + RES res; + if (ResourceLoader::exists(p_file, "")) { + res = ResourceLoader::load(p_file); + } else { + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + if (textfile_ext.has(p_file.get_extension())) { + res = ScriptEditor::get_singleton()->open_file(p_file); + } + } if (res.is_null()) { warning_dialog->set_text(TTR("Failed to load resource.")); @@ -469,18 +482,19 @@ void InspectorDock::update(Object *p_object) { const bool is_object = p_object != nullptr; const bool is_resource = is_object && p_object->is_class("Resource"); + const bool is_text_file = is_object && p_object->is_class("TextFile"); const bool is_node = is_object && p_object->is_class("Node"); - object_menu->set_disabled(!is_object); - search->set_editable(is_object); - resource_save_button->set_disabled(!is_resource); - open_docs_button->set_disabled(!is_resource && !is_node); + object_menu->set_disabled(!is_object || is_text_file); + search->set_editable(is_object && !is_text_file); + resource_save_button->set_disabled(!is_resource || is_text_file); + open_docs_button->set_disabled(is_text_file || (!is_resource && !is_node)); PopupMenu *resource_extra_popup = resource_extra_button->get_popup(); - resource_extra_popup->set_item_disabled(resource_extra_popup->get_item_index(RESOURCE_COPY), !is_resource); - resource_extra_popup->set_item_disabled(resource_extra_popup->get_item_index(RESOURCE_MAKE_BUILT_IN), !is_resource); + resource_extra_popup->set_item_disabled(resource_extra_popup->get_item_index(RESOURCE_COPY), !is_resource || is_text_file); + resource_extra_popup->set_item_disabled(resource_extra_popup->get_item_index(RESOURCE_MAKE_BUILT_IN), !is_resource || is_text_file); - if (!is_object) { + if (!is_object || is_text_file) { warning->hide(); editor_path->clear_path(); return; diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 24cb660f7a..55ffbf9477 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -776,16 +776,16 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) { } if (player) { - for (Map<StringName, ProgressBar *>::Element *E = animations.front(); E; E = E->next()) { - Ref<AnimationNodeAnimation> an = blend_tree->get_node(E->key()); + for (const KeyValue<StringName, ProgressBar *> &E : animations) { + Ref<AnimationNodeAnimation> an = blend_tree->get_node(E.key); if (an.is_valid()) { if (player->has_animation(an->get_animation())) { Ref<Animation> anim = player->get_animation(an->get_animation()); if (anim.is_valid()) { - E->get()->set_max(anim->get_length()); + E.value->set_max(anim->get_length()); //StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node; - StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E->key()) + "/time"; - E->get()->set_value(AnimationTreeEditor::get_singleton()->get_tree()->get(time_path)); + StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E.key) + "/time"; + E.value->set_value(AnimationTreeEditor::get_singleton()->get_tree()->get(time_path)); } } } diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 664b2f521e..aacfc3e305 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -830,9 +830,9 @@ void EditorAssetLibrary::_update_image_queue() { int current_images = 0; List<int> to_delete; - for (Map<int, ImageQueue>::Element *E = image_queue.front(); E; E = E->next()) { - if (!E->get().active && current_images < max_images) { - String cache_filename_base = EditorPaths::get_singleton()->get_cache_dir().plus_file("assetimage_" + E->get().image_url.md5_text()); + for (KeyValue<int, ImageQueue> &E : image_queue) { + if (!E.value.active && current_images < max_images) { + String cache_filename_base = EditorPaths::get_singleton()->get_cache_dir().plus_file("assetimage_" + E.value.image_url.md5_text()); Vector<String> headers; if (FileAccess::exists(cache_filename_base + ".etag") && FileAccess::exists(cache_filename_base + ".data")) { @@ -844,14 +844,14 @@ void EditorAssetLibrary::_update_image_queue() { } } - Error err = E->get().request->request(E->get().image_url, headers); + Error err = E.value.request->request(E.value.image_url, headers); if (err != OK) { - to_delete.push_back(E->key()); + to_delete.push_back(E.key); } else { - E->get().active = true; + E.value.active = true; } current_images++; - } else if (E->get().active) { + } else if (E.value.active) { current_images++; } } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 66a1719ff3..a49dd916f3 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -748,8 +748,8 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retreive_locked, bool remove_canvas_item_if_parent_in_selection) { List<CanvasItem *> selection; - for (Map<Node *, Object *>::Element *E = editor_selection->get_selection().front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key()); + for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retreive_locked || !_is_node_locked(canvas_item))) { CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); if (se) { @@ -1460,8 +1460,8 @@ bool CanvasItemEditor::_gui_input_open_scene_on_double_click(const Ref<InputEven List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { CanvasItem *canvas_item = selection[0]; - if (canvas_item->get_filename() != "" && canvas_item != editor->get_edited_scene()) { - editor->open_request(canvas_item->get_filename()); + if (canvas_item->get_scene_file_path() != "" && canvas_item != editor->get_edited_scene()) { + editor->open_request(canvas_item->get_scene_file_path()); return true; } } @@ -3782,8 +3782,8 @@ void CanvasItemEditor::_notification(int p_what) { } // Update the viewport if bones changes - for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { - Object *b = ObjectDB::get_instance(E->key().from); + for (KeyValue<BoneKey, BoneList> &E : bone_list) { + Object *b = ObjectDB::get_instance(E.key.from); if (!b) { viewport->update(); break; @@ -3796,14 +3796,14 @@ void CanvasItemEditor::_notification(int p_what) { Transform2D global_xform = b2->get_global_transform(); - if (global_xform != E->get().xform) { - E->get().xform = global_xform; + if (global_xform != E.value.xform) { + E.value.xform = global_xform; viewport->update(); } Bone2D *bone = Object::cast_to<Bone2D>(b); - if (bone && bone->get_length() != E->get().length) { - E->get().length = bone->get_length(); + if (bone && bone->get_length() != E.value.length) { + E.value.length = bone->get_length(); viewport->update(); } } @@ -4263,8 +4263,8 @@ void CanvasItemEditor::_button_tool_select(int p_index) { void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, bool p_scale, bool p_on_existing) { Map<Node *, Object *> &selection = editor_selection->get_selection(); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); if (!canvas_item || !canvas_item->is_visible_in_tree()) { continue; } @@ -4695,8 +4695,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { Map<Node *, Object *> &selection = editor_selection->get_selection(); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); if (!canvas_item || !canvas_item->is_visible_in_tree()) { continue; } @@ -4741,8 +4741,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { case ANIM_CLEAR_POSE: { Map<Node *, Object *> &selection = editor_selection->get_selection(); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); if (!canvas_item || !canvas_item->is_visible_in_tree()) { continue; } @@ -4816,8 +4816,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { Node *editor_root = EditorNode::get_singleton()->get_edited_scene()->get_tree()->get_edited_scene_root(); undo_redo->create_action(TTR("Create Custom Bone2D(s) from Node(s)")); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - Node2D *n2d = Object::cast_to<Node2D>(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + Node2D *n2d = Object::cast_to<Node2D>(E.key); Bone2D *new_bone = memnew(Bone2D); String new_bone_name = n2d->get_name(); @@ -4861,8 +4861,8 @@ void CanvasItemEditor::_focus_selection(int p_op) { int count = 0; Map<Node *, Object *> &selection = editor_selection->get_selection(); - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E.key); if (!canvas_item) { continue; } @@ -5800,7 +5800,7 @@ void CanvasItemEditorViewport::_remove_preview() { } bool CanvasItemEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { - if (p_desired_node->get_filename() == p_target_scene_path) { + if (p_desired_node->get_scene_file_path() == p_target_scene_path) { return true; } @@ -5897,14 +5897,14 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons return false; } - if (editor->get_edited_scene()->get_filename() != "") { // cyclical instancing - if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instantiated_scene)) { + if (editor->get_edited_scene()->get_scene_file_path() != "") { // cyclical instancing + if (_cyclical_dependency_exists(editor->get_edited_scene()->get_scene_file_path(), instantiated_scene)) { memdelete(instantiated_scene); return false; } } - instantiated_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path)); + instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path)); editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene); editor_data->get_undo_redo().add_do_method(instantiated_scene, "set_owner", editor->get_edited_scene()); diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp index a4436525fb..6df2e34ceb 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp @@ -33,7 +33,7 @@ void GPUParticlesCollisionSDFEditorPlugin::_bake() { if (col_sdf) { if (col_sdf->get_texture().is_null() || !col_sdf->get_texture()->get_path().is_resource_file()) { - String path = get_tree()->get_edited_scene_root()->get_filename(); + String path = get_tree()->get_edited_scene_root()->get_scene_file_path(); if (path == String()) { path = "res://" + col_sdf->get_name() + "_data.exr"; } else { diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp index b4a70cd31d..123087446c 100644 --- a/editor/plugins/lightmap_gi_editor_plugin.cpp +++ b/editor/plugins/lightmap_gi_editor_plugin.cpp @@ -43,9 +43,9 @@ void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) { switch (err) { case LightmapGI::BAKE_ERROR_NO_SAVE_PATH: { - String scene_path = lightmap->get_filename(); + String scene_path = lightmap->get_scene_file_path(); if (scene_path == String()) { - scene_path = lightmap->get_owner()->get_filename(); + scene_path = lightmap->get_owner()->get_scene_file_path(); } if (scene_path == String()) { EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for lightmap images.\nSave your scene and try again.")); diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index eb771f2bc4..fb92359818 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -43,13 +43,13 @@ #include "scene/3d/decal.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/gpu_particles_collision_3d.h" +#include "scene/3d/joint_3d.h" #include "scene/3d/light_3d.h" #include "scene/3d/lightmap_gi.h" #include "scene/3d/lightmap_probe.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/navigation_region_3d.h" #include "scene/3d/occluder_instance_3d.h" -#include "scene/3d/physics_joint_3d.h" #include "scene/3d/position_3d.h" #include "scene/3d/ray_cast_3d.h" #include "scene/3d/reflection_probe.h" @@ -4773,10 +4773,10 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } Vector<Vector3> lines; - for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) { - if (E->get()) { - lines.push_back(E->key().from); - lines.push_back(E->key().to); + for (const KeyValue<_EdgeKey, bool> &E : edge_map) { + if (E.value) { + lines.push_back(E.key.from); + lines.push_back(E.key.to); } } diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index fdd4baaf7d..f179c01f89 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -357,8 +357,8 @@ int Node3DEditorViewport::get_selected_count() const { int count = 0; - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E.key); if (!sp) { continue; } @@ -864,8 +864,8 @@ void Node3DEditorViewport::_compute_edit(const Point2 &p_point) { Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; if (se && se->gizmo.is_valid()) { - for (Map<int, Transform3D>::Element *E = se->subgizmos.front(); E; E = E->next()) { - int subgizmo_id = E->key(); + for (const KeyValue<int, Transform3D> &E : se->subgizmos) { + int subgizmo_id = E.key; se->subgizmos[subgizmo_id] = se->gizmo->get_subgizmo_transform(subgizmo_id); } se->original_local = selected->get_transform(); @@ -1374,9 +1374,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Vector<int> ids; Vector<Transform3D> restore; - for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { - ids.push_back(GE->key()); - restore.push_back(GE->value()); + for (const KeyValue<int, Transform3D> &GE : se->subgizmos) { + ids.push_back(GE.key); + restore.push_back(GE.value); } se->gizmo->commit_subgizmos(ids, restore, true); @@ -1612,9 +1612,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Vector<int> ids; Vector<Transform3D> restore; - for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { - ids.push_back(GE->key()); - restore.push_back(GE->value()); + for (const KeyValue<int, Transform3D> &GE : se->subgizmos) { + ids.push_back(GE.key); + restore.push_back(GE.value); } se->gizmo->commit_subgizmos(ids, restore, false); @@ -1845,13 +1845,13 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } if (se->gizmo.is_valid()) { - for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { - Transform3D xform = GE->get(); + for (KeyValue<int, Transform3D> &GE : se->subgizmos) { + Transform3D xform = GE.value; Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords); if (!local_coords) { new_xform = se->original.affine_inverse() * new_xform; } - se->gizmo->set_subgizmo_transform(GE->key(), new_xform); + se->gizmo->set_subgizmo_transform(GE.key, new_xform); } } else { Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original, se->original_local, motion, snap, local_coords); @@ -1944,11 +1944,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } if (se->gizmo.is_valid()) { - for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { - Transform3D xform = GE->get(); + for (KeyValue<int, Transform3D> &GE : se->subgizmos) { + Transform3D xform = GE.value; Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original * xform, xform, motion, snap, local_coords); new_xform = se->original.affine_inverse() * new_xform; - se->gizmo->set_subgizmo_transform(GE->key(), new_xform); + se->gizmo->set_subgizmo_transform(GE.key, new_xform); } } else { Transform3D new_xform = _compute_transform(TRANSFORM_TRANSLATE, se->original, se->original_local, motion, snap, local_coords); @@ -2030,14 +2030,14 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Vector3 compute_axis = local_coords ? axis : plane.normal; if (se->gizmo.is_valid()) { - for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { - Transform3D xform = GE->get(); + for (KeyValue<int, Transform3D> &GE : se->subgizmos) { + Transform3D xform = GE.value; Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords); if (!local_coords) { new_xform = se->original.affine_inverse() * new_xform; } - se->gizmo->set_subgizmo_transform(GE->key(), new_xform); + se->gizmo->set_subgizmo_transform(GE.key, new_xform); } } else { Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords); @@ -2483,8 +2483,14 @@ static bool is_shortcut_pressed(const String &p_path) { if (shortcut.is_null()) { return false; } - InputEventKey *k = Object::cast_to<InputEventKey>(shortcut->get_event().ptr()); - if (k == nullptr) { + + const Array shortcuts = shortcut->get_events(); + Ref<InputEventKey> k; + if (shortcuts.size() > 0) { + k = shortcuts.front(); + } + + if (k.is_null()) { return false; } const Input &input = *Input::get_singleton(); @@ -2601,6 +2607,9 @@ void Node3DEditorViewport::_project_settings_changed() { const bool use_occlusion_culling = GLOBAL_GET("rendering/occlusion_culling/use_occlusion_culling"); viewport->set_use_occlusion_culling(use_occlusion_culling); + + const float lod_threshold = GLOBAL_GET("rendering/mesh_lod/lod_change/threshold_pixels"); + viewport->set_lod_threshold(lod_threshold); } void Node3DEditorViewport::_notification(int p_what) { @@ -2663,8 +2672,8 @@ void Node3DEditorViewport::_notification(int p_what) { bool changed = false; bool exist = false; - for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { - Node3D *sp = Object::cast_to<Node3D>(E->key()); + for (const KeyValue<Node *, Object *> &E : selection) { + Node3D *sp = Object::cast_to<Node3D>(E.key); if (!sp) { continue; } @@ -3806,8 +3815,8 @@ void Node3DEditorViewport::focus_selection() { } if (se->gizmo.is_valid()) { - for (Map<int, Transform3D>::Element *GE = se->subgizmos.front(); GE; GE = GE->next()) { - center += se->gizmo->get_subgizmo_transform(GE->key()).origin; + for (const KeyValue<int, Transform3D> &GE : se->subgizmos) { + center += se->gizmo->get_subgizmo_transform(GE.key).origin; count++; } } @@ -3917,7 +3926,7 @@ void Node3DEditorViewport::_remove_preview() { } bool Node3DEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { - if (p_desired_node->get_filename() == p_target_scene_path) { + if (p_desired_node->get_scene_file_path() == p_target_scene_path) { return true; } @@ -3959,15 +3968,15 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po return false; } - if (editor->get_edited_scene()->get_filename() != "") { // cyclical instancing - if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instantiated_scene)) { + if (editor->get_edited_scene()->get_scene_file_path() != "") { // cyclical instancing + if (_cyclical_dependency_exists(editor->get_edited_scene()->get_scene_file_path(), instantiated_scene)) { memdelete(instantiated_scene); return false; } } if (scene != nullptr) { - instantiated_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path)); + instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(path)); } editor_data->get_undo_redo().add_do_method(parent, "add_child", instantiated_scene); @@ -4747,8 +4756,8 @@ void Node3DEditor::update_transform_gizmo() { Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; if (se && se->gizmo.is_valid()) { - for (Map<int, Transform3D>::Element *E = se->subgizmos.front(); E; E = E->next()) { - Transform3D xf = se->sp->get_global_transform() * se->gizmo->get_subgizmo_transform(E->key()); + for (const KeyValue<int, Transform3D> &E : se->subgizmos) { + Transform3D xf = se->sp->get_global_transform() * se->gizmo->get_subgizmo_transform(E.key); gizmo_center += xf.origin; if (count == 0 && local_gizmo_coords) { gizmo_basis = xf.basis; @@ -6674,8 +6683,8 @@ Vector<int> Node3DEditor::get_subgizmo_selection() { Vector<int> ret; if (se) { - for (Map<int, Transform3D>::Element *E = se->subgizmos.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<int, Transform3D> &E : se->subgizmos) { + ret.push_back(E.key); } } return ret; diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.cpp b/editor/plugins/occluder_instance_3d_editor_plugin.cpp index ab88b9f00d..0328b1bea6 100644 --- a/editor/plugins/occluder_instance_3d_editor_plugin.cpp +++ b/editor/plugins/occluder_instance_3d_editor_plugin.cpp @@ -41,9 +41,9 @@ void OccluderInstance3DEditorPlugin::_bake_select_file(const String &p_file) { switch (err) { case OccluderInstance3D::BAKE_ERROR_NO_SAVE_PATH: { - String scene_path = occluder_instance->get_filename(); + String scene_path = occluder_instance->get_scene_file_path(); if (scene_path == String()) { - scene_path = occluder_instance->get_owner()->get_filename(); + scene_path = occluder_instance->get_owner()->get_scene_file_path(); } if (scene_path == String()) { EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for the occluder.\nSave your scene and try again.")); diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp index f92f50f826..b1e104e680 100644 --- a/editor/plugins/physical_bone_3d_editor_plugin.cpp +++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp @@ -43,6 +43,7 @@ void PhysicalBone3DEditor::_on_toggle_button_transform_joint(bool p_is_pressed) void PhysicalBone3DEditor::_set_move_joint() { if (selected) { selected->_set_gizmo_move_joint(button_transform_joint->is_pressed()); + Node3DEditor::get_singleton()->update_transform_gizmo(); } } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 6922a48a50..ccb63871b7 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1030,35 +1030,22 @@ void ScriptEditor::_file_dialog_action(String p_file) { } file->close(); memdelete(file); - [[fallthrough]]; - } - case FILE_OPEN: { - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("Script", &extensions); - if (extensions.find(p_file.get_extension())) { - Ref<Script> scr = ResourceLoader::load(p_file); - if (!scr.is_valid()) { - editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); - file_dialog_option = -1; - return; - } - edit(scr); - file_dialog_option = -1; - return; - } - - Error error; - Ref<TextFile> text_file = _load_text_file(p_file, &error); - if (error != OK) { - editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); + if (EditorFileSystem::get_singleton()) { + const Vector<String> textfile_extensions = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + if (textfile_extensions.has(p_file.get_extension())) { + EditorFileSystem::get_singleton()->update_file(p_file); + } } - if (text_file.is_valid()) { - edit(text_file); - file_dialog_option = -1; + if (!open_textfile_after_create) { return; } + [[fallthrough]]; + } + case FILE_OPEN: { + open_file(p_file); + file_dialog_option = -1; } break; case FILE_SAVE_AS: { ScriptEditorBase *current = _get_current_editor(); @@ -1133,8 +1120,13 @@ void ScriptEditor::_menu_option(int p_option) { file_dialog_option = FILE_NEW_TEXTFILE; file_dialog->clear_filters(); + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (int i = 0; i < textfile_ext.size(); i++) { + file_dialog->add_filter("*." + textfile_ext[i] + " ; " + textfile_ext[i].to_upper()); + } file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("New Text File...")); + open_textfile_after_create = true; } break; case FILE_OPEN: { file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); @@ -1148,6 +1140,11 @@ void ScriptEditor::_menu_option(int p_option) { file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); } + const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false); + for (int i = 0; i < textfile_ext.size(); i++) { + file_dialog->add_filter("*." + textfile_ext[i] + " ; " + textfile_ext[i].to_upper()); + } + file_dialog->popup_file_dialog(); file_dialog->set_title(TTR("Open File")); return; @@ -2436,6 +2433,41 @@ void ScriptEditor::open_script_create_dialog(const String &p_base_name, const St script_create_dialog->config(p_base_name, p_base_path); } +void ScriptEditor::open_text_file_create_dialog(const String &p_base_path, const String &p_base_name) { + file_dialog->set_current_file(p_base_name); + file_dialog->set_current_dir(p_base_path); + _menu_option(FILE_NEW_TEXTFILE); + open_textfile_after_create = false; +} + +RES ScriptEditor::open_file(const String &p_file) { + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("Script", &extensions); + if (extensions.find(p_file.get_extension())) { + Ref<Script> scr = ResourceLoader::load(p_file); + if (!scr.is_valid()) { + editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); + return RES(); + } + + edit(scr); + return scr; + } + + Error error; + Ref<TextFile> text_file = _load_text_file(p_file, &error); + if (error != OK) { + editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!")); + return RES(); + } + + if (text_file.is_valid()) { + edit(text_file); + return text_file; + } + return RES(); +} + void ScriptEditor::_editor_stop() { for (int i = 0; i < tab_container->get_child_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i)); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 6d9b27e0be..e0c7e668ce 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -366,6 +366,7 @@ class ScriptEditor : public PanelContainer { void _add_callback(Object *p_obj, const String &p_function, const PackedStringArray &p_args); void _res_saved_callback(const Ref<Resource> &p_res); + bool open_textfile_after_create = true; bool trim_trailing_whitespace_on_save; bool use_space_indentation; bool convert_indent_on_save; @@ -472,6 +473,8 @@ public: bool is_scripts_panel_toggled(); void apply_scripts() const; void open_script_create_dialog(const String &p_base_name, const String &p_base_path); + void open_text_file_create_dialog(const String &p_base_path, const String &p_base_name = ""); + RES open_file(const String &p_file); void ensure_select_current(); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 22ca5592bd..a88e24c0d0 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -131,9 +131,9 @@ void ShaderTextEditor::_load_theme_settings() { List<String> built_ins; if (shader.is_valid()) { - for (const Map<StringName, ShaderLanguage::FunctionInfo>::Element *E = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())).front(); E; E = E->next()) { - for (const Map<StringName, ShaderLanguage::BuiltInInfo>::Element *F = E->get().built_ins.front(); F; F = F->next()) { - built_ins.push_back(F->key()); + for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode()))) { + for (const KeyValue<StringName, ShaderLanguage::BuiltInInfo> &F : E.value.built_ins) { + built_ins.push_back(F.key); } } diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 309821b3dc..4e3ab5380b 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -37,9 +37,9 @@ #include "editor/plugins/animation_player_editor_plugin.h" #include "node_3d_editor_plugin.h" #include "scene/3d/collision_shape_3d.h" +#include "scene/3d/joint_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/physics_body_3d.h" -#include "scene/3d/physics_joint_3d.h" #include "scene/resources/capsule_shape_3d.h" #include "scene/resources/sphere_shape_3d.h" diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 165a381407..19e1b40a0d 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -437,8 +437,8 @@ void ThemeItemImportTree::_update_total_selected(Theme::DataType p_data_type) { } int count = 0; - for (Map<ThemeItem, ItemCheckedState>::Element *E = selected_items.front(); E; E = E->next()) { - ThemeItem ti = E->key(); + for (const KeyValue<ThemeItem, ItemCheckedState> &E : selected_items) { + ThemeItem ti = E.key; if (ti.data_type == p_data_type) { count++; } @@ -759,7 +759,7 @@ void ThemeItemImportTree::_import_selected() { ProgressDialog::get_singleton()->add_task("import_theme_items", TTR("Importing Theme Items"), selected_items.size() + 2); int idx = 0; - for (Map<ThemeItem, ItemCheckedState>::Element *E = selected_items.front(); E; E = E->next()) { + for (KeyValue<ThemeItem, ItemCheckedState> &E : selected_items) { // Arbitrary number of items to skip from reporting. // Reduces the number of UI updates that this causes when copying large themes. if (idx % 10 == 0) { @@ -769,8 +769,8 @@ void ThemeItemImportTree::_import_selected() { ProgressDialog::get_singleton()->task_step("import_theme_items", TTR("Importing items {n}/{n}").format(arr, "{n}"), idx); } - ItemCheckedState cs = E->get(); - ThemeItem ti = E->key(); + ItemCheckedState cs = E.value; + ThemeItem ti = E.key; if (cs == SELECT_IMPORT_DEFINITION || cs == SELECT_IMPORT_FULL) { Variant item_value = Variant(); @@ -3333,7 +3333,7 @@ ThemeEditor::ThemeEditor() { preview_tabs->set_h_size_flags(SIZE_EXPAND_FILL); preview_tabbar_hb->add_child(preview_tabs); preview_tabs->connect("tab_changed", callable_mp(this, &ThemeEditor::_change_preview_tab)); - preview_tabs->connect("right_button_pressed", callable_mp(this, &ThemeEditor::_remove_preview_tab)); + preview_tabs->connect("tab_rmb_clicked", callable_mp(this, &ThemeEditor::_remove_preview_tab)); HBoxContainer *add_preview_button_hb = memnew(HBoxContainer); preview_tabbar_hb->add_child(add_preview_button_hb); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index e98bd74b62..f21d5098d3 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -522,10 +522,10 @@ void TileAtlasView::_update_alternative_tiles_rect_cache() { } Vector3i TileAtlasView::get_alternative_tile_at_pos(const Vector2 p_pos) const { - for (Map<Vector2, Map<int, Rect2i>>::Element *E_coords = alternative_tiles_rect_cache.front(); E_coords; E_coords = E_coords->next()) { - for (Map<int, Rect2i>::Element *E_alternative = E_coords->value().front(); E_alternative; E_alternative = E_alternative->next()) { - if (E_alternative->value().has_point(p_pos)) { - return Vector3i(E_coords->key().x, E_coords->key().y, E_alternative->key()); + for (const KeyValue<Vector2, Map<int, Rect2i>> &E_coords : alternative_tiles_rect_cache) { + for (const KeyValue<int, Rect2i> &E_alternative : E_coords.value) { + if (E_alternative.value.has_point(p_pos)) { + return Vector3i(E_coords.key.x, E_coords.key.y, E_alternative.key); } } } diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 216c5f7c7d..1a69d19d3c 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -231,10 +231,14 @@ void GenericTilePolygonEditor::_zoom_changed() { void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) { switch (p_item_pressed) { - case RESET_TO_DEFAULT_TILE: + case RESET_TO_DEFAULT_TILE: { undo_redo->create_action(TTR("Edit Polygons")); undo_redo->add_do_method(this, "clear_polygons"); - undo_redo->add_do_method(this, "add_polygon", tile_set->get_tile_shape_polygon()); + Vector<Vector2> polygon = tile_set->get_tile_shape_polygon(); + for (int i = 0; i < polygon.size(); i++) { + polygon.write[i] = polygon[i] * tile_set->get_tile_size(); + } + undo_redo->add_do_method(this, "add_polygon", polygon); undo_redo->add_do_method(base_control, "update"); undo_redo->add_do_method(this, "emit_signal", "polygons_changed"); undo_redo->add_undo_method(this, "clear_polygons"); @@ -244,8 +248,8 @@ void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) { undo_redo->add_undo_method(base_control, "update"); undo_redo->add_undo_method(this, "emit_signal", "polygons_changed"); undo_redo->commit_action(true); - break; - case CLEAR_TILE: + } break; + case CLEAR_TILE: { undo_redo->create_action(TTR("Edit Polygons")); undo_redo->add_do_method(this, "clear_polygons"); undo_redo->add_do_method(base_control, "update"); @@ -257,7 +261,7 @@ void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) { undo_redo->add_undo_method(base_control, "update"); undo_redo->add_undo_method(this, "emit_signal", "polygons_changed"); undo_redo->commit_action(true); - break; + } break; default: break; } @@ -308,6 +312,9 @@ void GenericTilePolygonEditor::_snap_to_tile_shape(Point2 &r_point, float &r_cur ERR_FAIL_COND(!tile_set.is_valid()); Vector<Point2> polygon = tile_set->get_tile_shape_polygon(); + for (int i = 0; i < polygon.size(); i++) { + polygon.write[i] = polygon[i] * tile_set->get_tile_size(); + } Point2 snapped_point = r_point; // Snap to polygon vertices. @@ -539,7 +546,11 @@ void GenericTilePolygonEditor::set_tile_set(Ref<TileSet> p_tile_set) { // Set the default tile shape clear_polygons(); if (p_tile_set.is_valid()) { - add_polygon(p_tile_set->get_tile_shape_polygon()); + Vector<Vector2> polygon = p_tile_set->get_tile_shape_polygon(); + for (int i = 0; i < polygon.size(); i++) { + polygon.write[i] = polygon[i] * p_tile_set->get_tile_size(); + } + add_polygon(polygon); } } tile_set = p_tile_set; @@ -745,10 +756,10 @@ Variant TileDataDefaultEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_s } void TileDataDefaultEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, Map<TileMapCell, Variant> p_previous_values, Variant p_new_value) { - for (Map<TileMapCell, Variant>::Element *E = p_previous_values.front(); E; E = E->next()) { - Vector2i coords = E->key().get_atlas_coords(); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/%s", coords.x, coords.y, E->key().alternative_tile, property), E->get()); - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/%s", coords.x, coords.y, E->key().alternative_tile, property), p_new_value); + for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) { + Vector2i coords = E.key.get_atlas_coords(); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/%s", coords.x, coords.y, E.key.alternative_tile, property), E.value); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/%s", coords.x, coords.y, E.key.alternative_tile, property), p_new_value); } } @@ -1180,10 +1191,10 @@ Variant TileDataOcclusionShapeEditor::_get_value(TileSetAtlasSource *p_tile_set_ } void TileDataOcclusionShapeEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, Map<TileMapCell, Variant> p_previous_values, Variant p_new_value) { - for (Map<TileMapCell, Variant>::Element *E = p_previous_values.front(); E; E = E->next()) { - Vector2i coords = E->key().get_atlas_coords(); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/occlusion_layer_%d/polygon", coords.x, coords.y, E->key().alternative_tile, occlusion_layer), E->get()); - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/occlusion_layer_%d/polygon", coords.x, coords.y, E->key().alternative_tile, occlusion_layer), p_new_value); + for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) { + Vector2i coords = E.key.get_atlas_coords(); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/occlusion_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, occlusion_layer), E.value); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/occlusion_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, occlusion_layer), p_new_value); } } @@ -1265,17 +1276,21 @@ void TileDataCollisionEditor::_polygons_changed() { } Variant TileDataCollisionEditor::_get_painted_value() { + Dictionary dict; + dict["linear_velocity"] = dummy_object->get("linear_velocity"); + dict["angular_velocity"] = dummy_object->get("angular_velocity"); Array array; for (int i = 0; i < polygon_editor->get_polygon_count(); i++) { ERR_FAIL_COND_V(polygon_editor->get_polygon(i).size() < 3, Variant()); - Dictionary dict; - dict["points"] = polygon_editor->get_polygon(i); - dict["one_way"] = dummy_object->get(vformat("polygon_%d_one_way", i)); - dict["one_way_margin"] = dummy_object->get(vformat("polygon_%d_one_way_margin", i)); - array.push_back(dict); + Dictionary polygon_dict; + polygon_dict["points"] = polygon_editor->get_polygon(i); + polygon_dict["one_way"] = dummy_object->get(vformat("polygon_%d_one_way", i)); + polygon_dict["one_way_margin"] = dummy_object->get(vformat("polygon_%d_one_way_margin", i)); + array.push_back(polygon_dict); } + dict["polygons"] = array; - return array; + return dict; } void TileDataCollisionEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) { @@ -1291,12 +1306,14 @@ void TileDataCollisionEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_ } _polygons_changed(); + dummy_object->set("linear_velocity", tile_data->get_constant_linear_velocity(physics_layer)); + dummy_object->set("angular_velocity", tile_data->get_constant_angular_velocity(physics_layer)); for (int i = 0; i < tile_data->get_collision_polygons_count(physics_layer); i++) { dummy_object->set(vformat("polygon_%d_one_way", i), tile_data->is_collision_polygon_one_way(physics_layer, i)); dummy_object->set(vformat("polygon_%d_one_way_margin", i), tile_data->get_collision_polygon_one_way_margin(physics_layer, i)); } - for (Map<StringName, EditorProperty *>::Element *E = property_editors.front(); E; E = E->next()) { - E->get()->update_property(); + for (const KeyValue<StringName, EditorProperty *> &E : property_editors) { + E.value->update_property(); } polygon_editor->set_background(p_tile_set_atlas_source->get_texture(), p_tile_set_atlas_source->get_tile_texture_region(p_coords), p_tile_set_atlas_source->get_tile_effective_texture_offset(p_coords, p_alternative_tile), tile_data->get_flip_h(), tile_data->get_flip_v(), tile_data->get_transpose(), tile_data->get_modulate()); @@ -1306,13 +1323,16 @@ void TileDataCollisionEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_so TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); ERR_FAIL_COND(!tile_data); - Array array = p_value; + Dictionary dict = p_value; + tile_data->set_constant_linear_velocity(physics_layer, dict["linear_velocity"]); + tile_data->set_constant_angular_velocity(physics_layer, dict["angular_velocity"]); + Array array = dict["polygons"]; tile_data->set_collision_polygons_count(physics_layer, array.size()); for (int i = 0; i < array.size(); i++) { - Dictionary dict = array[i]; - tile_data->set_collision_polygon_points(physics_layer, i, dict["points"]); - tile_data->set_collision_polygon_one_way(physics_layer, i, dict["one_way"]); - tile_data->set_collision_polygon_one_way_margin(physics_layer, i, dict["one_way_margin"]); + Dictionary polygon_dict = array[i]; + tile_data->set_collision_polygon_points(physics_layer, i, polygon_dict["points"]); + tile_data->set_collision_polygon_one_way(physics_layer, i, polygon_dict["one_way"]); + tile_data->set_collision_polygon_one_way_margin(physics_layer, i, polygon_dict["one_way_margin"]); } polygon_editor->set_background(p_tile_set_atlas_source->get_texture(), p_tile_set_atlas_source->get_tile_texture_region(p_coords), p_tile_set_atlas_source->get_tile_effective_texture_offset(p_coords, p_alternative_tile), tile_data->get_flip_h(), tile_data->get_flip_v(), tile_data->get_transpose(), tile_data->get_modulate()); @@ -1322,37 +1342,41 @@ Variant TileDataCollisionEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile)); ERR_FAIL_COND_V(!tile_data, Variant()); + Dictionary dict; + dict["linear_velocity"] = tile_data->get_constant_linear_velocity(physics_layer); + dict["angular_velocity"] = tile_data->get_constant_angular_velocity(physics_layer); Array array; for (int i = 0; i < tile_data->get_collision_polygons_count(physics_layer); i++) { - Dictionary dict; - dict["points"] = tile_data->get_collision_polygon_points(physics_layer, i); - dict["one_way"] = tile_data->is_collision_polygon_one_way(physics_layer, i); - dict["one_way_margin"] = tile_data->get_collision_polygon_one_way_margin(physics_layer, i); - array.push_back(dict); + Dictionary polygon_dict; + polygon_dict["points"] = tile_data->get_collision_polygon_points(physics_layer, i); + polygon_dict["one_way"] = tile_data->is_collision_polygon_one_way(physics_layer, i); + polygon_dict["one_way_margin"] = tile_data->get_collision_polygon_one_way_margin(physics_layer, i); + array.push_back(polygon_dict); } - return array; + dict["polygons"] = array; + return dict; } void TileDataCollisionEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, Map<TileMapCell, Variant> p_previous_values, Variant p_new_value) { Array new_array = p_new_value; - for (Map<TileMapCell, Variant>::Element *E = p_previous_values.front(); E; E = E->next()) { - Array old_array = E->get(); + for (KeyValue<TileMapCell, Variant> &E : p_previous_values) { + Array old_array = E.value; - Vector2i coords = E->key().get_atlas_coords(); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygons_count", coords.x, coords.y, E->key().alternative_tile, physics_layer), old_array.size()); + Vector2i coords = E.key.get_atlas_coords(); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygons_count", coords.x, coords.y, E.key.alternative_tile, physics_layer), old_array.size()); for (int i = 0; i < old_array.size(); i++) { Dictionary dict = old_array[i]; - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/points", coords.x, coords.y, E->key().alternative_tile, physics_layer, i), dict["points"]); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way", coords.x, coords.y, E->key().alternative_tile, physics_layer, i), dict["one_way"]); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way_margin", coords.x, coords.y, E->key().alternative_tile, physics_layer, i), dict["one_way_margin"]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/points", coords.x, coords.y, E.key.alternative_tile, physics_layer, i), dict["points"]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way", coords.x, coords.y, E.key.alternative_tile, physics_layer, i), dict["one_way"]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way_margin", coords.x, coords.y, E.key.alternative_tile, physics_layer, i), dict["one_way_margin"]); } - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygons_count", coords.x, coords.y, E->key().alternative_tile, physics_layer), new_array.size()); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygons_count", coords.x, coords.y, E.key.alternative_tile, physics_layer), new_array.size()); for (int i = 0; i < new_array.size(); i++) { Dictionary dict = new_array[i]; - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/points", coords.x, coords.y, E->key().alternative_tile, physics_layer, i), dict["points"]); - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way", coords.x, coords.y, E->key().alternative_tile, physics_layer, i), dict["one_way"]); - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way_margin", coords.x, coords.y, E->key().alternative_tile, physics_layer, i), dict["one_way_margin"]); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/points", coords.x, coords.y, E.key.alternative_tile, physics_layer, i), dict["points"]); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way", coords.x, coords.y, E.key.alternative_tile, physics_layer, i), dict["one_way"]); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/physics_layer_%d/polygon_%d/one_way_margin", coords.x, coords.y, E.key.alternative_tile, physics_layer, i), dict["one_way_margin"]); } } } @@ -1378,6 +1402,27 @@ TileDataCollisionEditor::TileDataCollisionEditor() { polygon_editor->connect("polygons_changed", callable_mp(this, &TileDataCollisionEditor::_polygons_changed)); add_child(polygon_editor); + dummy_object->add_dummy_property("linear_velocity"); + dummy_object->set("linear_velocity", Vector2()); + dummy_object->add_dummy_property("angular_velocity"); + dummy_object->set("angular_velocity", 0.0); + + EditorProperty *linear_velocity_editor = EditorInspectorDefaultPlugin::get_editor_for_property(dummy_object, Variant::VECTOR2, "linear_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT); + linear_velocity_editor->set_object_and_property(dummy_object, "linear_velocity"); + linear_velocity_editor->set_label("linear_velocity"); + linear_velocity_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1)); + linear_velocity_editor->update_property(); + add_child(linear_velocity_editor); + property_editors["linear_velocity"] = linear_velocity_editor; + + EditorProperty *angular_velocity_editor = EditorInspectorDefaultPlugin::get_editor_for_property(dummy_object, Variant::FLOAT, "angular_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT); + angular_velocity_editor->set_object_and_property(dummy_object, "angular_velocity"); + angular_velocity_editor->set_label("angular_velocity"); + angular_velocity_editor->connect("property_changed", callable_mp(this, &TileDataCollisionEditor::_property_value_changed).unbind(1)); + angular_velocity_editor->update_property(); + add_child(angular_velocity_editor); + property_editors["angular_velocity"] = linear_velocity_editor; + _polygons_changed(); } @@ -1976,16 +2021,16 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t drag_type = DRAG_TYPE_NONE; } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET) { undo_redo->create_action(TTR("Painting Terrain Set")); - for (Map<TileMapCell, Variant>::Element *E = drag_modified.front(); E; E = E->next()) { - Dictionary dict = E->get(); - Vector2i coords = E->key().get_atlas_coords(); - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->key().alternative_tile), drag_painted_value); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->key().alternative_tile), dict["terrain_set"]); + for (KeyValue<TileMapCell, Variant> &E : drag_modified) { + Dictionary dict = E.value; + Vector2i coords = E.key.get_atlas_coords(); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), drag_painted_value); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]); Array array = dict["terrain_peering_bits"]; for (int i = 0; i < array.size(); i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (tile_set->is_valid_peering_bit_terrain(dict["terrain_set"], bit)) { - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E->key().alternative_tile), array[i]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); } } } @@ -1996,17 +2041,17 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t int terrain_set = int(painted["terrain_set"]); int terrain = int(painted["terrain"]); undo_redo->create_action(TTR("Painting Terrain")); - for (Map<TileMapCell, Variant>::Element *E = drag_modified.front(); E; E = E->next()) { - Dictionary dict = E->get(); - Vector2i coords = E->key().get_atlas_coords(); + for (KeyValue<TileMapCell, Variant> &E : drag_modified) { + Dictionary dict = E.value; + Vector2i coords = E.key.get_atlas_coords(); Array array = dict["terrain_peering_bits"]; for (int i = 0; i < array.size(); i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (tile_set->is_valid_peering_bit_terrain(terrain_set, bit)) { - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E->key().alternative_tile), terrain); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), terrain); } if (tile_set->is_valid_peering_bit_terrain(dict["terrain_set"], bit)) { - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E->key().alternative_tile), array[i]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); } } } @@ -2259,14 +2304,14 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi } else { if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET) { undo_redo->create_action(TTR("Painting Tiles Property")); - for (Map<TileMapCell, Variant>::Element *E = drag_modified.front(); E; E = E->next()) { - Dictionary dict = E->get(); - Vector2i coords = E->key().get_atlas_coords(); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->key().alternative_tile), dict["terrain_set"]); - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->key().alternative_tile), drag_painted_value); + for (KeyValue<TileMapCell, Variant> &E : drag_modified) { + Dictionary dict = E.value; + Vector2i coords = E.key.get_atlas_coords(); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), dict["terrain_set"]); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E.key.alternative_tile), drag_painted_value); Array array = dict["terrain_peering_bits"]; for (int i = 0; i < array.size(); i++) { - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E->key().alternative_tile), array[i]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); } } undo_redo->commit_action(false); @@ -2276,17 +2321,17 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi int terrain_set = int(painted["terrain_set"]); int terrain = int(painted["terrain"]); undo_redo->create_action(TTR("Painting Terrain")); - for (Map<TileMapCell, Variant>::Element *E = drag_modified.front(); E; E = E->next()) { - Dictionary dict = E->get(); - Vector2i coords = E->key().get_atlas_coords(); + for (KeyValue<TileMapCell, Variant> &E : drag_modified) { + Dictionary dict = E.value; + Vector2i coords = E.key.get_atlas_coords(); Array array = dict["terrain_peering_bits"]; for (int i = 0; i < array.size(); i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (tile_set->is_valid_peering_bit_terrain(terrain_set, bit)) { - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E->key().alternative_tile), terrain); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), terrain); } if (tile_set->is_valid_peering_bit_terrain(dict["terrain_set"], bit)) { - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E->key().alternative_tile), array[i]); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrains_peering_bit/" + String(TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[i]), coords.x, coords.y, E.key.alternative_tile), array[i]); } } } @@ -2398,10 +2443,10 @@ Variant TileDataNavigationEditor::_get_value(TileSetAtlasSource *p_tile_set_atla } void TileDataNavigationEditor::_setup_undo_redo_action(TileSetAtlasSource *p_tile_set_atlas_source, Map<TileMapCell, Variant> p_previous_values, Variant p_new_value) { - for (Map<TileMapCell, Variant>::Element *E = p_previous_values.front(); E; E = E->next()) { - Vector2i coords = E->key().get_atlas_coords(); - undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/navigation_layer_%d/polygon", coords.x, coords.y, E->key().alternative_tile, navigation_layer), E->get()); - undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/navigation_layer_%d/polygon", coords.x, coords.y, E->key().alternative_tile, navigation_layer), p_new_value); + for (const KeyValue<TileMapCell, Variant> &E : p_previous_values) { + Vector2i coords = E.key.get_atlas_coords(); + undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/navigation_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, navigation_layer), E.value); + undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/navigation_layer_%d/polygon", coords.x, coords.y, E.key.alternative_tile, navigation_layer), p_new_value); } } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index a248f23517..cc5ff90541 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -455,15 +455,15 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p switch (drag_type) { case DRAG_TYPE_PAINT: { Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, drag_last_mouse_pos, mpos); - for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) { - if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) { + for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { + if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) { continue; } - Vector2i coords = E->key(); + Vector2i coords = E.key; if (!drag_modified.has(coords)) { drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords)); } - tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } } break; case DRAG_TYPE_BUCKET: { @@ -471,15 +471,15 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p for (int i = 0; i < line.size(); i++) { if (!drag_modified.has(line[i])) { Map<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_continuous_checkbox->is_pressed()); - for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) { - if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) { + for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { + if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) { continue; } - Vector2i coords = E->key(); + Vector2i coords = E.key; if (!drag_modified.has(coords)) { drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords)); } - tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } } } @@ -531,15 +531,15 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p drag_start_mouse_pos = mpos; drag_modified.clear(); Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, mpos, mpos); - for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) { - if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) { + for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { + if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) { continue; } - Vector2i coords = E->key(); + Vector2i coords = E.key; if (!drag_modified.has(coords)) { drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords)); } - tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } } else if (tool_buttons_group->get_pressed_button() == line_tool_button) { drag_type = DRAG_TYPE_LINE; @@ -557,15 +557,15 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p for (int i = 0; i < line.size(); i++) { if (!drag_modified.has(line[i])) { Map<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_continuous_checkbox->is_pressed()); - for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) { - if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) { + for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { + if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) { continue; } - Vector2i coords = E->key(); + Vector2i coords = E.key; if (!drag_modified.has(coords)) { drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords)); } - tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } } } @@ -710,8 +710,8 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over // Expand the grid if needed if (expand_grid && !preview.is_empty()) { drawn_grid_rect = Rect2i(preview.front()->key(), Vector2i(1, 1)); - for (Map<Vector2i, TileMapCell>::Element *E = preview.front(); E; E = E->next()) { - drawn_grid_rect.expand_to(E->key()); + for (const KeyValue<Vector2i, TileMapCell> &E : preview) { + drawn_grid_rect.expand_to(E.key); } } } @@ -748,23 +748,23 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over } // Draw the preview. - for (Map<Vector2i, TileMapCell>::Element *E = preview.front(); E; E = E->next()) { + for (const KeyValue<Vector2i, TileMapCell> &E : preview) { Transform2D tile_xform; - tile_xform.set_origin(tile_map->map_to_world(E->key())); + tile_xform.set_origin(tile_map->map_to_world(E.key)); tile_xform.set_scale(tile_set->get_tile_size()); if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) { tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); } else { - if (tile_set->has_source(E->get().source_id)) { - TileSetSource *source = *tile_set->get_source(E->get().source_id); + if (tile_set->has_source(E.value.source_id)) { + TileSetSource *source = *tile_set->get_source(E.value.source_id); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { // Get tile data. - TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E->get().get_atlas_coords(), E->get().alternative_tile)); + TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E.value.get_atlas_coords(), E.value.alternative_tile)); // Compute the offset - Rect2i source_rect = atlas_source->get_tile_texture_region(E->get().get_atlas_coords()); - Vector2i tile_offset = atlas_source->get_tile_effective_texture_offset(E->get().get_atlas_coords(), E->get().alternative_tile); + Rect2i source_rect = atlas_source->get_tile_texture_region(E.value.get_atlas_coords()); + Vector2i tile_offset = atlas_source->get_tile_effective_texture_offset(E.value.get_atlas_coords(), E.value.alternative_tile); // Compute the destination rectangle in the CanvasItem. Rect2 dest_rect; @@ -772,9 +772,9 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over bool transpose = tile_data->get_transpose(); if (transpose) { - dest_rect.position = (tile_map->map_to_world(E->key()) - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset); + dest_rect.position = (tile_map->map_to_world(E.key) - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset); } else { - dest_rect.position = (tile_map->map_to_world(E->key()) - dest_rect.size / 2 - tile_offset); + dest_rect.position = (tile_map->map_to_world(E.key) - dest_rect.size / 2 - tile_offset); } dest_rect = xform.xform(dest_rect); @@ -1165,11 +1165,11 @@ void TileMapEditorTilesPlugin::_stop_dragging() { } undo_redo->create_action(TTR("Move tiles")); // Move the tiles. - for (Map<Vector2i, TileMapCell>::Element *E = cells_do.front(); E; E = E->next()) { - undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + for (const KeyValue<Vector2i, TileMapCell> &E : cells_do) { + undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } - for (Map<Vector2i, TileMapCell>::Element *E = cells_undo.front(); E; E = E->next()) { - undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + for (const KeyValue<Vector2i, TileMapCell> &E : cells_undo) { + undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } // Update the selection. @@ -1205,41 +1205,41 @@ void TileMapEditorTilesPlugin::_stop_dragging() { } break; case DRAG_TYPE_PAINT: { undo_redo->create_action(TTR("Paint tiles")); - for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) { - undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key())); - undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + for (const KeyValue<Vector2i, TileMapCell> &E : drag_modified) { + undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key)); + undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } undo_redo->commit_action(false); } break; case DRAG_TYPE_LINE: { Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, drag_start_mouse_pos, mpos); undo_redo->create_action(TTR("Paint tiles")); - for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) { - if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) { + for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { + if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) { continue; } - undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); - undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key())); + undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); + undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key)); } undo_redo->commit_action(); } break; case DRAG_TYPE_RECT: { Map<Vector2i, TileMapCell> to_draw = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos)); undo_redo->create_action(TTR("Paint tiles")); - for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) { - if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) { + for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { + if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) { continue; } - undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); - undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key())); + undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); + undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key)); } undo_redo->commit_action(); } break; case DRAG_TYPE_BUCKET: { undo_redo->create_action(TTR("Paint tiles")); - for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) { - undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key())); - undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + for (const KeyValue<Vector2i, TileMapCell> &E : drag_modified) { + undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key)); + undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } undo_redo->commit_action(false); } break; @@ -1364,17 +1364,17 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection( } int vertical_offset = 0; - for (Map<int, List<const TileMapCell *>>::Element *E_source = per_source.front(); E_source; E_source = E_source->next()) { + for (const KeyValue<int, List<const TileMapCell *>> &E_source : per_source) { // Per source. List<const TileMapCell *> unorganized; Rect2i encompassing_rect_coords; Map<Vector2i, const TileMapCell *> organized_pattern; - TileSetSource *source = *tile_set->get_source(E_source->key()); + TileSetSource *source = *tile_set->get_source(E_source.key); TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); if (atlas_source) { // Organize using coordinates. - for (const TileMapCell *current : E_source->get()) { + for (const TileMapCell *current : E_source.value) { if (current->alternative_tile == 0) { organized_pattern[current->get_atlas_coords()] = current; } else { @@ -1393,14 +1393,14 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection( } } else { // Add everything unorganized. - for (const TileMapCell *cell : E_source->get()) { + for (const TileMapCell *cell : E_source.value) { unorganized.push_back(cell); } } // Now add everything to the output pattern. - for (Map<Vector2i, const TileMapCell *>::Element *E_cell = organized_pattern.front(); E_cell; E_cell = E_cell->next()) { - selection_pattern->set_cell(E_cell->key() - encompassing_rect_coords.position + Vector2i(0, vertical_offset), E_cell->get()->source_id, E_cell->get()->get_atlas_coords(), E_cell->get()->alternative_tile); + for (const KeyValue<Vector2i, const TileMapCell *> &E_cell : organized_pattern) { + selection_pattern->set_cell(E_cell.key - encompassing_rect_coords.position + Vector2i(0, vertical_offset), E_cell.value->source_id, E_cell.value->get_atlas_coords(), E_cell.value->alternative_tile); } Vector2i organized_size = selection_pattern->get_size(); int unorganized_index = 0; @@ -2308,14 +2308,14 @@ Set<TileMapEditorTerrainsPlugin::TerrainsTilePattern> TileMapEditorTerrainsPlugi // Returns all tiles compatible with the given constraints. Set<TerrainsTilePattern> compatible_terrain_tile_patterns; - for (Map<TerrainsTilePattern, Set<TileMapCell>>::Element *E = per_terrain_terrains_tile_patterns_tiles[p_terrain_set].front(); E; E = E->next()) { + for (const KeyValue<TerrainsTilePattern, Set<TileMapCell>> &E : per_terrain_terrains_tile_patterns_tiles[p_terrain_set]) { int valid = true; int in_pattern_count = 0; for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (tile_set->is_valid_peering_bit_terrain(p_terrain_set, bit)) { // Check if the bit is compatible with the constraints. - Constraint terrain_bit_constraint = Constraint(tile_map, p_position, bit, E->key()[in_pattern_count]); + Constraint terrain_bit_constraint = Constraint(tile_map, p_position, bit, E.key[in_pattern_count]); Set<Constraint>::Element *in_set_constraint_element = p_constraints.find(terrain_bit_constraint); if (in_set_constraint_element && in_set_constraint_element->get().get_terrain() != terrain_bit_constraint.get_terrain()) { @@ -2327,7 +2327,7 @@ Set<TileMapEditorTerrainsPlugin::TerrainsTilePattern> TileMapEditorTerrainsPlugi } if (valid) { - compatible_terrain_tile_patterns.insert(E->key()); + compatible_terrain_tile_patterns.insert(E.key); } } @@ -2368,15 +2368,15 @@ Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_c // Count the number of occurrences per terrain. Map<Vector2i, TileSet::CellNeighbor> overlapping_terrain_bits = c.get_overlapping_coords_and_peering_bits(); - for (Map<Vector2i, TileSet::CellNeighbor>::Element *E_overlapping = overlapping_terrain_bits.front(); E_overlapping; E_overlapping = E_overlapping->next()) { - if (!p_to_replace.has(E_overlapping->key())) { - TileMapCell neighbor_cell = tile_map->get_cell(tile_map_layer, E_overlapping->key()); + for (const KeyValue<Vector2i, TileSet::CellNeighbor> &E_overlapping : overlapping_terrain_bits) { + if (!p_to_replace.has(E_overlapping.key)) { + TileMapCell neighbor_cell = tile_map->get_cell(tile_map_layer, E_overlapping.key); TileData *neighbor_tile_data = nullptr; if (terrain_tiles.has(neighbor_cell) && terrain_tiles[neighbor_cell]->get_terrain_set() == p_terrain_set) { neighbor_tile_data = terrain_tiles[neighbor_cell]; } - int terrain = neighbor_tile_data ? neighbor_tile_data->get_peering_bit_terrain(TileSet::CellNeighbor(E_overlapping->get())) : -1; + int terrain = neighbor_tile_data ? neighbor_tile_data->get_peering_bit_terrain(TileSet::CellNeighbor(E_overlapping.value)) : -1; if (terrain_count.has(terrain)) { terrain_count[terrain] = 0; } @@ -2387,10 +2387,10 @@ Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_c // Get the terrain with the max number of occurrences. int max = 0; int max_terrain = -1; - for (Map<int, int>::Element *E_terrain_count = terrain_count.front(); E_terrain_count; E_terrain_count = E_terrain_count->next()) { - if (E_terrain_count->get() > max) { - max = E_terrain_count->get(); - max_terrain = E_terrain_count->key(); + for (const KeyValue<int, int> &E_terrain_count : terrain_count) { + if (E_terrain_count.value > max) { + max = E_terrain_count.value; + max_terrain = E_terrain_count.key; } } @@ -2458,15 +2458,15 @@ Map<Vector2i, TileMapEditorTerrainsPlugin::TerrainsTilePattern> TileMapEditorTer while (!to_replace.is_empty()) { // Compute the minimum number of tile possibilities for each cell. int min_nb_possibilities = 100000000; - for (Map<Vector2i, Set<TerrainsTilePattern>>::Element *E = per_cell_acceptable_tiles.front(); E; E = E->next()) { - min_nb_possibilities = MIN(min_nb_possibilities, E->get().size()); + for (const KeyValue<Vector2i, Set<TerrainsTilePattern>> &E : per_cell_acceptable_tiles) { + min_nb_possibilities = MIN(min_nb_possibilities, E.value.size()); } // Get the set of possible cells to fill. LocalVector<Vector2i> to_choose_from; - for (Map<Vector2i, Set<TerrainsTilePattern>>::Element *E = per_cell_acceptable_tiles.front(); E; E = E->next()) { - if (E->get().size() == min_nb_possibilities) { - to_choose_from.push_back(E->key()); + for (const KeyValue<Vector2i, Set<TerrainsTilePattern>> &E : per_cell_acceptable_tiles) { + if (E.value.size() == min_nb_possibilities) { + to_choose_from.push_back(E.key); } } @@ -2584,9 +2584,9 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map // Add the constraints from the added tiles. Set<TileMapEditorTerrainsPlugin::Constraint> added_tiles_constraints_set; - for (Map<Vector2i, TerrainsTilePattern>::Element *E_to_paint = p_to_paint.front(); E_to_paint; E_to_paint = E_to_paint->next()) { - Vector2i coords = E_to_paint->key(); - TerrainsTilePattern terrains_tile_pattern = E_to_paint->get(); + for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) { + Vector2i coords = E_to_paint.key; + TerrainsTilePattern terrains_tile_pattern = E_to_paint.value; Set<TileMapEditorTerrainsPlugin::Constraint> cell_constraints = _get_constraints_from_added_tile(coords, p_terrain_set, terrains_tile_pattern); for (Set<TileMapEditorTerrainsPlugin::Constraint>::Element *E = cell_constraints.front(); E; E = E->next()) { @@ -2596,8 +2596,8 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map // Build the list of potential tiles to replace. Set<Vector2i> potential_to_replace; - for (Map<Vector2i, TerrainsTilePattern>::Element *E_to_paint = p_to_paint.front(); E_to_paint; E_to_paint = E_to_paint->next()) { - Vector2i coords = E_to_paint->key(); + for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) { + Vector2i coords = E_to_paint.key; for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { if (tile_map->is_existing_neighbor(TileSet::CellNeighbor(i))) { Vector2i neighbor = tile_map->get_neighbor_cell(coords, TileSet::CellNeighbor(i)); @@ -2612,8 +2612,8 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map Set<Vector2i> to_replace; // Add the central tiles to the one to replace. TODO: maybe change that. - for (Map<Vector2i, TerrainsTilePattern>::Element *E_to_paint = p_to_paint.front(); E_to_paint; E_to_paint = E_to_paint->next()) { - to_replace.insert(E_to_paint->key()); + for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) { + to_replace.insert(E_to_paint.key); } // Add the constraints from the surroundings of the modified areas. @@ -2627,9 +2627,9 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map Map<Constraint, Set<Vector2i>> source_tiles_of_constraint; for (Set<Constraint>::Element *E = removed_cells_constraints_set.front(); E; E = E->next()) { Map<Vector2i, TileSet::CellNeighbor> sources_of_constraint = E->get().get_overlapping_coords_and_peering_bits(); - for (Map<Vector2i, TileSet::CellNeighbor>::Element *E_source_tile_of_constraint = sources_of_constraint.front(); E_source_tile_of_constraint; E_source_tile_of_constraint = E_source_tile_of_constraint->next()) { - if (potential_to_replace.has(E_source_tile_of_constraint->key())) { - source_tiles_of_constraint[E->get()].insert(E_source_tile_of_constraint->key()); + for (const KeyValue<Vector2i, TileSet::CellNeighbor> &E_source_tile_of_constraint : sources_of_constraint) { + if (potential_to_replace.has(E_source_tile_of_constraint.key)) { + source_tiles_of_constraint[E->get()].insert(E_source_tile_of_constraint.key); } } } @@ -2646,8 +2646,8 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map potential_to_replace.erase(to_add_to_remove); to_replace.insert(to_add_to_remove); to_replace_modified = true; - for (Map<Constraint, Set<Vector2i>>::Element *E_source_tiles_of_constraint = source_tiles_of_constraint.front(); E_source_tiles_of_constraint; E_source_tiles_of_constraint = E_source_tiles_of_constraint->next()) { - E_source_tiles_of_constraint->get().erase(to_add_to_remove); + for (KeyValue<Constraint, Set<Vector2i>> &E_source_tiles_of_constraint : source_tiles_of_constraint) { + E_source_tiles_of_constraint.value.erase(to_add_to_remove); } break; } @@ -2665,13 +2665,13 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map Map<Vector2i, TerrainsTilePattern> wfc_output = _wave_function_collapse(to_replace, p_terrain_set, constraints); // Use the WFC run for the output. - for (Map<Vector2i, TerrainsTilePattern>::Element *E = wfc_output.front(); E; E = E->next()) { - output[E->key()] = _get_random_tile_from_pattern(p_terrain_set, E->get()); + for (const KeyValue<Vector2i, TerrainsTilePattern> &E : wfc_output) { + output[E.key] = _get_random_tile_from_pattern(p_terrain_set, E.value); } // Override the WFC results to make sure at least the painted tiles are actually painted. - for (Map<Vector2i, TerrainsTilePattern>::Element *E_to_paint = p_to_paint.front(); E_to_paint; E_to_paint = E_to_paint->next()) { - output[E_to_paint->key()] = _get_random_tile_from_pattern(p_terrain_set, E_to_paint->get()); + for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) { + output[E_to_paint.key] = _get_random_tile_from_pattern(p_terrain_set, E_to_paint.value); } return output; @@ -2749,9 +2749,9 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() { } break; case DRAG_TYPE_PAINT: { undo_redo->create_action(TTR("Paint terrain")); - for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) { - undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key())); - undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + for (const KeyValue<Vector2i, TileMapCell> &E : drag_modified) { + undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key)); + undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } undo_redo->commit_action(false); } break; @@ -2825,11 +2825,11 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent> to_draw[line[i]] = selected_terrains_tile_pattern; } Map<Vector2i, TileMapCell> modified = _draw_terrains(to_draw, selected_terrain_set); - for (Map<Vector2i, TileMapCell>::Element *E = modified.front(); E; E = E->next()) { - if (!drag_modified.has(E->key())) { - drag_modified[E->key()] = tile_map->get_cell(tile_map_layer, E->key()); + for (const KeyValue<Vector2i, TileMapCell> &E : modified) { + if (!drag_modified.has(E.key)) { + drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key); } - tile_map->set_cell(tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + tile_map->set_cell(tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } } } break; @@ -2864,9 +2864,9 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent> terrains_to_draw[tile_map->world_to_map(mpos)] = selected_terrains_tile_pattern; Map<Vector2i, TileMapCell> to_draw = _draw_terrains(terrains_to_draw, selected_terrain_set); - for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) { - drag_modified[E->key()] = tile_map->get_cell(tile_map_layer, E->key()); - tile_map->set_cell(tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile); + for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) { + drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key); + tile_map->set_cell(tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile); } } } diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 1f1408016b..bc026146ef 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -674,9 +674,9 @@ void TileSetAtlasSourceEditor::_update_tile_data_editors() { #undef ADD_TILE_DATA_EDITOR // Add tile data editors as children. - for (Map<String, TileDataEditor *>::Element *E = tile_data_editors.front(); E; E = E->next()) { + for (KeyValue<String, TileDataEditor *> &E : tile_data_editors) { // Tile Data Editor. - TileDataEditor *tile_data_editor = E->get(); + TileDataEditor *tile_data_editor = E.value; if (!tile_data_editor->is_inside_tree()) { tile_data_painting_editor_container->add_child(tile_data_editor); } @@ -716,9 +716,9 @@ void TileSetAtlasSourceEditor::_update_current_tile_data_editor() { } // Hide all editors but the current one. - for (Map<String, TileDataEditor *>::Element *E = tile_data_editors.front(); E; E = E->next()) { - E->get()->hide(); - E->get()->get_toolbar()->hide(); + for (const KeyValue<String, TileDataEditor *> &E : tile_data_editors) { + E.value->hide(); + E.value->get_toolbar()->hide(); } if (tile_data_editors.has(property)) { current_tile_data_editor = tile_data_editors[property]; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 27f30479cf..b1b64564bb 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -123,9 +123,9 @@ void VisualShaderGraphPlugin::set_connections(List<VisualShader::Connection> &p_ void VisualShaderGraphPlugin::show_port_preview(VisualShader::Type p_type, int p_node_id, int p_port_id) { if (visual_shader->get_shader_type() == p_type && links.has(p_node_id) && links[p_node_id].output_ports.has(p_port_id)) { - for (Map<int, Port>::Element *E = links[p_node_id].output_ports.front(); E; E = E->next()) { - if (E->value().preview_button != nullptr) { - E->value().preview_button->set_pressed(false); + for (const KeyValue<int, Port> &E : links[p_node_id].output_ports) { + if (E.value.preview_button != nullptr) { + E.value.preview_button->set_pressed(false); } } @@ -264,11 +264,11 @@ void VisualShaderGraphPlugin::register_curve_editor(int p_node_id, int p_index, } void VisualShaderGraphPlugin::update_uniform_refs() { - for (Map<int, Link>::Element *E = links.front(); E; E = E->next()) { - VisualShaderNodeUniformRef *ref = Object::cast_to<VisualShaderNodeUniformRef>(E->get().visual_node); + for (KeyValue<int, Link> &E : links) { + VisualShaderNodeUniformRef *ref = Object::cast_to<VisualShaderNodeUniformRef>(E.value.visual_node); if (ref) { - remove_node(E->get().type, E->key()); - add_node(E->get().type, E->key()); + remove_node(E.value.type, E.key); + add_node(E.value.type, E.key); } } } diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp index 5bbc0c9dd5..9a44d40dcb 100644 --- a/editor/plugins/voxel_gi_editor_plugin.cpp +++ b/editor/plugins/voxel_gi_editor_plugin.cpp @@ -33,7 +33,7 @@ void VoxelGIEditorPlugin::_bake() { if (voxel_gi) { if (voxel_gi->get_probe_data().is_null()) { - String path = get_tree()->get_edited_scene_root()->get_filename(); + String path = get_tree()->get_edited_scene_root()->get_scene_file_path(); if (path == String()) { path = "res://" + voxel_gi->get_name() + "_data.res"; } else { diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp index 3441060fad..95a5646013 100644 --- a/editor/progress_dialog.cpp +++ b/editor/progress_dialog.cpp @@ -63,9 +63,9 @@ void BackgroundProgress::_add_task(const String &p_task, const String &p_label, void BackgroundProgress::_update() { _THREAD_SAFE_METHOD_ - for (Map<String, int>::Element *E = updates.front(); E; E = E->next()) { - if (tasks.has(E->key())) { - _task_step(E->key(), E->get()); + for (const KeyValue<String, int> &E : updates) { + if (tasks.has(E.key)) { + _task_step(E.key, E.value); } } diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 14158b02c8..ad9c81458f 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -752,6 +752,9 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem if (p_only_scenes && type != "PackedScene") { continue; } + if (type == "TextFile") { + continue; + } TreeItem *file = include_files->create_item(p_item); file->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 5ce88949ef..a100e9fc55 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -187,8 +187,8 @@ void SceneTreeDock::_perform_instantiate_scenes(const Vector<String> &p_files, N break; } - if (edited_scene->get_filename() != "") { - if (_cyclical_dependency_exists(edited_scene->get_filename(), instantiated_scene)) { + if (edited_scene->get_scene_file_path() != "") { + if (_cyclical_dependency_exists(edited_scene->get_scene_file_path(), instantiated_scene)) { accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."), p_files[i])); accept->popup_centered(); error = true; @@ -196,7 +196,7 @@ void SceneTreeDock::_perform_instantiate_scenes(const Vector<String> &p_files, N } } - instantiated_scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_files[i])); + instantiated_scene->set_scene_file_path(ProjectSettings::get_singleton()->localize_path(p_files[i])); instances.push_back(instantiated_scene); } @@ -307,7 +307,7 @@ bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_de bool result = false; Vector<Node *> instances; while (true) { - if (p->get_filename() == p_target_scene_path) { + if (p->get_scene_file_path() == p_target_scene_path) { result = true; break; } @@ -442,7 +442,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (!node_clipboard.is_empty()) { _clear_clipboard(); } - clipboard_source_scene = editor->get_edited_scene()->get_filename(); + clipboard_source_scene = editor->get_edited_scene()->get_scene_file_path(); selection.sort_custom<Node::Comparator>(); @@ -465,9 +465,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } bool has_cycle = false; - if (edited_scene->get_filename() != String()) { + if (edited_scene->get_scene_file_path() != String()) { for (Node *E : node_clipboard) { - if (edited_scene->get_filename() == E->get_filename()) { + if (edited_scene->get_scene_file_path() == E->get_scene_file_path()) { has_cycle = true; break; } @@ -496,7 +496,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { editor_data->get_undo_redo().add_do_method(editor_selection, "clear"); Map<RES, RES> resource_remap; - String target_scene = editor->get_edited_scene()->get_filename(); + String target_scene = editor->get_edited_scene()->get_scene_file_path(); if (target_scene != clipboard_source_scene) { if (!clipboard_resource_remap.has(target_scene)) { Map<RES, RES> remap; @@ -517,8 +517,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { editor_data->get_undo_redo().add_do_method(paste_parent, "add_child", dup); - for (Map<const Node *, Node *>::Element *E2 = duplimap.front(); E2; E2 = E2->next()) { - Node *d = E2->value(); + for (KeyValue<const Node *, Node *> &E2 : duplimap) { + Node *d = E2.value; editor_data->get_undo_redo().add_do_method(d, "set_owner", owner); } @@ -808,7 +808,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { return; } - if (node->get_filename() != String()) { + if (node->get_scene_file_path() != String()) { accept->set_text(TTR("Instantiated scenes can't become root")); accept->popup_centered(); return; @@ -818,14 +818,14 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node); editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", node); editor_data->get_undo_redo().add_do_method(node, "add_child", root); - editor_data->get_undo_redo().add_do_method(node, "set_filename", root->get_filename()); - editor_data->get_undo_redo().add_do_method(root, "set_filename", String()); + editor_data->get_undo_redo().add_do_method(node, "set_scene_file_path", root->get_scene_file_path()); + editor_data->get_undo_redo().add_do_method(root, "set_scene_file_path", String()); editor_data->get_undo_redo().add_do_method(node, "set_owner", (Object *)nullptr); editor_data->get_undo_redo().add_do_method(root, "set_owner", node); _node_replace_owner(root, root, node, MODE_DO); - editor_data->get_undo_redo().add_undo_method(root, "set_filename", root->get_filename()); - editor_data->get_undo_redo().add_undo_method(node, "set_filename", String()); + editor_data->get_undo_redo().add_undo_method(root, "set_scene_file_path", root->get_scene_file_path()); + editor_data->get_undo_redo().add_undo_method(node, "set_scene_file_path", String()); editor_data->get_undo_redo().add_undo_method(node, "remove_child", root); editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", root); editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node); @@ -848,8 +848,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; } Ref<MultiNodeEdit> mne = memnew(MultiNodeEdit); - for (const Map<Node *, Object *>::Element *E = editor_selection->get_selection().front(); E; E = E->next()) { - mne->add_node(root->get_path_to(E->key())); + for (const KeyValue<Node *, Object *> &E : editor_selection->get_selection()) { + mne->add_node(root->get_path_to(E.key)); } EditorNode::get_singleton()->push_item(mne.ptr()); @@ -887,7 +887,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *node = remove_list[0]; if (node == editor_data->get_edited_scene_root()) { msg = vformat(TTR("Delete the root node \"%s\"?"), node->get_name()); - } else if (node->get_filename() == "" && node->get_child_count() > 0) { + } else if (node->get_scene_file_path() == "" && node->get_child_count() > 0) { // Display this message only for non-instantiated scenes msg = vformat(TTR("Delete node \"%s\" and its children?"), node->get_name()); } else { @@ -934,7 +934,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; } - if (tocopy != editor_data->get_edited_scene_root() && tocopy->get_filename() != "") { + if (tocopy != editor_data->get_edited_scene_root() && tocopy->get_scene_file_path() != "") { accept->set_text(TTR("Can't save the branch of an already instantiated scene.\nTo create a variation of a scene, you can make an inherited scene based on the instantiated scene using Scene > New Inherited Scene... instead.")); accept->popup_centered(); break; @@ -1047,10 +1047,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; } - ERR_FAIL_COND(node->get_filename() == String()); + ERR_FAIL_COND(node->get_scene_file_path() == String()); undo_redo->create_action(TTR("Make Local")); - undo_redo->add_do_method(node, "set_filename", ""); - undo_redo->add_undo_method(node, "set_filename", node->get_filename()); + undo_redo->add_do_method(node, "set_scene_file_path", ""); + undo_redo->add_undo_method(node, "set_scene_file_path", node->get_scene_file_path()); _node_replace_owner(node, node, root); undo_redo->add_do_method(scene_tree, "update_tree"); undo_redo->add_undo_method(scene_tree, "update_tree"); @@ -1064,7 +1064,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (e) { Node *node = e->get(); if (node) { - scene_tree->emit_signal(SNAME("open"), node->get_filename()); + scene_tree->emit_signal(SNAME("open"), node->get_scene_file_path()); } } } break; @@ -1694,7 +1694,7 @@ bool SceneTreeDock::_validate_no_instance() { List<Node *> selection = editor_selection->get_selected_node_list(); for (Node *E : selection) { - if (E != edited_scene && E->get_filename() != "") { + if (E != edited_scene && E->get_scene_file_path() != "") { accept->set_text(TTR("This operation can't be done on instantiated scenes.")); accept->popup_centered(); return false; @@ -2753,7 +2753,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { bool can_replace = true; for (Node *E : selection) { - if (E != edited_scene && (E->get_owner() != edited_scene || E->get_filename() != "")) { + if (E != edited_scene && (E->get_owner() != edited_scene || E->get_scene_file_path() != "")) { can_replace = false; break; } @@ -2785,7 +2785,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH); } - bool is_external = (selection[0]->get_filename() != ""); + bool is_external = (selection[0]->get_scene_file_path() != ""); if (is_external) { bool is_inherited = selection[0]->get_scene_inherited_state() != nullptr; bool is_top_level = selection[0]->get_owner() == nullptr; @@ -2885,9 +2885,9 @@ void SceneTreeDock::attach_script_to_selected(bool p_extend) { Ref<Script> existing = selected->get_script(); - String path = selected->get_filename(); + String path = selected->get_scene_file_path(); if (path == "") { - String root_path = editor_data->get_edited_scene_root()->get_filename(); + String root_path = editor_data->get_edited_scene_root()->get_scene_file_path(); if (root_path == "") { path = String("res://").plus_file(selected->get_name()); } else { @@ -2939,7 +2939,7 @@ void SceneTreeDock::attach_shader_to_selected() { if (path == "") { String root_path; if (editor_data->get_edited_scene_root()) { - root_path = editor_data->get_edited_scene_root()->get_filename(); + root_path = editor_data->get_edited_scene_root()->get_scene_file_path(); } String shader_name; if (selected_shader_material->get_name().is_empty()) { diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 3de87d9df7..ccca01ed8b 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -66,7 +66,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i emit_signal(SNAME("open"), n->get_scene_inherited_state()->get_path()); } } else { - emit_signal(SNAME("open"), n->get_filename()); + emit_signal(SNAME("open"), n->get_scene_file_path()); } } else if (p_id == BUTTON_SCRIPT) { Ref<Script> script_typed = n->get_script(); @@ -302,10 +302,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll } item->set_tooltip(0, tooltip); - } else if (p_node != get_scene_node() && p_node->get_filename() != "" && can_open_instance) { + } else if (p_node != get_scene_node() && p_node->get_scene_file_path() != "" && can_open_instance) { item->add_button(0, get_theme_icon(SNAME("InstanceOptions"), SNAME("EditorIcons")), BUTTON_SUBSCENE, false, TTR("Open in Editor")); - String tooltip = String(p_node->get_name()) + "\n" + TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class(); + String tooltip = String(p_node->get_name()) + "\n" + TTR("Instance:") + " " + p_node->get_scene_file_path() + "\n" + TTR("Type:") + " " + p_node->get_class(); if (p_node->get_editor_description() != String()) { tooltip += "\n\n" + p_node->get_editor_description(); } @@ -954,7 +954,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from Node *n = get_node(np); if (n) { // Only allow selection if not part of an instantiated scene. - if (!n->get_owner() || n->get_owner() == get_scene_node() || n->get_owner()->get_filename() == String()) { + if (!n->get_owner() || n->get_owner() == get_scene_node() || n->get_owner()->get_scene_file_path() == String()) { selected.push_back(n); icons.push_back(next->get_icon(0)); } diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 4cbc859e0c..1e19d9bd47 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -425,8 +425,8 @@ void ScriptCreateDialog::_lang_changed(int l) { templates[i].id = new_id; } // Disable overridden - for (Map<String, Vector<int>>::Element *E = template_overrides.front(); E; E = E->next()) { - const Vector<int> &overrides = E->get(); + for (const KeyValue<String, Vector<int>> &E : template_overrides) { + const Vector<int> &overrides = E.value; if (overrides.size() == 1) { continue; // doesn't override anything diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index f024589ef1..9062169e06 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -193,35 +193,25 @@ void EditorSettingsDialog::_event_config_confirmed() { return; } - if (editing_action) { - if (current_action_event_index == -1) { - // Add new event - current_action_events.push_back(k); - } else { - // Edit existing event - current_action_events[current_action_event_index] = k; - } + if (current_event_index == -1) { + // Add new event + current_events.push_back(k); + } else { + // Edit existing event + current_events[current_event_index] = k; + } - _update_builtin_action(current_action, current_action_events); + if (is_editing_action) { + _update_builtin_action(current_edited_identifier, current_events); } else { - k = k->duplicate(); - Ref<Shortcut> current_sc = EditorSettings::get_singleton()->get_shortcut(shortcut_being_edited); - - undo_redo->create_action(TTR("Change Shortcut") + " '" + shortcut_being_edited + "'"); - undo_redo->add_do_method(current_sc.ptr(), "set_event", k); - undo_redo->add_undo_method(current_sc.ptr(), "set_event", current_sc->get_event()); - undo_redo->add_do_method(this, "_update_shortcuts"); - undo_redo->add_undo_method(this, "_update_shortcuts"); - undo_redo->add_do_method(this, "_settings_changed"); - undo_redo->add_undo_method(this, "_settings_changed"); - undo_redo->commit_action(); + _update_shortcut_events(current_edited_identifier, current_events); } } void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Array &p_events) { - Array old_input_array = EditorSettings::get_singleton()->get_builtin_action_overrides(current_action); + Array old_input_array = EditorSettings::get_singleton()->get_builtin_action_overrides(p_name); - undo_redo->create_action(TTR("Edit Built-in Action")); + undo_redo->create_action(TTR("Edit Built-in Action") + " '" + p_name + "'"); undo_redo->add_do_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, p_events); undo_redo->add_undo_method(EditorSettings::get_singleton(), "set_builtin_action_override", p_name, old_input_array); undo_redo->add_do_method(this, "_settings_changed"); @@ -231,15 +221,125 @@ void EditorSettingsDialog::_update_builtin_action(const String &p_name, const Ar _update_shortcuts(); } +void EditorSettingsDialog::_update_shortcut_events(const String &p_path, const Array &p_events) { + Ref<Shortcut> current_sc = EditorSettings::get_singleton()->get_shortcut(p_path); + + undo_redo->create_action(TTR("Edit Shortcut") + " '" + p_path + "'"); + undo_redo->add_do_method(current_sc.ptr(), "set_events", p_events); + undo_redo->add_undo_method(current_sc.ptr(), "set_events", current_sc->get_events()); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); +} + +Array EditorSettingsDialog::_event_list_to_array_helper(List<Ref<InputEvent>> &p_events) { + Array events; + + // Convert the list to an array, and only keep key events as this is for the editor. + for (List<Ref<InputEvent>>::Element *E = p_events.front(); E; E = E->next()) { + Ref<InputEventKey> k = E->get(); + if (k.is_valid()) { + events.append(E->get()); + } + } + + return events; +} + +void EditorSettingsDialog::_create_shortcut_treeitem(TreeItem *p_parent, const String &p_shortcut_identifier, const String &p_display, Array &p_events, bool p_allow_revert, bool p_is_action, bool p_is_collapsed) { + TreeItem *shortcut_item = shortcuts->create_item(p_parent); + shortcut_item->set_collapsed(p_is_collapsed); + shortcut_item->set_text(0, p_display); + + Ref<InputEvent> primary = p_events.size() > 0 ? Ref<InputEvent>(p_events[0]) : Ref<InputEvent>(); + Ref<InputEvent> secondary = p_events.size() > 1 ? Ref<InputEvent>(p_events[1]) : Ref<InputEvent>(); + + String sc_text = "None"; + if (primary.is_valid()) { + sc_text = primary->as_text(); + + if (secondary.is_valid()) { + sc_text += ", " + secondary->as_text(); + + if (p_events.size() > 2) { + sc_text += " (+" + itos(p_events.size() - 2) + ")"; + } + } + } + + shortcut_item->set_text(1, sc_text); + if (sc_text == "None") { + // Fade out unassigned shortcut labels for easier visual grepping. + shortcut_item->set_custom_color(1, shortcuts->get_theme_color("font_color", "Label") * Color(1, 1, 1, 0.5)); + } + + if (p_allow_revert) { + shortcut_item->add_button(1, shortcuts->get_theme_icon("Reload", "EditorIcons"), SHORTCUT_REVERT); + } + + shortcut_item->add_button(1, shortcuts->get_theme_icon("Add", "EditorIcons"), SHORTCUT_ADD); + shortcut_item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), SHORTCUT_ERASE); + + shortcut_item->set_meta("is_action", p_is_action); + shortcut_item->set_meta("type", "shortcut"); + shortcut_item->set_meta("shortcut_identifier", p_shortcut_identifier); + shortcut_item->set_meta("events", p_events); + + // Shortcut Input Events + for (int i = 0; i < p_events.size(); i++) { + Ref<InputEvent> ie = p_events[i]; + if (ie.is_null()) { + continue; + } + + TreeItem *event_item = shortcuts->create_item(shortcut_item); + + event_item->set_text(0, shortcut_item->get_child_count() == 1 ? "Primary" : ""); + event_item->set_text(1, ie->as_text()); + + event_item->add_button(1, shortcuts->get_theme_icon("Edit", "EditorIcons"), SHORTCUT_EDIT); + event_item->add_button(1, shortcuts->get_theme_icon("Close", "EditorIcons"), SHORTCUT_ERASE); + + event_item->set_custom_bg_color(0, shortcuts->get_theme_color("dark_color_3", "Editor")); + event_item->set_custom_bg_color(1, shortcuts->get_theme_color("dark_color_3", "Editor")); + + event_item->set_meta("is_action", p_is_action); + event_item->set_meta("type", "event"); + event_item->set_meta("event_index", i); + } +} + void EditorSettingsDialog::_update_shortcuts() { // Before clearing the tree, take note of which categories are collapsed so that this state can be maintained when the tree is repopulated. Map<String, bool> collapsed; if (shortcuts->get_root() && shortcuts->get_root()->get_first_child()) { - for (TreeItem *item = shortcuts->get_root()->get_first_child(); item; item = item->get_next()) { - collapsed[item->get_text(0)] = item->is_collapsed(); + TreeItem *ti = shortcuts->get_root()->get_first_child(); + while (ti) { + // Not all items have valid or unique text in the first column - so if it has an identifier, use that, as it should be unique. + if (ti->get_first_child() && ti->has_meta("shortcut_identifier")) { + collapsed[ti->get_meta("shortcut_identifier")] = ti->is_collapsed(); + } else { + collapsed[ti->get_text(0)] = ti->is_collapsed(); + } + + // Try go down tree + TreeItem *ti_next = ti->get_first_child(); + // Try go across tree + if (!ti_next) { + ti_next = ti->get_next(); + } + // Try go up tree, to next node + if (!ti_next) { + ti_next = ti->get_parent()->get_next(); + } + + ti = ti_next; } } + shortcuts->clear(); TreeItem *root = shortcuts->create_item(); @@ -247,7 +347,6 @@ void EditorSettingsDialog::_update_shortcuts() { // Set up section for Common/Built-in actions TreeItem *common_section = shortcuts->create_item(root); - sections["Common"] = common_section; common_section->set_text(0, TTR("Common")); common_section->set_selectable(0, false); @@ -262,7 +361,6 @@ void EditorSettingsDialog::_update_shortcuts() { OrderedHashMap<StringName, InputMap::Action> action_map = InputMap::get_singleton()->get_action_map(); for (OrderedHashMap<StringName, InputMap::Action>::Element E = action_map.front(); E; E = E.next()) { String action_name = E.key(); - InputMap::Action action = E.get(); Array events; // Need to get the list of events into an array so it can be set as metadata on the item. @@ -278,21 +376,6 @@ void EditorSettingsDialog::_update_shortcuts() { } } - bool same_as_defaults = key_default_events.size() == action.inputs.size(); // Initially this is set to just whether the arrays are equal. Later we check the events if needed. - - int count = 0; - for (List<Ref<InputEvent>>::Element *I = action.inputs.front(); I; I = I->next()) { - // Add event and event text to respective arrays. - events.push_back(I->get()); - event_strings.push_back(I->get()->as_text()); - - // Only check if the events have been the same so far - once one fails, we don't need to check any more. - if (same_as_defaults && !key_default_events[count]->is_match(I->get())) { - same_as_defaults = false; - } - count++; - } - // Join the text of the events with a delimiter so they can all be displayed in one cell. String events_display_string = event_strings.is_empty() ? "None" : String("; ").join(event_strings); @@ -300,25 +383,12 @@ void EditorSettingsDialog::_update_shortcuts() { continue; } - TreeItem *item = shortcuts->create_item(common_section); - item->set_text(0, action_name); - item->set_text(1, events_display_string); - - if (!same_as_defaults) { - item->add_button(1, shortcuts->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), 2); - } - - if (events_display_string == "None") { - // Fade out unassigned shortcut labels for easier visual grepping. - item->set_custom_color(1, shortcuts->get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.5)); - } + Array action_events = _event_list_to_array_helper(action.inputs); + Array default_events = _event_list_to_array_helper(all_default_events); + bool same_as_defaults = Shortcut::is_event_array_equal(default_events, action_events); + bool collapse = !collapsed.has(action_name) || (collapsed.has(action_name) && collapsed[action_name]); - item->add_button(1, shortcuts->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), 0); - item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), 1); - item->set_tooltip(0, action_name); - item->set_tooltip(1, events_display_string); - item->set_metadata(0, "Common"); - item->set_metadata(1, events); + _create_shortcut_treeitem(common_section, action_name, action_name, action_events, !same_as_defaults, true, collapse); } // Editor Shortcuts @@ -332,11 +402,10 @@ void EditorSettingsDialog::_update_shortcuts() { continue; } - Ref<InputEvent> original = sc->get_meta("original"); - - String section_name = E.get_slice("/", 0); + // Shortcut Section TreeItem *section; + String section_name = E.get_slice("/", 0); if (sections.has(section_name)) { section = sections[section_name]; @@ -357,33 +426,23 @@ void EditorSettingsDialog::_update_shortcuts() { sections[section_name] = section; } - // Don't match unassigned shortcuts when searching for assigned keys in search results. - // This prevents all unassigned shortcuts from appearing when searching a string like "no". - if (shortcut_filter.is_subsequence_ofi(sc->get_name()) || (sc->get_as_text() != "None" && shortcut_filter.is_subsequence_ofi(sc->get_as_text()))) { - TreeItem *item = shortcuts->create_item(section); - - item->set_text(0, sc->get_name()); - item->set_text(1, sc->get_as_text()); + // Shortcut Item - if (!sc->matches_event(original) && !(sc->get_event().is_null() && original.is_null())) { - item->add_button(1, shortcuts->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")), 2); - } + if (!shortcut_filter.is_subsequence_ofi(sc->get_name())) { + continue; + } - if (sc->get_as_text() == "None") { - // Fade out unassigned shortcut labels for easier visual grepping. - item->set_custom_color(1, shortcuts->get_theme_color(SNAME("font_color"), SNAME("Label")) * Color(1, 1, 1, 0.5)); - } + Array original = sc->get_meta("original"); + Array shortcuts_array = sc->get_events(); + bool same_as_defaults = Shortcut::is_event_array_equal(original, shortcuts_array); + bool collapse = !collapsed.has(E) || (collapsed.has(E) && collapsed[E]); - item->add_button(1, shortcuts->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), 0); - item->add_button(1, shortcuts->get_theme_icon(SNAME("Close"), SNAME("EditorIcons")), 1); - item->set_tooltip(0, E); - item->set_metadata(0, E); - } + _create_shortcut_treeitem(section, E, sc->get_name(), shortcuts_array, !same_as_defaults, false, collapse); } // remove sections with no shortcuts - for (Map<String, TreeItem *>::Element *E = sections.front(); E; E = E->next()) { - TreeItem *section = E->get(); + for (KeyValue<String, TreeItem *> &E : sections) { + TreeItem *section = E.value; if (section->get_first_child() == nullptr) { root->remove_child(section); } @@ -392,123 +451,130 @@ void EditorSettingsDialog::_update_shortcuts() { void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column, int p_idx) { TreeItem *ti = Object::cast_to<TreeItem>(p_item); - ERR_FAIL_COND(!ti); - - button_idx = p_idx; + ERR_FAIL_COND_MSG(!ti, "Object passed is not a TreeItem"); - if (ti->get_metadata(0) == "Common") { - // Editing a Built-in action, which can have multiple bindings. - editing_action = true; - current_action = ti->get_text(0); + ShortcutButton button_idx = (ShortcutButton)p_idx; - switch (button_idx) { - case SHORTCUT_REVERT: { - Array events; - List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied()[current_action]; + is_editing_action = ti->get_meta("is_action"); - // Convert the list to an array, and only keep key events as this is for the editor. - for (const Ref<InputEvent> &k : defaults) { - if (k.is_valid()) { - events.append(k); - } - } + String type = ti->get_meta("type"); - _update_builtin_action(current_action, events); - } break; - case SHORTCUT_EDIT: - case SHORTCUT_ERASE: { - // For Edit end Delete, we will show a popup which displays each event so the user can select which one to edit/delete. - current_action_events = ti->get_metadata(1); - action_popup->clear(); - - for (int i = 0; i < current_action_events.size(); i++) { - Ref<InputEvent> ie = current_action_events[i]; - action_popup->add_item(ie->as_text()); - action_popup->set_item_metadata(i, ie); - } - - if (button_idx == SHORTCUT_EDIT) { - // If editing, add a button which can be used to add an additional event. - action_popup->add_icon_item(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add")); - } + if (type == "event") { + current_edited_identifier = ti->get_parent()->get_meta("shortcut_identifier"); + current_events = ti->get_parent()->get_meta("events"); + current_event_index = ti->get_meta("event_index"); + } else { // Type is "shortcut" + current_edited_identifier = ti->get_meta("shortcut_identifier"); + current_events = ti->get_meta("events"); + current_event_index = -1; + } - action_popup->set_position(get_position() + get_mouse_position()); - action_popup->take_mouse_focus(); - action_popup->popup(); - action_popup->set_as_minsize(); - } break; - default: - break; - } - } else { - // Editing an Editor Shortcut, which can only have 1 binding. - String item = ti->get_metadata(0); - Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(item); - editing_action = false; - - switch (button_idx) { - case EditorSettingsDialog::SHORTCUT_EDIT: - shortcut_editor->popup_and_configure(sc->get_event()); - shortcut_being_edited = item; - break; - case EditorSettingsDialog::SHORTCUT_ERASE: { - if (!sc.is_valid()) { - return; //pointless, there is nothing + switch (button_idx) { + case EditorSettingsDialog::SHORTCUT_ADD: { + // Only for "shortcut" types + shortcut_editor->popup_and_configure(); + } break; + case EditorSettingsDialog::SHORTCUT_EDIT: { + // Only for "event" types + shortcut_editor->popup_and_configure(current_events[current_event_index]); + } break; + case EditorSettingsDialog::SHORTCUT_ERASE: { + if (type == "shortcut") { + if (is_editing_action) { + _update_builtin_action(current_edited_identifier, Array()); + } else { + _update_shortcut_events(current_edited_identifier, Array()); } + } else if (type == "event") { + current_events.remove(current_event_index); - undo_redo->create_action(TTR("Erase Shortcut")); - undo_redo->add_do_method(sc.ptr(), "set_event", Ref<InputEvent>()); - undo_redo->add_undo_method(sc.ptr(), "set_event", sc->get_event()); - undo_redo->add_do_method(this, "_update_shortcuts"); - undo_redo->add_undo_method(this, "_update_shortcuts"); - undo_redo->add_do_method(this, "_settings_changed"); - undo_redo->add_undo_method(this, "_settings_changed"); - undo_redo->commit_action(); - } break; - case EditorSettingsDialog::SHORTCUT_REVERT: { - if (!sc.is_valid()) { - return; //pointless, there is nothing + if (is_editing_action) { + _update_builtin_action(current_edited_identifier, current_events); + } else { + _update_shortcut_events(current_edited_identifier, current_events); } + } + } break; + case EditorSettingsDialog::SHORTCUT_REVERT: { + // Only for "shortcut" types + if (is_editing_action) { + List<Ref<InputEvent>> defaults = InputMap::get_singleton()->get_builtins_with_feature_overrides_applied()[current_edited_identifier]; + Array events = _event_list_to_array_helper(defaults); - Ref<InputEvent> original = sc->get_meta("original"); - - undo_redo->create_action(TTR("Restore Shortcut")); - undo_redo->add_do_method(sc.ptr(), "set_event", original); - undo_redo->add_undo_method(sc.ptr(), "set_event", sc->get_event()); - undo_redo->add_do_method(this, "_update_shortcuts"); - undo_redo->add_undo_method(this, "_update_shortcuts"); - undo_redo->add_do_method(this, "_settings_changed"); - undo_redo->add_undo_method(this, "_settings_changed"); - undo_redo->commit_action(); - } break; - default: - break; - } - } -} - -void EditorSettingsDialog::_builtin_action_popup_index_pressed(int p_index) { - switch (button_idx) { - case SHORTCUT_EDIT: { - if (p_index == action_popup->get_item_count() - 1) { - // Selected last item in list (Add button), therefore add new - current_action_event_index = -1; - shortcut_editor->popup_and_configure(); + _update_builtin_action(current_edited_identifier, events); } else { - // Configure existing - current_action_event_index = p_index; - shortcut_editor->popup_and_configure(action_popup->get_item_metadata(p_index)); + Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(current_edited_identifier); + Array original = sc->get_meta("original"); + _update_shortcut_events(current_edited_identifier, original); } } break; - case SHORTCUT_ERASE: { - current_action_events.remove(p_index); - _update_builtin_action(current_action, current_action_events); - } break; default: break; } } +Variant EditorSettingsDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) { + TreeItem *selected = shortcuts->get_selected(); + + // Only allow drag for events + if (!selected || !selected->has_meta("type") || selected->get_meta("type") != "event") { + return Variant(); + } + + String label_text = "Event " + itos(selected->get_meta("event_index")); + Label *label = memnew(Label(label_text)); + label->set_modulate(Color(1, 1, 1, 1.0f)); + shortcuts->set_drag_preview(label); + + shortcuts->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN); + + return Dictionary(); // No data required +} + +bool EditorSettingsDialog::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + TreeItem *selected = shortcuts->get_selected(); + TreeItem *item = shortcuts->get_item_at_position(p_point); + if (!selected || !item || item == selected || !item->has_meta("type") || item->get_meta("type") != "event") { + return false; + } + + // Don't allow moving an events in-between shortcuts. + if (selected->get_parent()->get_meta("shortcut_identifier") != item->get_parent()->get_meta("shortcut_identifier")) { + return false; + } + + return true; +} + +void EditorSettingsDialog::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + if (!can_drop_data_fw(p_point, p_data, p_from)) { + return; + } + + TreeItem *selected = shortcuts->get_selected(); + TreeItem *target = shortcuts->get_item_at_position(p_point); + + if (!target) { + return; + } + + int target_event_index = target->get_meta("event_index"); + int index_moving_from = selected->get_meta("event_index"); + + Array events = selected->get_parent()->get_meta("events"); + + Variant event_moved = events[index_moving_from]; + events.remove(index_moving_from); + events.insert(target_event_index, event_moved); + + String ident = selected->get_parent()->get_meta("shortcut_identifier"); + if (selected->get_meta("is_action")) { + _update_builtin_action(ident, events); + } else { + _update_shortcut_events(ident, events); + } +} + void EditorSettingsDialog::_tabs_tab_changed(int p_tab) { _focus_current_search_box(); } @@ -544,13 +610,13 @@ void EditorSettingsDialog::_editor_restart_close() { void EditorSettingsDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_shortcuts"), &EditorSettingsDialog::_update_shortcuts); ClassDB::bind_method(D_METHOD("_settings_changed"), &EditorSettingsDialog::_settings_changed); + + ClassDB::bind_method(D_METHOD("_get_drag_data_fw"), &EditorSettingsDialog::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("_can_drop_data_fw"), &EditorSettingsDialog::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("_drop_data_fw"), &EditorSettingsDialog::drop_data_fw); } EditorSettingsDialog::EditorSettingsDialog() { - action_popup = memnew(PopupMenu); - action_popup->connect("index_pressed", callable_mp(this, &EditorSettingsDialog::_builtin_action_popup_index_pressed)); - add_child(action_popup); - set_title(TTR("Editor Settings")); undo_redo = memnew(UndoRedo); @@ -628,6 +694,8 @@ EditorSettingsDialog::EditorSettingsDialog() { shortcuts->connect("button_pressed", callable_mp(this, &EditorSettingsDialog::_shortcut_button_pressed)); tab_shortcuts->add_child(shortcuts); + shortcuts->set_drag_forwarding(this); + // Adding event dialog shortcut_editor = memnew(InputEventConfigurationDialog); shortcut_editor->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_event_config_confirmed)); diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h index 2b6c9b3e1d..7317a014b2 100644 --- a/editor/settings_config_dialog.h +++ b/editor/settings_config_dialog.h @@ -53,29 +53,28 @@ class EditorSettingsDialog : public AcceptDialog { LineEdit *shortcut_search_box; SectionedInspector *inspector; + // Shortcuts enum ShortcutButton { + SHORTCUT_ADD, SHORTCUT_EDIT, SHORTCUT_ERASE, SHORTCUT_REVERT }; - int button_idx; - int current_action_event_index = -1; - bool editing_action = false; - String current_action; - Array current_action_events; - PopupMenu *action_popup; + Tree *shortcuts; + String shortcut_filter; + + InputEventConfigurationDialog *shortcut_editor; + + bool is_editing_action = false; + String current_edited_identifier; + Array current_events; + int current_event_index = -1; Timer *timer; UndoRedo *undo_redo; - // Shortcuts - String shortcut_filter; - Tree *shortcuts; - InputEventConfigurationDialog *shortcut_editor; - String shortcut_being_edited; - virtual void cancel_pressed() override; virtual void ok_pressed() override; @@ -89,7 +88,14 @@ class EditorSettingsDialog : public AcceptDialog { void _event_config_confirmed(); + void _create_shortcut_treeitem(TreeItem *p_parent, const String &p_shortcut_identifier, const String &p_display, Array &p_events, bool p_allow_revert, bool p_is_common, bool p_is_collapsed); + Array _event_list_to_array_helper(List<Ref<InputEvent>> &p_events); void _update_builtin_action(const String &p_name, const Array &p_events); + void _update_shortcut_events(const String &p_path, const Array &p_events); + + Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); + bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); void _tabs_tab_changed(int p_tab); void _focus_current_search_box(); diff --git a/main/main.cpp b/main/main.cpp index d512c41e7a..5a2a088494 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -407,6 +407,7 @@ Error Main::test_setup() { GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2); translation_server = memnew(TranslationServer); + tsman = memnew(TextServerManager); register_core_extensions(); @@ -440,6 +441,9 @@ Error Main::test_setup() { register_module_types(); register_driver_types(); + ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE); + TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(0)); + ClassDB::set_current_api(ClassDB::API_NONE); _start_success = true; @@ -459,6 +463,7 @@ void Main::test_cleanup() { #ifdef TOOLS_ENABLED EditorNode::unregister_editor_types(); #endif + unregister_module_types(); unregister_platform_apis(); unregister_scene_types(); @@ -469,6 +474,9 @@ void Main::test_cleanup() { if (translation_server) { memdelete(translation_server); } + if (tsman) { + memdelete(tsman); + } if (globals) { memdelete(globals); } @@ -1461,6 +1469,8 @@ error: } Error Main::setup2(Thread::ID p_main_tid_override) { + tsman = memnew(TextServerManager); + preregister_module_types(); preregister_server_types(); @@ -1479,64 +1489,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) { } #endif - /* Determine text driver */ - - if (text_driver == "") { - text_driver = GLOBAL_GET("internationalization/rendering/text_driver"); - } - - if (text_driver != "") { - /* Load user selected text server. */ - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - if (text_driver == TextServerManager::get_interface_name(i)) { - text_driver_idx = i; - break; - } - } - } - - if (text_driver_idx < 0) { - /* If not selected, use one with the most features available. */ - int max_features = 0; - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - uint32_t ftrs = TextServerManager::get_interface_features(i); - int features = 0; - while (ftrs) { - features += ftrs & 1; - ftrs >>= 1; - } - if (features >= max_features) { - max_features = features; - text_driver_idx = i; - } - } - } - print_verbose("Using \"" + TextServerManager::get_interface_name(text_driver_idx) + "\" text server..."); - - /* Initialize Text Server */ - - { - tsman = memnew(TextServerManager); - Error err; - TextServer *text_server = TextServerManager::initialize(text_driver_idx, err); - if (err != OK || text_server == nullptr) { - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - if (i == text_driver_idx) { - continue; //don't try the same twice - } - text_server = TextServerManager::initialize(i, err); - if (err == OK && text_server != nullptr) { - break; - } - } - } - - if (err != OK || text_server == nullptr) { - ERR_PRINT("Unable to create TextServer, all text drivers failed."); - return err; - } - } - /* Initialize Input */ input = memnew(Input); @@ -1721,8 +1673,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) { } #ifdef TOOLS_ENABLED - Ref<Image> icon = memnew(Image(app_icon_png)); - DisplayServer::get_singleton()->set_icon(icon); + if (OS::get_singleton()->get_bundle_icon_path().is_empty()) { + Ref<Image> icon = memnew(Image(app_icon_png)); + DisplayServer::get_singleton()->set_icon(icon); + } #endif } @@ -1779,6 +1733,57 @@ Error Main::setup2(Thread::ID p_main_tid_override) { ResourceLoader::load_path_remaps(); + MAIN_PRINT("Main: Load TextServer"); + + /* Enum text drivers */ + GLOBAL_DEF("internationalization/rendering/text_driver", ""); + String text_driver_options; + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + if (i > 0) { + text_driver_options += ","; + } + text_driver_options += TextServerManager::get_singleton()->get_interface(i)->get_name(); + } + ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options)); + + /* Determine text driver */ + if (text_driver == "") { + text_driver = GLOBAL_GET("internationalization/rendering/text_driver"); + } + + if (text_driver != "") { + /* Load user selected text server. */ + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + if (TextServerManager::get_singleton()->get_interface(i)->get_name() == text_driver) { + text_driver_idx = i; + break; + } + } + } + + if (text_driver_idx < 0) { + /* If not selected, use one with the most features available. */ + int max_features = 0; + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + uint32_t features = TextServerManager::get_singleton()->get_interface(i)->get_features(); + int feature_number = 0; + while (features) { + feature_number += features & 1; + features >>= 1; + } + if (feature_number >= max_features) { + max_features = feature_number; + text_driver_idx = i; + } + } + } + if (text_driver_idx >= 0) { + TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(text_driver_idx)); + } else { + ERR_PRINT("TextServer: Unable to create TextServer interface."); + return ERR_CANT_CREATE; + } + MAIN_PRINT("Main: Load Scene Types"); register_scene_types(); @@ -1791,7 +1796,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { #endif - MAIN_PRINT("Main: Load Modules, Physics, Drivers, Scripts"); + MAIN_PRINT("Main: Load Modules"); register_platform_apis(); register_module_types(); @@ -1815,6 +1820,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) { camera_server = CameraServer::create(); + MAIN_PRINT("Main: Load Physics, Drivers, Scripts"); + initialize_physics(); initialize_navigation_server(); register_server_singletons(); @@ -2440,7 +2447,7 @@ bool Main::start() { #endif } - if (!hasicon) { + if (!hasicon && OS::get_singleton()->get_bundle_icon_path().is_empty()) { Ref<Image> icon = memnew(Image(app_icon_png)); DisplayServer::get_singleton()->set_icon(icon); } @@ -2726,10 +2733,6 @@ void Main::cleanup(bool p_force) { finalize_navigation_server(); finalize_display(); - if (tsman) { - memdelete(tsman); - } - if (input) { memdelete(input); } @@ -2752,6 +2755,9 @@ void Main::cleanup(bool p_force) { if (translation_server) { memdelete(translation_server); } + if (tsman) { + memdelete(tsman); + } if (globals) { memdelete(globals); } diff --git a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns b/misc/dist/osx_tools.app/Contents/Resources/Godot.icns Binary files differindex be9254630c..61697976c6 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns +++ b/misc/dist/osx_tools.app/Contents/Resources/Godot.icns diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub index ba57de303e..09509abc44 100644 --- a/modules/bullet/SCsub +++ b/modules/bullet/SCsub @@ -10,7 +10,7 @@ env_bullet = env_modules.Clone() thirdparty_obj = [] if env["builtin_bullet"]: - # Build only version 2 for now (as of 2.89) + # Build only "Bullet2" API (not "Bullet3" folders). # Sync file list with relevant upstream CMakeLists.txt for each folder. if env["float"] == "64": env.Append(CPPDEFINES=["BT_USE_DOUBLE_PRECISION=1"]) @@ -189,6 +189,7 @@ if env["builtin_bullet"]: "LinearMath/btGeometryUtil.cpp", "LinearMath/btPolarDecomposition.cpp", "LinearMath/btQuickprof.cpp", + "LinearMath/btReducedVector.cpp", "LinearMath/btSerializer.cpp", "LinearMath/btSerializer64.cpp", "LinearMath/btThreads.cpp", @@ -200,15 +201,11 @@ if env["builtin_bullet"]: thirdparty_sources = [thirdparty_dir + file for file in bullet2_src] - # Treat Bullet headers as system headers to avoid raising warnings. Not supported on MSVC. - if not env.msvc: - env_bullet.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path]) - else: - env_bullet.Prepend(CPPPATH=[thirdparty_dir]) + env_bullet.Prepend(CPPPATH=[thirdparty_dir]) if env["target"] == "debug" or env["target"] == "release_debug": env_bullet.Append(CPPDEFINES=["DEBUG"]) - env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD"]) + env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD", "BT_THREADSAFE"]) env_thirdparty = env_bullet.Clone() env_thirdparty.disable_warnings() diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index ed05e51e53..bb2db49c87 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -124,7 +124,7 @@ RID BulletPhysicsServer3D::shape_create(ShapeType p_shape) { } void BulletPhysicsServer3D::shape_set_data(RID p_shape, const Variant &p_data) { - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); shape->set_data(p_data); } @@ -134,25 +134,25 @@ void BulletPhysicsServer3D::shape_set_custom_solver_bias(RID p_shape, real_t p_b } PhysicsServer3D::ShapeType BulletPhysicsServer3D::shape_get_type(RID p_shape) const { - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, PhysicsServer3D::SHAPE_CUSTOM); return shape->get_type(); } Variant BulletPhysicsServer3D::shape_get_data(RID p_shape) const { - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, Variant()); return shape->get_data(); } void BulletPhysicsServer3D::shape_set_margin(RID p_shape, real_t p_margin) { - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); shape->set_margin(p_margin); } real_t BulletPhysicsServer3D::shape_get_margin(RID p_shape) const { - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0.0); return shape->get_margin(); } @@ -168,7 +168,7 @@ RID BulletPhysicsServer3D::space_create() { } void BulletPhysicsServer3D::space_set_active(RID p_space, bool p_active) { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); if (space_is_active(p_space) == p_active) { @@ -185,47 +185,47 @@ void BulletPhysicsServer3D::space_set_active(RID p_space, bool p_active) { } bool BulletPhysicsServer3D::space_is_active(RID p_space) const { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, false); return -1 != active_spaces.find(space); } void BulletPhysicsServer3D::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); space->set_param(p_param, p_value); } real_t BulletPhysicsServer3D::space_get_param(RID p_space, SpaceParameter p_param) const { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_param(p_param); } PhysicsDirectSpaceState3D *BulletPhysicsServer3D::space_get_direct_state(RID p_space) { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, nullptr); return space->get_direct_state(); } void BulletPhysicsServer3D::space_set_debug_contacts(RID p_space, int p_max_contacts) { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); space->set_debug_contacts(p_max_contacts); } Vector<Vector3> BulletPhysicsServer3D::space_get_contacts(RID p_space) const { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, Vector<Vector3>()); return space->get_debug_contacts(); } int BulletPhysicsServer3D::space_get_contact_count(RID p_space) const { - SpaceBullet *space = space_owner.getornull(p_space); + SpaceBullet *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_debug_contact_count(); @@ -239,91 +239,91 @@ RID BulletPhysicsServer3D::area_create() { } void BulletPhysicsServer3D::area_set_space(RID p_area, RID p_space) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); SpaceBullet *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } area->set_space(space); } RID BulletPhysicsServer3D::area_get_space(RID p_area) const { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); return area->get_space()->get_self(); } void BulletPhysicsServer3D::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_spOv_mode(p_mode); } PhysicsServer3D::AreaSpaceOverrideMode BulletPhysicsServer3D::area_get_space_override_mode(RID p_area) const { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED); return area->get_spOv_mode(); } void BulletPhysicsServer3D::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); area->add_shape(shape, p_transform, p_disabled); } void BulletPhysicsServer3D::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); area->set_shape(p_shape_idx, shape); } void BulletPhysicsServer3D::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_shape_transform(p_shape_idx, p_transform); } int BulletPhysicsServer3D::area_get_shape_count(RID p_area) const { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, 0); return area->get_shape_count(); } RID BulletPhysicsServer3D::area_get_shape(RID p_area, int p_shape_idx) const { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, RID()); return area->get_shape(p_shape_idx)->get_self(); } Transform3D BulletPhysicsServer3D::area_get_shape_transform(RID p_area, int p_shape_idx) const { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Transform3D()); return area->get_shape_transform(p_shape_idx); } void BulletPhysicsServer3D::area_remove_shape(RID p_area, int p_shape_idx) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); return area->remove_shape_full(p_shape_idx); } void BulletPhysicsServer3D::area_clear_shapes(RID p_area) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); for (int i = area->get_shape_count(); 0 < i; --i) { @@ -332,7 +332,7 @@ void BulletPhysicsServer3D::area_clear_shapes(RID p_area) { } void BulletPhysicsServer3D::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_shape_disabled(p_shape_idx, p_disabled); @@ -342,7 +342,7 @@ void BulletPhysicsServer3D::area_attach_object_instance_id(RID p_area, ObjectID if (space_owner.owns(p_area)) { return; } - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_instance_id(p_id); } @@ -351,19 +351,19 @@ ObjectID BulletPhysicsServer3D::area_get_object_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { return ObjectID(); } - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, ObjectID()); return area->get_instance_id(); } void BulletPhysicsServer3D::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { if (space_owner.owns(p_area)) { - SpaceBullet *space = space_owner.getornull(p_area); + SpaceBullet *space = space_owner.get_or_null(p_area); if (space) { space->set_param(p_param, p_value); } } else { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_param(p_param, p_value); @@ -372,10 +372,10 @@ void BulletPhysicsServer3D::area_set_param(RID p_area, AreaParameter p_param, co Variant BulletPhysicsServer3D::area_get_param(RID p_area, AreaParameter p_param) const { if (space_owner.owns(p_area)) { - SpaceBullet *space = space_owner.getornull(p_area); + SpaceBullet *space = space_owner.get_or_null(p_area); return space->get_param(p_param); } else { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Variant()); return area->get_param(p_param); @@ -383,52 +383,52 @@ Variant BulletPhysicsServer3D::area_get_param(RID p_area, AreaParameter p_param) } void BulletPhysicsServer3D::area_set_transform(RID p_area, const Transform3D &p_transform) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); } Transform3D BulletPhysicsServer3D::area_get_transform(RID p_area) const { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Transform3D()); return area->get_transform(); } void BulletPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_collision_mask(p_mask); } void BulletPhysicsServer3D::area_set_collision_layer(RID p_area, uint32_t p_layer) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_collision_layer(p_layer); } void BulletPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_monitorable(p_monitorable); } void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); } void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); } void BulletPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { - AreaBullet *area = area_owner.getornull(p_area); + AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_ray_pickable(p_enable); } @@ -445,12 +445,12 @@ RID BulletPhysicsServer3D::body_create(BodyMode p_mode, bool p_init_sleeping) { } void BulletPhysicsServer3D::body_set_space(RID p_body, RID p_space) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); SpaceBullet *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } @@ -462,7 +462,7 @@ void BulletPhysicsServer3D::body_set_space(RID p_body, RID p_space) { } RID BulletPhysicsServer3D::body_get_space(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, RID()); SpaceBullet *space = body->get_space(); @@ -473,52 +473,52 @@ RID BulletPhysicsServer3D::body_get_space(RID p_body) const { } void BulletPhysicsServer3D::body_set_mode(RID p_body, PhysicsServer3D::BodyMode p_mode) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_mode(p_mode); } PhysicsServer3D::BodyMode BulletPhysicsServer3D::body_get_mode(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); return body->get_mode(); } void BulletPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); body->add_shape(shape, p_transform, p_disabled); } void BulletPhysicsServer3D::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - ShapeBullet *shape = shape_owner.getornull(p_shape); + ShapeBullet *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); body->set_shape(p_shape_idx, shape); } void BulletPhysicsServer3D::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_shape_transform(p_shape_idx, p_transform); } int BulletPhysicsServer3D::body_get_shape_count(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_shape_count(); } RID BulletPhysicsServer3D::body_get_shape(RID p_body, int p_shape_idx) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, RID()); ShapeBullet *shape = body->get_shape(p_shape_idx); @@ -528,27 +528,27 @@ RID BulletPhysicsServer3D::body_get_shape(RID p_body, int p_shape_idx) const { } Transform3D BulletPhysicsServer3D::body_get_shape_transform(RID p_body, int p_shape_idx) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Transform3D()); return body->get_shape_transform(p_shape_idx); } void BulletPhysicsServer3D::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_shape_disabled(p_shape_idx, p_disabled); } void BulletPhysicsServer3D::body_remove_shape(RID p_body, int p_shape_idx) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->remove_shape_full(p_shape_idx); } void BulletPhysicsServer3D::body_clear_shapes(RID p_body) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->remove_all_shapes(); @@ -569,42 +569,42 @@ ObjectID BulletPhysicsServer3D::body_get_object_instance_id(RID p_body) const { } void BulletPhysicsServer3D::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_continuous_collision_detection(p_enable); } bool BulletPhysicsServer3D::body_is_continuous_collision_detection_enabled(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); return body->is_continuous_collision_detection_enabled(); } void BulletPhysicsServer3D::body_set_collision_layer(RID p_body, uint32_t p_layer) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); } uint32_t BulletPhysicsServer3D::body_get_collision_layer(RID p_body) const { - const RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + const RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_layer(); } void BulletPhysicsServer3D::body_set_collision_mask(RID p_body, uint32_t p_mask) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); } uint32_t BulletPhysicsServer3D::body_get_collision_mask(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_mask(); @@ -620,21 +620,21 @@ uint32_t BulletPhysicsServer3D::body_get_user_flags(RID p_body) const { } void BulletPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_param(p_param, p_value); } real_t BulletPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_param(p_param); } void BulletPhysicsServer3D::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); if (body->get_kinematic_utilities()) { @@ -643,7 +643,7 @@ void BulletPhysicsServer3D::body_set_kinematic_safe_margin(RID p_body, real_t p_ } real_t BulletPhysicsServer3D::body_get_kinematic_safe_margin(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); if (body->get_kinematic_utilities()) { @@ -654,90 +654,90 @@ real_t BulletPhysicsServer3D::body_get_kinematic_safe_margin(RID p_body) const { } void BulletPhysicsServer3D::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_state(p_state, p_variant); } Variant BulletPhysicsServer3D::body_get_state(RID p_body, BodyState p_state) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Variant()); return body->get_state(p_state); } void BulletPhysicsServer3D::body_set_applied_force(RID p_body, const Vector3 &p_force) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_applied_force(p_force); } Vector3 BulletPhysicsServer3D::body_get_applied_force(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Vector3()); return body->get_applied_force(); } void BulletPhysicsServer3D::body_set_applied_torque(RID p_body, const Vector3 &p_torque) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_applied_torque(p_torque); } Vector3 BulletPhysicsServer3D::body_get_applied_torque(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Vector3()); return body->get_applied_torque(); } void BulletPhysicsServer3D::body_add_central_force(RID p_body, const Vector3 &p_force) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->apply_central_force(p_force); } void BulletPhysicsServer3D::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->apply_force(p_force, p_position); } void BulletPhysicsServer3D::body_add_torque(RID p_body, const Vector3 &p_torque) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->apply_torque(p_torque); } void BulletPhysicsServer3D::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->apply_central_impulse(p_impulse); } void BulletPhysicsServer3D::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->apply_impulse(p_impulse, p_position); } void BulletPhysicsServer3D::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->apply_torque_impulse(p_impulse); } void BulletPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); Vector3 v = body->get_linear_velocity(); @@ -748,39 +748,39 @@ void BulletPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_ } void BulletPhysicsServer3D::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_axis_lock(p_axis, p_lock); } bool BulletPhysicsServer3D::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { - const RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + const RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->is_axis_locked(p_axis); } void BulletPhysicsServer3D::body_add_collision_exception(RID p_body, RID p_body_b) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - RigidBodyBullet *other_body = rigid_body_owner.getornull(p_body_b); + RigidBodyBullet *other_body = rigid_body_owner.get_or_null(p_body_b); ERR_FAIL_COND(!other_body); body->add_collision_exception(other_body); } void BulletPhysicsServer3D::body_remove_collision_exception(RID p_body, RID p_body_b) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - RigidBodyBullet *other_body = rigid_body_owner.getornull(p_body_b); + RigidBodyBullet *other_body = rigid_body_owner.get_or_null(p_body_b); ERR_FAIL_COND(!other_body); body->remove_collision_exception(other_body); } void BulletPhysicsServer3D::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); for (int i = 0; i < body->get_exceptions().size(); i++) { p_exceptions->push_back(body->get_exceptions()[i]); @@ -788,14 +788,14 @@ void BulletPhysicsServer3D::body_get_collision_exceptions(RID p_body, List<RID> } void BulletPhysicsServer3D::body_set_max_contacts_reported(RID p_body, int p_contacts) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_max_collisions_detection(p_contacts); } int BulletPhysicsServer3D::body_get_max_contacts_reported(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_max_collisions_detection(); @@ -811,39 +811,39 @@ real_t BulletPhysicsServer3D::body_get_contacts_reported_depth_threshold(RID p_b } void BulletPhysicsServer3D::body_set_omit_force_integration(RID p_body, bool p_omit) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_omit_forces_integration(p_omit); } bool BulletPhysicsServer3D::body_is_omitting_force_integration(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); return body->get_omit_forces_integration(); } void BulletPhysicsServer3D::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_force_integration_callback(p_callable, p_udata); } void BulletPhysicsServer3D::body_set_ray_pickable(RID p_body, bool p_enable) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_ray_pickable(p_enable); } PhysicsDirectBodyState3D *BulletPhysicsServer3D::body_get_direct_state(RID p_body) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, nullptr); return BulletPhysicsDirectBodyState3D::get_singleton(body); } bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes, const Set<RID> &p_exclude) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -851,7 +851,7 @@ bool BulletPhysicsServer3D::body_test_motion(RID p_body, const Transform3D &p_fr } int BulletPhysicsServer3D::body_test_ray_separation(RID p_body, const Transform3D &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, real_t p_margin) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_body); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); ERR_FAIL_COND_V(!body->get_space(), 0); @@ -869,19 +869,19 @@ RID BulletPhysicsServer3D::soft_body_create(bool p_init_sleeping) { } void BulletPhysicsServer3D::soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->update_rendering_server(p_rendering_server_handler); } void BulletPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); SpaceBullet *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } @@ -893,7 +893,7 @@ void BulletPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) { } RID BulletPhysicsServer3D::soft_body_get_space(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, RID()); SpaceBullet *space = body->get_space(); @@ -903,8 +903,8 @@ RID BulletPhysicsServer3D::soft_body_get_space(RID p_body) const { return space->get_self(); } -void BulletPhysicsServer3D::soft_body_set_mesh(RID p_body, const REF &p_mesh) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); +void BulletPhysicsServer3D::soft_body_set_mesh(RID p_body, RID p_mesh) { + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_soft_mesh(p_mesh); @@ -918,40 +918,40 @@ AABB BulletPhysicsServer::soft_body_get_bounds(RID p_body) const { } void BulletPhysicsServer3D::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); } uint32_t BulletPhysicsServer3D::soft_body_get_collision_layer(RID p_body) const { - const SoftBodyBullet *body = soft_body_owner.getornull(p_body); + const SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_layer(); } void BulletPhysicsServer3D::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); } uint32_t BulletPhysicsServer3D::soft_body_get_collision_mask(RID p_body) const { - const SoftBodyBullet *body = soft_body_owner.getornull(p_body); + const SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_mask(); } void BulletPhysicsServer3D::soft_body_add_collision_exception(RID p_body, RID p_body_b) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - CollisionObjectBullet *other_body = rigid_body_owner.getornull(p_body_b); + CollisionObjectBullet *other_body = rigid_body_owner.get_or_null(p_body_b); if (!other_body) { - other_body = soft_body_owner.getornull(p_body_b); + other_body = soft_body_owner.get_or_null(p_body_b); } ERR_FAIL_COND(!other_body); @@ -959,12 +959,12 @@ void BulletPhysicsServer3D::soft_body_add_collision_exception(RID p_body, RID p_ } void BulletPhysicsServer3D::soft_body_remove_collision_exception(RID p_body, RID p_body_b) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - CollisionObjectBullet *other_body = rigid_body_owner.getornull(p_body_b); + CollisionObjectBullet *other_body = rigid_body_owner.get_or_null(p_body_b); if (!other_body) { - other_body = soft_body_owner.getornull(p_body_b); + other_body = soft_body_owner.get_or_null(p_body_b); } ERR_FAIL_COND(!other_body); @@ -972,7 +972,7 @@ void BulletPhysicsServer3D::soft_body_remove_collision_exception(RID p_body, RID } void BulletPhysicsServer3D::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); for (int i = 0; i < body->get_exceptions().size(); i++) { p_exceptions->push_back(body->get_exceptions()[i]); @@ -991,98 +991,98 @@ Variant BulletPhysicsServer3D::soft_body_get_state(RID p_body, BodyState p_state } void BulletPhysicsServer3D::soft_body_set_transform(RID p_body, const Transform3D &p_transform) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_soft_transform(p_transform); } void BulletPhysicsServer3D::soft_body_set_ray_pickable(RID p_body, bool p_enable) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_ray_pickable(p_enable); } void BulletPhysicsServer3D::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_simulation_precision(p_simulation_precision); } int BulletPhysicsServer3D::soft_body_get_simulation_precision(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_simulation_precision(); } void BulletPhysicsServer3D::soft_body_set_total_mass(RID p_body, real_t p_total_mass) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_total_mass(p_total_mass); } real_t BulletPhysicsServer3D::soft_body_get_total_mass(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_total_mass(); } void BulletPhysicsServer3D::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_linear_stiffness(p_stiffness); } real_t BulletPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_linear_stiffness(); } void BulletPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_pressure_coefficient(p_pressure_coefficient); } real_t BulletPhysicsServer3D::soft_body_get_pressure_coefficient(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_pressure_coefficient(); } void BulletPhysicsServer3D::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_damping_coefficient(p_damping_coefficient); } real_t BulletPhysicsServer3D::soft_body_get_damping_coefficient(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_damping_coefficient(); } void BulletPhysicsServer3D::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_drag_coefficient(p_drag_coefficient); } real_t BulletPhysicsServer3D::soft_body_get_drag_coefficient(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_drag_coefficient(); } void BulletPhysicsServer3D::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_node_position(p_point_index, p_global_position); } Vector3 BulletPhysicsServer3D::soft_body_get_point_global_position(RID p_body, int p_point_index) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Vector3(0., 0., 0.)); Vector3 pos; body->get_node_position(p_point_index, pos); @@ -1090,25 +1090,25 @@ Vector3 BulletPhysicsServer3D::soft_body_get_point_global_position(RID p_body, i } void BulletPhysicsServer3D::soft_body_remove_all_pinned_points(RID p_body) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->reset_all_node_mass(); } void BulletPhysicsServer3D::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_node_mass(p_point_index, p_pin ? 0 : 1); } bool BulletPhysicsServer3D::soft_body_is_point_pinned(RID p_body, int p_point_index) const { - SoftBodyBullet *body = soft_body_owner.getornull(p_body); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_node_mass(p_point_index); } PhysicsServer3D::JointType BulletPhysicsServer3D::joint_get_type(RID p_joint) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, JOINT_PIN); return joint->get_type(); } @@ -1123,28 +1123,28 @@ int BulletPhysicsServer3D::joint_get_solver_priority(RID p_joint) const { } void BulletPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); joint->disable_collisions_between_bodies(p_disable); } bool BulletPhysicsServer3D::joint_is_disabled_collisions_between_bodies(RID p_joint) const { - JointBullet *joint(joint_owner.getornull(p_joint)); + JointBullet *joint(joint_owner.get_or_null(p_joint)); ERR_FAIL_COND_V(!joint, false); return joint->is_disabled_collisions_between_bodies(); } RID BulletPhysicsServer3D::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { - RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = nullptr; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); + body_B = rigid_body_owner.get_or_null(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1158,7 +1158,7 @@ RID BulletPhysicsServer3D::joint_create_pin(RID p_body_A, const Vector3 &p_local } void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1166,7 +1166,7 @@ void BulletPhysicsServer3D::pin_joint_set_param(RID p_joint, PinJointParam p_par } real_t BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1174,7 +1174,7 @@ real_t BulletPhysicsServer3D::pin_joint_get_param(RID p_joint, PinJointParam p_p } void BulletPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1182,7 +1182,7 @@ void BulletPhysicsServer3D::pin_joint_set_local_a(RID p_joint, const Vector3 &p_ } Vector3 BulletPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1190,7 +1190,7 @@ Vector3 BulletPhysicsServer3D::pin_joint_get_local_a(RID p_joint) const { } void BulletPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1198,7 +1198,7 @@ void BulletPhysicsServer3D::pin_joint_set_local_b(RID p_joint, const Vector3 &p_ } Vector3 BulletPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1206,13 +1206,13 @@ Vector3 BulletPhysicsServer3D::pin_joint_get_local_b(RID p_joint) const { } RID BulletPhysicsServer3D::joint_create_hinge(RID p_body_A, const Transform3D &p_hinge_A, RID p_body_B, const Transform3D &p_hinge_B) { - RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = nullptr; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); + body_B = rigid_body_owner.get_or_null(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1226,13 +1226,13 @@ RID BulletPhysicsServer3D::joint_create_hinge(RID p_body_A, const Transform3D &p } RID BulletPhysicsServer3D::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { - RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = nullptr; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); + body_B = rigid_body_owner.get_or_null(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1246,7 +1246,7 @@ RID BulletPhysicsServer3D::joint_create_hinge_simple(RID p_body_A, const Vector3 } void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1254,7 +1254,7 @@ void BulletPhysicsServer3D::hinge_joint_set_param(RID p_joint, HingeJointParam p } real_t BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1262,7 +1262,7 @@ real_t BulletPhysicsServer3D::hinge_joint_get_param(RID p_joint, HingeJointParam } void BulletPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1270,7 +1270,7 @@ void BulletPhysicsServer3D::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_f } bool BulletPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1278,13 +1278,13 @@ bool BulletPhysicsServer3D::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_f } RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = nullptr; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); + body_B = rigid_body_owner.get_or_null(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1298,7 +1298,7 @@ RID BulletPhysicsServer3D::joint_create_slider(RID p_body_A, const Transform3D & } void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint); @@ -1306,7 +1306,7 @@ void BulletPhysicsServer3D::slider_joint_set_param(RID p_joint, SliderJointParam } real_t BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_SLIDER, 0); SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint); @@ -1314,13 +1314,13 @@ real_t BulletPhysicsServer3D::slider_joint_get_param(RID p_joint, SliderJointPar } RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = nullptr; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); + body_B = rigid_body_owner.get_or_null(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1332,7 +1332,7 @@ RID BulletPhysicsServer3D::joint_create_cone_twist(RID p_body_A, const Transform } void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint); @@ -1340,7 +1340,7 @@ void BulletPhysicsServer3D::cone_twist_joint_set_param(RID p_joint, ConeTwistJoi } real_t BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0.); ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0.); ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint); @@ -1348,13 +1348,13 @@ real_t BulletPhysicsServer3D::cone_twist_joint_get_param(RID p_joint, ConeTwistJ } RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.get_or_null(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = nullptr; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.getornull(p_body_B); + body_B = rigid_body_owner.get_or_null(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1368,7 +1368,7 @@ RID BulletPhysicsServer3D::joint_create_generic_6dof(RID p_body_A, const Transfo } void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1376,7 +1376,7 @@ void BulletPhysicsServer3D::generic_6dof_joint_set_param(RID p_joint, Vector3::A } real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1384,7 +1384,7 @@ real_t BulletPhysicsServer3D::generic_6dof_joint_get_param(RID p_joint, Vector3: } void BulletPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1392,7 +1392,7 @@ void BulletPhysicsServer3D::generic_6dof_joint_set_flag(RID p_joint, Vector3::Ax } bool BulletPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { - JointBullet *joint = joint_owner.getornull(p_joint); + JointBullet *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1401,17 +1401,17 @@ bool BulletPhysicsServer3D::generic_6dof_joint_get_flag(RID p_joint, Vector3::Ax void BulletPhysicsServer3D::free(RID p_rid) { if (shape_owner.owns(p_rid)) { - ShapeBullet *shape = shape_owner.getornull(p_rid); + ShapeBullet *shape = shape_owner.get_or_null(p_rid); // Notify the shape is configured - for (Map<ShapeOwnerBullet *, int>::Element *element = shape->get_owners().front(); element; element = element->next()) { - static_cast<ShapeOwnerBullet *>(element->key())->remove_shape_full(shape); + for (const KeyValue<ShapeOwnerBullet *, int> &element : shape->get_owners()) { + static_cast<ShapeOwnerBullet *>(element.key)->remove_shape_full(shape); } shape_owner.free(p_rid); bulletdelete(shape); } else if (rigid_body_owner.owns(p_rid)) { - RigidBodyBullet *body = rigid_body_owner.getornull(p_rid); + RigidBodyBullet *body = rigid_body_owner.get_or_null(p_rid); body->set_space(nullptr); @@ -1421,7 +1421,7 @@ void BulletPhysicsServer3D::free(RID p_rid) { bulletdelete(body); } else if (soft_body_owner.owns(p_rid)) { - SoftBodyBullet *body = soft_body_owner.getornull(p_rid); + SoftBodyBullet *body = soft_body_owner.get_or_null(p_rid); body->set_space(nullptr); @@ -1429,7 +1429,7 @@ void BulletPhysicsServer3D::free(RID p_rid) { bulletdelete(body); } else if (area_owner.owns(p_rid)) { - AreaBullet *area = area_owner.getornull(p_rid); + AreaBullet *area = area_owner.get_or_null(p_rid); area->set_space(nullptr); @@ -1439,13 +1439,13 @@ void BulletPhysicsServer3D::free(RID p_rid) { bulletdelete(area); } else if (joint_owner.owns(p_rid)) { - JointBullet *joint = joint_owner.getornull(p_rid); + JointBullet *joint = joint_owner.get_or_null(p_rid); joint->destroy_internal_constraint(); joint_owner.free(p_rid); bulletdelete(joint); } else if (space_owner.owns(p_rid)) { - SpaceBullet *space = space_owner.getornull(p_rid); + SpaceBullet *space = space_owner.get_or_null(p_rid); space->remove_all_collision_objects(); @@ -1493,38 +1493,38 @@ int BulletPhysicsServer3D::get_process_info(ProcessInfo p_info) { SpaceBullet *BulletPhysicsServer3D::get_space(RID p_rid) const { ERR_FAIL_COND_V_MSG(space_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); - return space_owner.getornull(p_rid); + return space_owner.get_or_null(p_rid); } ShapeBullet *BulletPhysicsServer3D::get_shape(RID p_rid) const { ERR_FAIL_COND_V_MSG(shape_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); - return shape_owner.getornull(p_rid); + return shape_owner.get_or_null(p_rid); } CollisionObjectBullet *BulletPhysicsServer3D::get_collision_object(RID p_object) const { if (rigid_body_owner.owns(p_object)) { - return rigid_body_owner.getornull(p_object); + return rigid_body_owner.get_or_null(p_object); } if (area_owner.owns(p_object)) { - return area_owner.getornull(p_object); + return area_owner.get_or_null(p_object); } if (soft_body_owner.owns(p_object)) { - return soft_body_owner.getornull(p_object); + return soft_body_owner.get_or_null(p_object); } ERR_FAIL_V_MSG(nullptr, "The RID is no valid."); } RigidCollisionObjectBullet *BulletPhysicsServer3D::get_rigid_collision_object(RID p_object) const { if (rigid_body_owner.owns(p_object)) { - return rigid_body_owner.getornull(p_object); + return rigid_body_owner.get_or_null(p_object); } if (area_owner.owns(p_object)) { - return area_owner.getornull(p_object); + return area_owner.get_or_null(p_object); } ERR_FAIL_V_MSG(nullptr, "The RID is no valid."); } JointBullet *BulletPhysicsServer3D::get_joint(RID p_rid) const { ERR_FAIL_COND_V_MSG(joint_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); - return joint_owner.getornull(p_rid); + return joint_owner.get_or_null(p_rid); } diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 7f0934e679..7c146de0c3 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -265,7 +265,7 @@ public: virtual void soft_body_set_space(RID p_body, RID p_space) override; virtual RID soft_body_get_space(RID p_body) const override; - virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) override; + virtual void soft_body_set_mesh(RID p_body, RID p_mesh) override; virtual AABB soft_body_get_bounds(RID p_body) const override; diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 88ffb9ec67..ec039ba842 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -63,8 +63,8 @@ btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const { } void ShapeBullet::notifyShapeChanged() { - for (Map<ShapeOwnerBullet *, int>::Element *E = owners.front(); E; E = E->next()) { - ShapeOwnerBullet *owner = static_cast<ShapeOwnerBullet *>(E->key()); + for (const KeyValue<ShapeOwnerBullet *, int> &E : owners) { + ShapeOwnerBullet *owner = static_cast<ShapeOwnerBullet *>(E.key); owner->shape_changed(owner->find_shape(this)); } } diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index bbbb0e7851..94b7e0ce38 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -32,9 +32,10 @@ #include "bullet_types_converter.h" #include "bullet_utilities.h" -#include "scene/3d/soft_body_3d.h" #include "space_bullet.h" +#include "servers/rendering_server.h" + SoftBodyBullet::SoftBodyBullet() : CollisionObjectBullet(CollisionObjectBullet::TYPE_SOFT_BODY) {} @@ -105,24 +106,26 @@ void SoftBodyBullet::update_rendering_server(RenderingServerHandler *p_rendering p_rendering_server_handler->set_aabb(aabb); } -void SoftBodyBullet::set_soft_mesh(const Ref<Mesh> &p_mesh) { - if (p_mesh.is_null()) { - soft_mesh.unref(); - } else { - soft_mesh = p_mesh; - } +void SoftBodyBullet::set_soft_mesh(RID p_mesh) { + destroy_soft_body(); + + soft_mesh = p_mesh; if (soft_mesh.is_null()) { - destroy_soft_body(); return; } - Array arrays = soft_mesh->surface_get_arrays(0); - ERR_FAIL_COND(!(soft_mesh->surface_get_format(0) & RS::ARRAY_FORMAT_INDEX)); - set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]); + Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); + + bool success = set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]); + if (!success) { + destroy_soft_body(); + } } void SoftBodyBullet::destroy_soft_body() { + soft_mesh = RID(); + if (!bt_soft_body) { return; } @@ -289,9 +292,9 @@ void SoftBodyBullet::set_drag_coefficient(real_t p_val) { } } -void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices) { - /// Assert the current soft body is destroyed - destroy_soft_body(); +bool SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices) { + ERR_FAIL_COND_V(p_indices.is_empty(), false); + ERR_FAIL_COND_V(p_vertices.is_empty(), false); /// Parse visual server indices to physical indices. /// Merge all overlapping vertices and create a map of physical vertices to visual server @@ -363,6 +366,8 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector bt_soft_body = btSoftBodyHelpers::CreateFromTriMesh(fake_world_info, &bt_vertices[0], &bt_triangles[0], triangles_size, false); setup_soft_body(); } + + return true; } void SoftBodyBullet::setup_soft_body() { diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index 63708b57a7..84da56ae69 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -32,7 +32,6 @@ #define SOFT_BODY_BULLET_H #include "collision_object_bullet.h" -#include "scene/resources/material.h" // TODO remove this please #ifdef None /// This is required to remove the macro None defined by x11 compiler because this word "None" is used internally by Bullet @@ -42,7 +41,6 @@ #include "BulletSoftBody/btSoftBodyHelpers.h" #include "collision_object_bullet.h" -#include "scene/resources/mesh.h" #include "servers/physics_server_3d.h" #ifdef x11_None @@ -64,7 +62,7 @@ private: btSoftBody::Material *mat0 = nullptr; // This is just a copy of pointer managed by btSoftBody bool isScratched = false; - Ref<Mesh> soft_mesh; + RID soft_mesh; int simulation_precision = 5; real_t total_mass = 1.; @@ -100,7 +98,7 @@ public: void update_rendering_server(RenderingServerHandler *p_rendering_server_handler); - void set_soft_mesh(const Ref<Mesh> &p_mesh); + void set_soft_mesh(RID p_mesh); void destroy_soft_body(); // Special function. This function has bad performance @@ -139,7 +137,7 @@ public: _FORCE_INLINE_ real_t get_drag_coefficient() const { return drag_coefficient; } private: - void set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices); + bool set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices); void setup_soft_body(); void pin_node(int p_node_index); diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 0cfd658bd5..66d7370bd7 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -122,7 +122,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra return 0; } - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale_abs(), p_margin); @@ -158,7 +158,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf btVector3 bt_motion; G_TO_B(p_motion, bt_motion); - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); ERR_FAIL_COND_V(!shape, false); btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin); @@ -219,7 +219,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform3D return false; } - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); ERR_FAIL_COND_V(!shape, false); btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); @@ -251,7 +251,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform3D } bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get_or_null(p_shape); ERR_FAIL_COND_V(!shape, false); btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 229e1e2724..53694035dc 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -258,8 +258,8 @@ void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector< } materials.resize(material_map.size()); - for (Map<Ref<Material>, int>::Element *E = material_map.front(); E; E = E->next()) { - materials.write[E->get()] = E->key(); + for (const KeyValue<Ref<Material>, int> &E : material_map) { + materials.write[E.value] = E.key; } _regen_face_aabbs(); @@ -457,8 +457,8 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b // Update the list of materials. r_merged_brush.materials.resize(mesh_merge.materials.size()); - for (const Map<Ref<Material>, int>::Element *E = mesh_merge.materials.front(); E; E = E->next()) { - r_merged_brush.materials.write[E->get()] = E->key(); + for (const KeyValue<Ref<Material>, int> &E : mesh_merge.materials) { + r_merged_brush.materials.write[E.value] = E.key; } } diff --git a/modules/enet/enet_multiplayer_peer.cpp b/modules/enet/enet_multiplayer_peer.cpp index 52eb46f070..2cfae60ad2 100644 --- a/modules/enet/enet_multiplayer_peer.cpp +++ b/modules/enet/enet_multiplayer_peer.cpp @@ -444,7 +444,7 @@ Error ENetMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size packet_flags = ENET_PACKET_FLAG_UNSEQUENCED; channel = SYSCH_UNRELIABLE; } break; - case Multiplayer::TRANSFER_MODE_ORDERED: { + case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: { packet_flags = 0; channel = SYSCH_UNRELIABLE; } break; diff --git a/modules/fbx/data/fbx_skeleton.cpp b/modules/fbx/data/fbx_skeleton.cpp index 1ac4922acf..3dc163964c 100644 --- a/modules/fbx/data/fbx_skeleton.cpp +++ b/modules/fbx/data/fbx_skeleton.cpp @@ -98,9 +98,9 @@ void FBXSkeleton::init_skeleton(const ImportState &state) { ERR_FAIL_COND_MSG(skeleton->get_bone_count() != bone_count, "Not all bones got added, is the file corrupted?"); - for (Map<int, Ref<FBXBone>>::Element *bone_element = bone_map.front(); bone_element; bone_element = bone_element->next()) { - const Ref<FBXBone> bone = bone_element->value(); - int bone_index = bone_element->key(); + for (const KeyValue<int, Ref<FBXBone>> &bone_element : bone_map) { + const Ref<FBXBone> bone = bone_element.value; + int bone_index = bone_element.key; print_verbose("working on bone: " + itos(bone_index) + " bone name:" + bone->bone_name); skeleton->set_bone_rest(bone->godot_bone_id, get_unscaled_transform(bone->node->pivot_transform->LocalTransform, state.scale)); diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index e3f36ef3e3..e0663ab49d 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -567,8 +567,8 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // this means that the nodes from maya kLocators will be preserved as bones // in the same rig without having to match this across skeletons and merge by detection // we can just merge and undo any parent transforms - for (Map<uint64_t, Ref<FBXBone>>::Element *bone_element = state.fbx_bone_map.front(); bone_element; bone_element = bone_element->next()) { - Ref<FBXBone> bone = bone_element->value(); + for (KeyValue<uint64_t, Ref<FBXBone>> &bone_element : state.fbx_bone_map) { + Ref<FBXBone> bone = bone_element.value; Ref<FBXSkeleton> fbx_skeleton_inst; uint64_t armature_id = bone->armature_id; @@ -609,8 +609,8 @@ Node3D *EditorSceneImporterFBX::_generate_scene( } // setup skeleton instances if required :) - for (Map<uint64_t, Ref<FBXSkeleton>>::Element *skeleton_node = state.skeleton_map.front(); skeleton_node; skeleton_node = skeleton_node->next()) { - Ref<FBXSkeleton> &skeleton = skeleton_node->value(); + for (KeyValue<uint64_t, Ref<FBXSkeleton>> &skeleton_node : state.skeleton_map) { + Ref<FBXSkeleton> &skeleton = skeleton_node.value; skeleton->init_skeleton(state); ERR_CONTINUE_MSG(skeleton->fbx_node.is_null(), "invalid fbx target map, missing skeleton"); @@ -699,9 +699,9 @@ Node3D *EditorSceneImporterFBX::_generate_scene( } } - for (Map<uint64_t, Ref<FBXMeshData>>::Element *mesh_data = state.renderer_mesh_data.front(); mesh_data; mesh_data = mesh_data->next()) { - const uint64_t mesh_id = mesh_data->key(); - Ref<FBXMeshData> mesh = mesh_data->value(); + for (KeyValue<uint64_t, Ref<FBXMeshData>> &mesh_data : state.renderer_mesh_data) { + const uint64_t mesh_id = mesh_data.key; + Ref<FBXMeshData> mesh = mesh_data.value; const FBXDocParser::MeshGeometry *mesh_geometry = p_document->GetObject(mesh_id)->Get<FBXDocParser::MeshGeometry>(); @@ -765,9 +765,9 @@ Node3D *EditorSceneImporterFBX::_generate_scene( } // mesh data iteration for populating skeleton mapping - for (Map<uint64_t, Ref<FBXMeshData>>::Element *mesh_data = state.renderer_mesh_data.front(); mesh_data; mesh_data = mesh_data->next()) { - Ref<FBXMeshData> mesh = mesh_data->value(); - const uint64_t mesh_id = mesh_data->key(); + for (KeyValue<uint64_t, Ref<FBXMeshData>> &mesh_data : state.renderer_mesh_data) { + Ref<FBXMeshData> mesh = mesh_data.value; + const uint64_t mesh_id = mesh_data.key; EditorSceneImporterMeshNode3D *mesh_instance = mesh->godot_mesh_instance; const int mesh_weights = mesh->max_weight_count; Ref<FBXSkeleton> skeleton; @@ -1004,13 +1004,13 @@ Node3D *EditorSceneImporterFBX::_generate_scene( // target id, [ track name, [time index, vector] ] //std::map<uint64_t, std::map<StringName, FBXTrack > > AnimCurveNodes; - for (Map<uint64_t, Map<StringName, FBXTrack>>::Element *track = AnimCurveNodes.front(); track; track = track->next()) { + for (KeyValue<uint64_t, Map<StringName, FBXTrack>> &track : AnimCurveNodes) { // 5 tracks // current track index // track count is 5 // track count is 5. // next track id is 5. - const uint64_t target_id = track->key(); + const uint64_t target_id = track.key; int track_idx = animation->add_track(Animation::TYPE_TRANSFORM3D); // animation->track_set_path(track_idx, node_path); @@ -1072,7 +1072,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene( const FBXDocParser::Model *model = target_node->fbx_model; const FBXDocParser::PropertyTable *props = dynamic_cast<const FBXDocParser::PropertyTable *>(model); - Map<StringName, FBXTrack> &track_data = track->value(); + Map<StringName, FBXTrack> &track_data = track.value; FBXTrack &translation_keys = track_data[StringName("T")]; FBXTrack &rotation_keys = track_data[StringName("R")]; FBXTrack &scale_keys = track_data[StringName("S")]; @@ -1259,15 +1259,15 @@ Node3D *EditorSceneImporterFBX::_generate_scene( state.fbx_target_map.clear(); state.fbx_node_list.clear(); - for (Map<uint64_t, Ref<FBXBone>>::Element *element = state.fbx_bone_map.front(); element; element = element->next()) { - Ref<FBXBone> bone = element->value(); + for (KeyValue<uint64_t, Ref<FBXBone>> &element : state.fbx_bone_map) { + Ref<FBXBone> bone = element.value; bone->parent_bone.unref(); bone->node.unref(); bone->fbx_skeleton.unref(); } - for (Map<uint64_t, Ref<FBXSkeleton>>::Element *element = state.skeleton_map.front(); element; element = element->next()) { - Ref<FBXSkeleton> skel = element->value(); + for (KeyValue<uint64_t, Ref<FBXSkeleton>> &element : state.skeleton_map) { + Ref<FBXSkeleton> skel = element.value; skel->fbx_node.unref(); skel->skeleton_bones.clear(); } diff --git a/modules/fbx/tools/validation_tools.h b/modules/fbx/tools/validation_tools.h index 906a721045..12d644ee94 100644 --- a/modules/fbx/tools/validation_tools.h +++ b/modules/fbx/tools/validation_tools.h @@ -53,9 +53,9 @@ protected: String csv_header = "file_path, error message, extra data\n"; massive_log_file += csv_header; - for (Map<String, LocalVector<String>>::Element *element = validation_entries.front(); element; element = element->next()) { - for (unsigned int x = 0; x < element->value().size(); x++) { - const String &line_entry = element->key() + ", " + element->value()[x].c_escape() + "\n"; + for (const KeyValue<String, LocalVector<String>> &element : validation_entries) { + for (unsigned int x = 0; x < element.value.size(); x++) { + const String &line_entry = element.key + ", " + element.value[x].c_escape() + "\n"; massive_log_file += line_entry; } } diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index 94bda04d12..f7f21a433e 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -18,7 +18,6 @@ Export("env_gdnative") SConscript("pluginscript/SCsub") SConscript("videodecoder/SCsub") -SConscript("text/SCsub") import gdnative_builders diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 627883886c..cf1c7dc01f 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -5103,489 +5103,6 @@ ] } ] - }, - { - "name": "text", - "type": "TEXT", - "version": { - "major": 1, - "minor": 0 - }, - "next": null, - "api": [ - { - "name": "godot_text_register_interface", - "return_type": "void", - "arguments": [ - [ - "const godot_text_interface_gdnative *", - "p_interface" - ], - [ - "const godot_string *", - "p_name" - ], - [ - "uint32_t", - "p_features" - ] - ] - }, - { - "name": "godot_glyph_new", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "r_dest" - ] - ] - }, - { - "name": "godot_glyph_get_range", - "return_type": "godot_vector2i", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_range", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "const godot_vector2i *", - "p_range" - ] - ] - }, - { - "name": "godot_glyph_get_count", - "return_type": "godot_int", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_count", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "godot_int", - "p_count" - ] - ] - }, - { - "name": "godot_glyph_get_repeat", - "return_type": "godot_int", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_repeat", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "godot_int", - "p_repeat" - ] - ] - }, - { - "name": "godot_glyph_get_flags", - "return_type": "godot_int", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_flags", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "godot_int", - "p_flags" - ] - ] - }, - { - "name": "godot_glyph_get_offset", - "return_type": "godot_vector2", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_offset", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "const godot_vector2 *", - "p_offset" - ] - ] - }, - { - "name": "godot_glyph_get_advance", - "return_type": "godot_real_t", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_advance", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "godot_real_t", - "p_advance" - ] - ] - }, - { - "name": "godot_glyph_get_font", - "return_type": "godot_rid", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_font", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "godot_rid *", - "p_font" - ] - ] - }, - { - "name": "godot_glyph_get_font_size", - "return_type": "godot_int", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_font_size", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "godot_int", - "p_size" - ] - ] - }, - { - "name": "godot_glyph_get_index", - "return_type": "godot_int", - "arguments": [ - [ - "const godot_glyph *", - "p_self" - ] - ] - }, - { - "name": "godot_glyph_set_index", - "return_type": "void", - "arguments": [ - [ - "godot_glyph *", - "p_self" - ], - [ - "godot_int", - "p_index" - ] - ] - }, - { - "name": "godot_packed_glyph_array_new", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "r_dest" - ] - ] - }, - { - "name": "godot_packed_glyph_array_new_copy", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "r_dest" - ], - [ - "const godot_packed_glyph_array *", - "p_src" - ] - ] - }, - { - "name": "godot_packed_glyph_array_is_empty", - "return_type": "godot_bool", - "arguments": [ - [ - "const godot_packed_glyph_array *", - "p_self" - ] - ] - }, - { - "name": "godot_packed_glyph_array_append", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_glyph *", - "p_data" - ] - ] - }, - { - "name": "godot_packed_glyph_array_append_array", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_packed_glyph_array *", - "p_array" - ] - ] - }, - { - "name": "godot_packed_glyph_array_insert", - "return_type": "godot_error", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_int", - "p_idx" - ], - [ - "const godot_glyph *", - "p_data" - ] - ] - }, - { - "name": "godot_packed_glyph_array_has", - "return_type": "godot_bool", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_glyph *", - "p_value" - ] - ] - }, - { - "name": "godot_packed_glyph_array_sort", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ] - ] - }, - { - "name": "godot_packed_glyph_array_reverse", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ] - ] - }, - { - "name": "godot_packed_glyph_array_push_back", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_glyph *", - "p_data" - ] - ] - }, - { - "name": "godot_packed_glyph_array_remove", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_int", - "p_idx" - ] - ] - }, - { - "name": "godot_packed_glyph_array_resize", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_int", - "p_size" - ] - ] - }, - { - "name": "godot_packed_glyph_array_ptr", - "return_type": "const godot_glyph *", - "arguments": [ - [ - "const godot_packed_glyph_array *", - "p_self" - ] - ] - }, - { - "name": "godot_packed_glyph_array_ptrw", - "return_type": "godot_glyph *", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ] - ] - }, - { - "name": "godot_packed_glyph_array_set", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_int", - "p_idx" - ], - [ - "const godot_glyph *", - "p_data" - ] - ] - }, - { - "name": "godot_packed_glyph_array_get", - "return_type": "godot_glyph", - "arguments": [ - [ - "const godot_packed_glyph_array *", - "p_self" - ], - [ - "const godot_int", - "p_idx" - ] - ] - }, - { - "name": "godot_packed_glyph_array_size", - "return_type": "godot_int", - "arguments": [ - [ - "const godot_packed_glyph_array *", - "p_self" - ] - ] - }, - { - "name": "godot_packed_glyph_array_destroy", - "return_type": "void", - "arguments": [ - [ - "godot_packed_glyph_array *", - "p_self" - ] - ] - } - ] } ] } diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py index 4986b173cf..6c96e23426 100644 --- a/modules/gdnative/gdnative_builders.py +++ b/modules/gdnative/gdnative_builders.py @@ -22,7 +22,6 @@ def _build_gdnative_api_struct_header(api): "#include <nativescript/godot_nativescript.h>", "#include <pluginscript/godot_pluginscript.h>", "#include <videodecoder/godot_videodecoder.h>", - "#include <text/godot_text.h>", "", "#ifdef __cplusplus", 'extern "C" {', diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp index f965bcd014..9dad13a615 100644 --- a/modules/gdnative/gdnative_library_editor_plugin.cpp +++ b/modules/gdnative/gdnative_library_editor_plugin.cpp @@ -38,9 +38,9 @@ void GDNativeLibraryEditor::edit(Ref<GDNativeLibrary> p_library) { library = p_library; Ref<ConfigFile> config = p_library->get_config_file(); - for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) { - for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) { - String target = E->key() + "." + it->get(); + for (KeyValue<String, NativePlatformConfig> &E : platforms) { + for (List<String>::Element *it = E.value.entries.front(); it; it = it->next()) { + String target = E.key + "." + it->get(); TargetConfig ecfg; ecfg.library = config->get_value("entry", target, ""); ecfg.dependencies = config->get_value("dependencies", target, Array()); @@ -245,9 +245,9 @@ void GDNativeLibraryEditor::_translate_to_config_file() { config->erase_section("entry"); config->erase_section("dependencies"); - for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) { - for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) { - String target = E->key() + "." + it->get(); + for (KeyValue<String, NativePlatformConfig> &E : platforms) { + for (List<String>::Element *it = E.value.entries.front(); it; it = it->next()) { + String target = E.key + "." + it->get(); if (entry_configs[target].library.is_empty() && entry_configs[target].dependencies.is_empty()) { continue; } @@ -341,9 +341,9 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() { filter_list->set_hide_on_checkable_item_selection(false); int idx = 0; - for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) { - filter_list->add_check_item(E->get().name, idx); - filter_list->set_item_metadata(idx, E->key()); + for (const KeyValue<String, NativePlatformConfig> &E : platforms) { + filter_list->add_check_item(E.value.name, idx); + filter_list->set_item_metadata(idx, E.key); filter_list->set_item_checked(idx, true); idx += 1; } diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 09eac2492f..5390d30c9f 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -39,7 +39,7 @@ extern "C" { typedef enum { GODOT_METHOD_RPC_MODE_DISABLED, - GODOT_METHOD_RPC_MODE_ANY, + GODOT_METHOD_RPC_MODE_ANY_PEER, GODOT_METHOD_RPC_MODE_AUTHORITY, } godot_nativescript_method_rpc_mode; diff --git a/modules/gdnative/include/text/godot_text.h b/modules/gdnative/include/text/godot_text.h deleted file mode 100644 index 940cfd11f8..0000000000 --- a/modules/gdnative/include/text/godot_text.h +++ /dev/null @@ -1,283 +0,0 @@ -/*************************************************************************/ -/* godot_text.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GODOT_NATIVETEXT_H -#define GODOT_NATIVETEXT_H - -#include <gdnative/gdnative.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define GODOT_TEXT_API_MAJOR 1 -#define GODOT_TEXT_API_MINOR 0 - -#define GODOT_GLYPH_SIZE 40 - -#ifndef GODOT_TEXT_API_GODOT_GLYPH_TYPE_DEFINED -#define GODOT_TEXT_API_GODOT_GLYPH_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_GLYPH_SIZE]; -} godot_glyph; -#endif - -#define GODOT_PACKED_GLYPH_ARRAY_SIZE (2 * sizeof(void *)) - -#ifndef GODOT_TEXT_API_GODOT_PACKED_GLYPH_ARRAY_TYPE_DEFINED -#define GODOT_TEXT_API_GODOT_PACKED_GLYPH_ARRAY_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_PACKED_GLYPH_ARRAY_SIZE]; -} godot_packed_glyph_array; -#endif - -typedef struct { - godot_gdnative_api_version version; - - void *(*constructor)(godot_object *); - void (*destructor)(void *); - - godot_string (*get_name)(const void *); - godot_bool (*has_feature)(const void *, godot_int); - - void (*free)(void *, godot_rid *); - bool (*has)(void *, godot_rid *); - - bool (*load_support_data)(void *, const godot_string *); - godot_string (*get_support_data_filename)(const void *); - godot_string (*get_support_data_info)(const void *); - bool (*save_support_data)(void *, const godot_string *); - - bool (*is_locale_right_to_left)(void *, const godot_string *); - int32_t (*name_to_tag)(const void *, const godot_string *); - godot_string (*tag_to_name)(const void *, int32_t); - - godot_rid (*create_font)(void *); - void (*font_set_data)(void *, godot_rid *, const godot_packed_byte_array *); - void (*font_set_data_ptr)(void *, godot_rid *, const uint8_t *, size_t); - void (*font_set_antialiased)(void *, godot_rid *, bool); - bool (*font_is_antialiased)(const void *, godot_rid *); - void (*font_set_multichannel_signed_distance_field)(void *, godot_rid *, bool); - bool (*font_is_multichannel_signed_distance_field)(const void *, godot_rid *); - void (*font_set_msdf_pixel_range)(void *, godot_rid *, godot_int); - godot_int (*font_get_msdf_pixel_range)(const void *, godot_rid *); - void (*font_set_msdf_size)(void *, godot_rid *, godot_int); - godot_int (*font_get_msdf_size)(const void *, godot_rid *); - void (*font_set_fixed_size)(void *, godot_rid *, godot_int); - godot_int (*font_get_fixed_size)(const void *, godot_rid *); - void (*font_set_force_autohinter)(void *, godot_rid *, bool); - bool (*font_is_force_autohinter)(const void *, godot_rid *); - void (*font_set_hinting)(void *, godot_rid *, godot_int); - godot_int (*font_get_hinting)(const void *, godot_rid *); - void (*font_set_variation_coordinates)(void *, godot_rid *, const godot_dictionary *); - godot_dictionary (*font_get_variation_coordinates)(const void *, godot_rid *); - void (*font_set_oversampling)(void *, godot_rid *, godot_real_t); - godot_real_t (*font_get_oversampling)(const void *, godot_rid *); - godot_array (*font_get_size_cache_list)(const void *, godot_rid *); - void (*font_clear_size_cache)(void *, godot_rid *); - void (*font_remove_size_cache)(void *, godot_rid *, const godot_vector2i *); - void (*font_set_ascent)(void *, godot_rid *, godot_int, godot_real_t); - godot_real_t (*font_get_ascent)(const void *, godot_rid *, godot_int); - void (*font_set_descent)(void *, godot_rid *, godot_int, godot_real_t); - godot_real_t (*font_get_descent)(const void *, godot_rid *, godot_int); - void (*font_set_underline_position)(void *, godot_rid *, godot_int, godot_real_t); - godot_real_t (*font_get_underline_position)(const void *, godot_rid *, godot_int); - void (*font_set_underline_thickness)(void *, godot_rid *, godot_int, godot_real_t); - godot_real_t (*font_get_underline_thickness)(const void *, godot_rid *, godot_int); - void (*font_set_scale)(void *, godot_rid *, godot_int, godot_real_t); - godot_real_t (*font_get_scale)(const void *, godot_rid *, godot_int); - void (*font_set_spacing)(void *, godot_rid *, godot_int, godot_int, godot_int); - godot_int (*font_get_spacing)(const void *, godot_rid *, godot_int, godot_int); - godot_int (*font_get_texture_count)(const void *, godot_rid *, const godot_vector2i *); - void (*font_clear_textures)(void *, godot_rid *, const godot_vector2i *); - void (*font_remove_texture)(void *, godot_rid *, const godot_vector2i *, godot_int); - void (*font_set_texture_image)(void *, godot_rid *, const godot_vector2i *, godot_int, const godot_object *); - godot_object *(*font_get_texture_image)(const void *, godot_rid *, const godot_vector2i *, godot_int); - void (*font_set_texture_offsets)(void *, godot_rid *, const godot_vector2i *, godot_int, const godot_packed_int32_array *); - godot_packed_int32_array (*font_get_texture_offsets)(const void *, godot_rid *, const godot_vector2i *, godot_int); - godot_array (*font_get_glyph_list)(const void *, godot_rid *, const godot_vector2i *); - void (*font_clear_glyphs)(void *, godot_rid *, const godot_vector2i *); - void (*font_remove_glyph)(void *, godot_rid *, const godot_vector2i *, int32_t); - godot_vector2 (*font_get_glyph_advance)(const void *, godot_rid *, godot_int, int32_t); - void (*font_set_glyph_advance)(void *, godot_rid *, godot_int, int32_t, const godot_vector2 *); - godot_vector2 (*font_get_glyph_offset)(const void *, godot_rid *, const godot_vector2i *, int32_t); - void (*font_set_glyph_offset)(void *, godot_rid *, const godot_vector2i *, int32_t, const godot_vector2 *); - godot_vector2 (*font_get_glyph_size)(const void *, godot_rid *, const godot_vector2i *, int32_t); - void (*font_set_glyph_size)(void *, godot_rid *, const godot_vector2i *, int32_t, const godot_vector2 *); - godot_rect2 (*font_get_glyph_uv_rect)(const void *, godot_rid *, const godot_vector2i *, int32_t); - void (*font_set_glyph_uv_rect)(void *, godot_rid *, const godot_vector2i *, int32_t, const godot_rect2 *); - godot_int (*font_get_glyph_texture_idx)(const void *, godot_rid *, const godot_vector2i *, int32_t); - void (*font_set_glyph_texture_idx)(void *, godot_rid *, const godot_vector2i *, int32_t, godot_int); - bool (*font_get_glyph_contours)(const void *, godot_rid *, godot_int, int32_t, godot_packed_vector3_array *, godot_packed_int32_array *, bool *); - godot_array (*font_get_kerning_list)(const void *, godot_rid *, godot_int); - void (*font_clear_kerning_map)(void *, godot_rid *, godot_int); - void (*font_remove_kerning)(void *, godot_rid *, godot_int, const godot_vector2i *); - void (*font_set_kerning)(void *, godot_rid *, godot_int, const godot_vector2i *, const godot_vector2 *); - godot_vector2 (*font_get_kerning)(const void *, godot_rid *, godot_int, const godot_vector2i *); - int32_t (*font_get_glyph_index)(const void *, godot_rid *, godot_int, char32_t, char32_t); - bool (*font_has_char)(const void *, godot_rid *, char32_t); - godot_string (*font_get_supported_chars)(const void *, godot_rid *); - void (*font_render_range)(void *, godot_rid *, const godot_vector2i *, char32_t, char32_t); - void (*font_render_glyph)(void *, godot_rid *, const godot_vector2i *, int32_t); - void (*font_draw_glyph)(const void *, godot_rid *, godot_rid *, godot_int, const godot_vector2 *, int32_t, const godot_color *); - void (*font_draw_glyph_outline)(const void *, godot_rid *, godot_rid *, godot_int, godot_int, const godot_vector2 *, int32_t, const godot_color *); - bool (*font_is_language_supported)(const void *, godot_rid *, const godot_string *); - void (*font_set_language_support_override)(void *, godot_rid *, const godot_string *, bool); - bool (*font_get_language_support_override)(const void *, godot_rid *, const godot_string *); - void (*font_remove_language_support_override)(void *, godot_rid *, const godot_string *); - godot_packed_string_array (*font_get_language_support_overrides)(const void *, godot_rid *); - bool (*font_is_script_supported)(const void *, godot_rid *, const godot_string *); - void (*font_set_script_support_override)(void *, godot_rid *, const godot_string *, bool); - bool (*font_get_script_support_override)(const void *, godot_rid *, const godot_string *); - void (*font_remove_script_support_override)(void *, godot_rid *, const godot_string *); - godot_packed_string_array (*font_get_script_support_overrides)(const void *, godot_rid *); - godot_dictionary (*font_supported_feature_list)(const void *, godot_rid *); - godot_dictionary (*font_supported_variation_list)(const void *, godot_rid *); - godot_real_t (*font_get_global_oversampling)(const void *); - void (*font_set_global_oversampling)(void *, godot_real_t); - - godot_rid (*create_shaped_text)(void *, godot_int, godot_int); - void (*shaped_text_clear)(void *, godot_rid *); - void (*shaped_text_set_direction)(void *, godot_rid *, godot_int); - godot_int (*shaped_text_get_direction)(void *, godot_rid *); - void (*shaped_text_set_bidi_override)(void *, godot_rid *, const godot_packed_vector2i_array *); - void (*shaped_text_set_orientation)(void *, godot_rid *, godot_int); - godot_int (*shaped_text_get_orientation)(void *, godot_rid *); - void (*shaped_text_set_preserve_invalid)(void *, godot_rid *, bool); - bool (*shaped_text_get_preserve_invalid)(void *, godot_rid *); - void (*shaped_text_set_preserve_control)(void *, godot_rid *, bool); - bool (*shaped_text_get_preserve_control)(void *, godot_rid *); - bool (*shaped_text_add_string)(void *, godot_rid *, const godot_string *, const godot_rid **, int, const godot_dictionary *, const godot_string *); - bool (*shaped_text_add_object)(void *, godot_rid *, const godot_variant *, const godot_vector2 *, godot_int, godot_int); - bool (*shaped_text_resize_object)(void *, godot_rid *, const godot_variant *, const godot_vector2 *, godot_int); - godot_rid (*shaped_text_substr)(void *, godot_rid *, godot_int, godot_int); - godot_rid (*shaped_text_get_parent)(void *, godot_rid *); - godot_real_t (*shaped_text_fit_to_width)(void *, godot_rid *, godot_real_t, uint8_t); - godot_real_t (*shaped_text_tab_align)(void *, godot_rid *, godot_packed_float32_array *); - bool (*shaped_text_shape)(void *, godot_rid *); - bool (*shaped_text_update_breaks)(void *, godot_rid *); - bool (*shaped_text_update_justification_ops)(void *, godot_rid *); - void (*shaped_text_overrun_trim_to_width)(void *, godot_rid *, godot_real_t, uint8_t); - bool (*shaped_text_is_ready)(void *, godot_rid *); - godot_packed_glyph_array (*shaped_text_get_glyphs)(void *, godot_rid *); - godot_vector2i (*shaped_text_get_range)(void *, godot_rid *); - godot_packed_glyph_array (*shaped_text_sort_logical)(void *, godot_rid *); - godot_packed_vector2i_array (*shaped_text_get_line_breaks_adv)(void *, godot_rid *, godot_packed_float32_array *, int, bool, uint8_t); - godot_packed_vector2i_array (*shaped_text_get_line_breaks)(void *, godot_rid *, godot_real_t, int, uint8_t); - godot_packed_vector2i_array (*shaped_text_get_word_breaks)(void *, godot_rid *, int); - godot_array (*shaped_text_get_objects)(void *, godot_rid *); - godot_rect2 (*shaped_text_get_object_rect)(void *, godot_rid *, const godot_variant *); - godot_vector2 (*shaped_text_get_size)(void *, godot_rid *); - godot_real_t (*shaped_text_get_ascent)(void *, godot_rid *); - godot_real_t (*shaped_text_get_descent)(void *, godot_rid *); - godot_real_t (*shaped_text_get_width)(void *, godot_rid *); - godot_real_t (*shaped_text_get_underline_position)(void *, godot_rid *); - godot_real_t (*shaped_text_get_underline_thickness)(void *, godot_rid *); - - godot_string (*format_number)(void *, const godot_string *, const godot_string *); - godot_string (*parse_number)(void *, const godot_string *, const godot_string *); - godot_string (*percent_sign)(void *, const godot_string *); -} godot_text_interface_gdnative; - -void GDAPI godot_text_register_interface(const godot_text_interface_gdnative *p_interface, const godot_string *p_name, uint32_t p_features); - -// Glyph - -void GDAPI godot_glyph_new(godot_glyph *r_dest); - -godot_vector2i GDAPI godot_glyph_get_range(const godot_glyph *p_self); -void GDAPI godot_glyph_set_range(godot_glyph *p_self, const godot_vector2i *p_range); - -godot_int GDAPI godot_glyph_get_count(const godot_glyph *p_self); -void GDAPI godot_glyph_set_count(godot_glyph *p_self, godot_int p_count); - -godot_int GDAPI godot_glyph_get_repeat(const godot_glyph *p_self); -void GDAPI godot_glyph_set_repeat(godot_glyph *p_self, godot_int p_repeat); - -godot_int GDAPI godot_glyph_get_flags(const godot_glyph *p_self); -void GDAPI godot_glyph_set_flags(godot_glyph *p_self, godot_int p_flags); - -godot_vector2 GDAPI godot_glyph_get_offset(const godot_glyph *p_self); -void GDAPI godot_glyph_set_offset(godot_glyph *p_self, const godot_vector2 *p_offset); - -godot_real_t GDAPI godot_glyph_get_advance(const godot_glyph *p_self); -void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_real_t p_advance); - -godot_rid GDAPI godot_glyph_get_font(const godot_glyph *p_self); -void GDAPI godot_glyph_set_font(godot_glyph *p_self, godot_rid *p_font); - -godot_int GDAPI godot_glyph_get_font_size(const godot_glyph *p_self); -void GDAPI godot_glyph_set_font_size(godot_glyph *p_self, godot_int p_size); - -godot_int GDAPI godot_glyph_get_index(const godot_glyph *p_self); -void GDAPI godot_glyph_set_index(godot_glyph *p_self, godot_int p_index); - -// GlyphArray - -void GDAPI godot_packed_glyph_array_new(godot_packed_glyph_array *r_dest); -void GDAPI godot_packed_glyph_array_new_copy(godot_packed_glyph_array *r_dest, const godot_packed_glyph_array *p_src); - -const godot_glyph GDAPI *godot_packed_glyph_array_ptr(const godot_packed_glyph_array *p_self); -godot_glyph GDAPI *godot_packed_glyph_array_ptrw(godot_packed_glyph_array *p_self); - -void GDAPI godot_packed_glyph_array_append(godot_packed_glyph_array *p_self, const godot_glyph *p_data); - -void GDAPI godot_packed_glyph_array_append_array(godot_packed_glyph_array *p_self, const godot_packed_glyph_array *p_array); - -godot_error GDAPI godot_packed_glyph_array_insert(godot_packed_glyph_array *p_self, const godot_int p_idx, const godot_glyph *p_data); - -godot_bool GDAPI godot_packed_glyph_array_has(godot_packed_glyph_array *p_self, const godot_glyph *p_value); - -void GDAPI godot_packed_glyph_array_sort(godot_packed_glyph_array *p_self); - -void GDAPI godot_packed_glyph_array_reverse(godot_packed_glyph_array *p_self); - -void GDAPI godot_packed_glyph_array_push_back(godot_packed_glyph_array *p_self, const godot_glyph *p_data); - -void GDAPI godot_packed_glyph_array_remove(godot_packed_glyph_array *p_self, godot_int p_idx); - -void GDAPI godot_packed_glyph_array_resize(godot_packed_glyph_array *p_self, godot_int p_size); - -void GDAPI godot_packed_glyph_array_set(godot_packed_glyph_array *p_self, godot_int p_idx, const godot_glyph *p_data); -godot_glyph GDAPI godot_packed_glyph_array_get(const godot_packed_glyph_array *p_self, godot_int p_idx); - -godot_int GDAPI godot_packed_glyph_array_size(const godot_packed_glyph_array *p_self); - -godot_bool GDAPI godot_packed_glyph_array_is_empty(const godot_packed_glyph_array *p_self); - -void GDAPI godot_packed_glyph_array_destroy(godot_packed_glyph_array *p_self); - -// Grapheme - -#ifdef __cplusplus -} -#endif - -#endif /* !GODOT_NATIVETEXT_H */ diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 2d9b45cb07..598f7c7ad0 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -223,8 +223,8 @@ List<ClassAPI> generate_c_api_classes() { enum_api_map[enum_name] = enum_api; } } - for (const Map<StringName, EnumAPI>::Element *E = enum_api_map.front(); E; E = E->next()) { - global_constants_api.enums.push_back(E->get()); + for (const KeyValue<StringName, EnumAPI> &E : enum_api_map) { + global_constants_api.enums.push_back(E.value); } global_constants_api.constants.sort_custom<ConstantAPIComparator>(); api.push_back(global_constants_api); diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 92ba9bd452..fb46bafb3c 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -360,8 +360,8 @@ void NativeScript::get_script_signal_list(List<MethodInfo> *r_signals) const { Set<MethodInfo> signals_; while (script_data) { - for (Map<StringName, NativeScriptDesc::Signal>::Element *S = script_data->signals_.front(); S; S = S->next()) { - signals_.insert(S->get().signal); + for (const KeyValue<StringName, NativeScriptDesc::Signal> &S : script_data->signals_) { + signals_.insert(S.value.signal); } script_data = script_data->base_data; @@ -401,8 +401,8 @@ void NativeScript::get_script_method_list(List<MethodInfo> *p_list) const { Set<MethodInfo> methods; while (script_data) { - for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) { - methods.insert(E->get().info); + for (const KeyValue<StringName, NativeScriptDesc::Method> &E : script_data->methods) { + methods.insert(E.value.info); } script_data = script_data->base_data; @@ -857,9 +857,9 @@ NativeScriptLanguage *NativeScriptLanguage::singleton; void NativeScriptLanguage::_unload_stuff(bool p_reload) { Map<String, Ref<GDNative>> erase_and_unload; - for (Map<String, Map<StringName, NativeScriptDesc>>::Element *L = library_classes.front(); L; L = L->next()) { - String lib_path = L->key(); - Map<StringName, NativeScriptDesc> classes = L->get(); + for (KeyValue<String, Map<StringName, NativeScriptDesc>> &L : library_classes) { + String lib_path = L.key; + Map<StringName, NativeScriptDesc> classes = L.value; if (p_reload) { Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path); @@ -890,9 +890,9 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { gdn = E->get(); } - for (Map<StringName, NativeScriptDesc>::Element *C = classes.front(); C; C = C->next()) { + for (KeyValue<StringName, NativeScriptDesc> &C : classes) { // free property stuff first - for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = C->get().properties.front(); P; P = P.next()) { + for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = C.value.properties.front(); P; P = P.next()) { if (P.get().getter.free_func) { P.get().getter.free_func(P.get().getter.method_data); } @@ -903,28 +903,28 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { } // free method stuff - for (Map<StringName, NativeScriptDesc::Method>::Element *M = C->get().methods.front(); M; M = M->next()) { - if (M->get().method.free_func) { - M->get().method.free_func(M->get().method.method_data); + for (const KeyValue<StringName, NativeScriptDesc::Method> &M : C.value.methods) { + if (M.value.method.free_func) { + M.value.method.free_func(M.value.method.method_data); } } // free constructor/destructor - if (C->get().create_func.free_func) { - C->get().create_func.free_func(C->get().create_func.method_data); + if (C.value.create_func.free_func) { + C.value.create_func.free_func(C.value.create_func.method_data); } - if (C->get().destroy_func.free_func) { - C->get().destroy_func.free_func(C->get().destroy_func.method_data); + if (C.value.destroy_func.free_func) { + C.value.destroy_func.free_func(C.value.destroy_func.method_data); } } erase_and_unload.insert(lib_path, gdn); } - for (Map<String, Ref<GDNative>>::Element *E = erase_and_unload.front(); E; E = E->next()) { - String lib_path = E->key(); - Ref<GDNative> gdn = E->get(); + for (KeyValue<String, Ref<GDNative>> &E : erase_and_unload) { + String lib_path = E.key; + Ref<GDNative> gdn = E.value; library_classes.erase(lib_path); @@ -957,8 +957,8 @@ NativeScriptLanguage::NativeScriptLanguage() { } NativeScriptLanguage::~NativeScriptLanguage() { - for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { - Ref<GDNative> lib = L->get(); + for (KeyValue<String, Ref<GDNative>> &L : NSL->library_gdnatives) { + Ref<GDNative> lib = L.value; // only shut down valid libs, duh! if (lib.is_valid()) { // If it's a singleton-library then the gdnative module @@ -1157,15 +1157,15 @@ int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_a int current = 0; - for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { + for (const KeyValue<StringName, ProfileData> &d : profile_data) { if (current >= p_info_max) { break; } - p_info_arr[current].call_count = d->get().call_count; - p_info_arr[current].self_time = d->get().self_time; - p_info_arr[current].total_time = d->get().total_time; - p_info_arr[current].signature = d->get().signature; + p_info_arr[current].call_count = d.value.call_count; + p_info_arr[current].self_time = d.value.self_time; + p_info_arr[current].total_time = d.value.total_time; + p_info_arr[current].signature = d.value.signature; current++; } @@ -1181,16 +1181,16 @@ int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, in int current = 0; - for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { + for (const KeyValue<StringName, ProfileData> &d : profile_data) { if (current >= p_info_max) { break; } - if (d->get().last_frame_call_count) { - p_info_arr[current].call_count = d->get().last_frame_call_count; - p_info_arr[current].self_time = d->get().last_frame_self_time; - p_info_arr[current].total_time = d->get().last_frame_total_time; - p_info_arr[current].signature = d->get().signature; + if (d.value.last_frame_call_count) { + p_info_arr[current].call_count = d.value.last_frame_call_count; + p_info_arr[current].self_time = d.value.last_frame_self_time; + p_info_arr[current].total_time = d.value.last_frame_total_time; + p_info_arr[current].signature = d.value.signature; current++; } } @@ -1503,9 +1503,9 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) { if (L) { Map<StringName, NativeScriptDesc> classes = L->get(); - for (Map<StringName, NativeScriptDesc>::Element *C = classes.front(); C; C = C->next()) { + for (KeyValue<StringName, NativeScriptDesc> &C : classes) { // free property stuff first - for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = C->get().properties.front(); P; P = P.next()) { + for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = C.value.properties.front(); P; P = P.next()) { if (P.get().getter.free_func) { P.get().getter.free_func(P.get().getter.method_data); } @@ -1516,19 +1516,19 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) { } // free method stuff - for (Map<StringName, NativeScriptDesc::Method>::Element *M = C->get().methods.front(); M; M = M->next()) { - if (M->get().method.free_func) { - M->get().method.free_func(M->get().method.method_data); + for (const KeyValue<StringName, NativeScriptDesc::Method> &M : C.value.methods) { + if (M.value.method.free_func) { + M.value.method.free_func(M.value.method.method_data); } } // free constructor/destructor - if (C->get().create_func.free_func) { - C->get().create_func.free_func(C->get().create_func.method_data); + if (C.value.create_func.free_func) { + C.value.create_func.free_func(C.value.create_func.method_data); } - if (C->get().destroy_func.free_func) { - C->get().destroy_func.free_func(C->get().destroy_func.method_data); + if (C.value.destroy_func.free_func) { + C.value.destroy_func.free_func(C.value.destroy_func.method_data); } } @@ -1548,14 +1548,14 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) { void NativeScriptLanguage::call_libraries_cb(const StringName &name) { // library_gdnatives is modified only from the main thread, so it's safe not to use mutex here - for (Map<String, Ref<GDNative>>::Element *L = library_gdnatives.front(); L; L = L->next()) { - if (L->get().is_null()) { + for (KeyValue<String, Ref<GDNative>> &L : library_gdnatives) { + if (L.value.is_null()) { continue; } - if (L->get()->is_initialized()) { + if (L.value->is_initialized()) { void *proc_ptr; - Error err = L->get()->get_symbol(L->get()->get_library()->get_symbol_prefix() + name, proc_ptr); + Error err = L.value->get_symbol(L.value->get_library()->get_symbol_prefix() + name, proc_ptr); if (!err) { ((void (*)())proc_ptr)(); @@ -1584,13 +1584,13 @@ void NativeScriptLanguage::frame() { { MutexLock lock(mutex); - for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { - d->get().last_frame_call_count = d->get().frame_call_count; - d->get().last_frame_self_time = d->get().frame_self_time; - d->get().last_frame_total_time = d->get().frame_total_time; - d->get().frame_call_count = 0; - d->get().frame_self_time = 0; - d->get().frame_total_time = 0; + for (KeyValue<StringName, ProfileData> &d : profile_data) { + d.value.last_frame_call_count = d.value.frame_call_count; + d.value.last_frame_self_time = d.value.frame_self_time; + d.value.last_frame_total_time = d.value.frame_total_time; + d.value.frame_call_count = 0; + d.value.frame_self_time = 0; + d.value.frame_total_time = 0; } } #endif @@ -1651,8 +1651,8 @@ void NativeReloadNode::_notification(int p_what) { MutexLock lock(NSL->mutex); NSL->_unload_stuff(true); - for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { - Ref<GDNative> gdn = L->get(); + for (KeyValue<String, Ref<GDNative>> &L : NSL->library_gdnatives) { + Ref<GDNative> gdn = L.value; if (gdn.is_null()) { continue; @@ -1685,8 +1685,8 @@ void NativeReloadNode::_notification(int p_what) { MutexLock lock(NSL->mutex); Set<StringName> libs_to_remove; - for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { - Ref<GDNative> gdn = L->get(); + for (KeyValue<String, Ref<GDNative>> &L : NSL->library_gdnatives) { + Ref<GDNative> gdn = L.value; if (gdn.is_null()) { continue; @@ -1703,24 +1703,24 @@ void NativeReloadNode::_notification(int p_what) { } if (!gdn->initialize()) { - libs_to_remove.insert(L->key()); + libs_to_remove.insert(L.key); continue; } - NSL->library_classes.insert(L->key(), Map<StringName, NativeScriptDesc>()); + NSL->library_classes.insert(L.key, Map<StringName, NativeScriptDesc>()); // here the library registers all the classes and stuff. void *proc_ptr; Error err = gdn->get_symbol(gdn->get_library()->get_symbol_prefix() + "nativescript_init", proc_ptr); if (err != OK) { - ERR_PRINT(String("No godot_nativescript_init in \"" + L->key() + "\" found").utf8().get_data()); + ERR_PRINT(String("No godot_nativescript_init in \"" + L.key + "\" found").utf8().get_data()); } else { - ((void (*)(void *))proc_ptr)((void *)&L->key()); + ((void (*)(void *))proc_ptr)((void *)&L.key); } - for (Map<String, Set<NativeScript *>>::Element *U = NSL->library_script_users.front(); U; U = U->next()) { - for (Set<NativeScript *>::Element *S = U->get().front(); S; S = S->next()) { + for (KeyValue<String, Set<NativeScript *>> &U : NSL->library_script_users) { + for (Set<NativeScript *>::Element *S = U.value.front(); S; S = S->next()) { NativeScript *script = S->get(); if (script->placeholders.size() == 0) { diff --git a/modules/gdnative/text/SCsub b/modules/gdnative/text/SCsub deleted file mode 100644 index 0b2db3b504..0000000000 --- a/modules/gdnative/text/SCsub +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_gdnative") - -env_gdnative.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/gdnative/text/config.py b/modules/gdnative/text/config.py deleted file mode 100644 index d22f9454ed..0000000000 --- a/modules/gdnative/text/config.py +++ /dev/null @@ -1,6 +0,0 @@ -def can_build(env, platform): - return True - - -def configure(env): - pass diff --git a/modules/gdnative/text/text_server_gdnative.cpp b/modules/gdnative/text/text_server_gdnative.cpp deleted file mode 100644 index 39db8ae636..0000000000 --- a/modules/gdnative/text/text_server_gdnative.cpp +++ /dev/null @@ -1,1086 +0,0 @@ -/*************************************************************************/ -/* text_server_gdnative.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "text_server_gdnative.h" - -bool TextServerGDNative::has_feature(Feature p_feature) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->has_feature(data, (godot_int)p_feature); -} - -String TextServerGDNative::get_name() const { - ERR_FAIL_COND_V(interface == nullptr, String()); - godot_string result = interface->get_name(data); - String name = *(String *)&result; - godot_string_destroy(&result); - return name; -} - -void TextServerGDNative::free(RID p_rid) { - ERR_FAIL_COND(interface == nullptr); - interface->free(data, (godot_rid *)&p_rid); -} - -bool TextServerGDNative::has(RID p_rid) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->has(data, (godot_rid *)&p_rid); -} - -bool TextServerGDNative::load_support_data(const String &p_filename) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->load_support_data(data, (godot_string *)&p_filename); -} - -#ifdef TOOLS_ENABLED - -String TextServerGDNative::get_support_data_filename() { - ERR_FAIL_COND_V(interface == nullptr, String()); - godot_string result = interface->get_support_data_filename(data); - String name = *(String *)&result; - godot_string_destroy(&result); - return name; -} - -String TextServerGDNative::get_support_data_info() { - ERR_FAIL_COND_V(interface == nullptr, String()); - godot_string result = interface->get_support_data_info(data); - String info = *(String *)&result; - godot_string_destroy(&result); - return info; -} - -bool TextServerGDNative::save_support_data(const String &p_filename) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->save_support_data(data, (godot_string *)&p_filename); -} - -#endif - -bool TextServerGDNative::is_locale_right_to_left(const String &p_locale) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->is_locale_right_to_left(data, (godot_string *)&p_locale); -} - -int32_t TextServerGDNative::name_to_tag(const String &p_name) const { - ERR_FAIL_COND_V(interface == nullptr, 0); - return interface->name_to_tag(data, (godot_string *)&p_name); -} - -String TextServerGDNative::tag_to_name(int32_t p_tag) const { - ERR_FAIL_COND_V(interface == nullptr, String()); - godot_string result = interface->tag_to_name(data, p_tag); - String name = *(String *)&result; - godot_string_destroy(&result); - return name; -} - -/*************************************************************************/ -/* Font */ -/*************************************************************************/ - -RID TextServerGDNative::create_font() { - ERR_FAIL_COND_V(interface == nullptr, RID()); - godot_rid result = interface->create_font(data); - RID rid = *(RID *)&result; - return rid; -} - -void TextServerGDNative::font_set_data(RID p_font_rid, const PackedByteArray &p_data) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_data(data, (godot_rid *)&p_font_rid, (const godot_packed_byte_array *)&p_data); -} - -void TextServerGDNative::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_data_ptr(data, (godot_rid *)&p_font_rid, p_data_ptr, p_data_size); -} - -void TextServerGDNative::font_set_antialiased(RID p_font_rid, bool p_antialiased) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_antialiased(data, (godot_rid *)&p_font_rid, p_antialiased); -} - -bool TextServerGDNative::font_is_antialiased(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_is_antialiased(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_multichannel_signed_distance_field(data, (godot_rid *)&p_font_rid, p_msdf); -} - -bool TextServerGDNative::font_is_multichannel_signed_distance_field(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_is_multichannel_signed_distance_field(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_msdf_pixel_range(data, (godot_rid *)&p_font_rid, p_msdf_pixel_range); -} - -int TextServerGDNative::font_get_msdf_pixel_range(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, 0); - return interface->font_get_msdf_pixel_range(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_set_msdf_size(RID p_font_rid, int p_msdf_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_msdf_size(data, (godot_rid *)&p_font_rid, p_msdf_size); -} - -int TextServerGDNative::font_get_msdf_size(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, 0); - return interface->font_get_msdf_size(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_set_fixed_size(RID p_font_rid, int p_fixed_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_fixed_size(data, (godot_rid *)&p_font_rid, p_fixed_size); -} - -int TextServerGDNative::font_get_fixed_size(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, 0); - return interface->font_get_fixed_size(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_force_autohinter(data, (godot_rid *)&p_font_rid, p_force_autohinter); -} - -bool TextServerGDNative::font_is_force_autohinter(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_is_force_autohinter(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_hinting(data, (godot_rid *)&p_font_rid, (godot_int)p_hinting); -} - -TextServer::Hinting TextServerGDNative::font_get_hinting(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, TextServer::HINTING_NONE); - return (TextServer::Hinting)interface->font_get_hinting(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_variation_coordinates(data, (godot_rid *)&p_font_rid, (const godot_dictionary *)&p_variation_coordinates); -} - -Dictionary TextServerGDNative::font_get_variation_coordinates(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, Dictionary()); - godot_dictionary result = interface->font_get_variation_coordinates(data, (godot_rid *)&p_font_rid); - Dictionary dict = *(Dictionary *)&result; - godot_dictionary_destroy(&result); - return dict; -} - -void TextServerGDNative::font_set_oversampling(RID p_font_rid, real_t p_oversampling) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_oversampling(data, (godot_rid *)&p_font_rid, p_oversampling); -} - -real_t TextServerGDNative::font_get_oversampling(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, 0.0f); - return interface->font_get_oversampling(data, (godot_rid *)&p_font_rid); -} - -Array TextServerGDNative::font_get_size_cache_list(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, Array()); - godot_array result = interface->font_get_size_cache_list(data, (godot_rid *)&p_font_rid); - Array list = *(Array *)&result; - godot_array_destroy(&result); - return list; -} - -void TextServerGDNative::font_clear_size_cache(RID p_font_rid) { - ERR_FAIL_COND(interface == nullptr); - interface->font_clear_size_cache(data, (godot_rid *)&p_font_rid); -} - -void TextServerGDNative::font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_remove_size_cache(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size); -} - -void TextServerGDNative::font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_ascent(data, (godot_rid *)&p_font_rid, p_size, p_ascent); -} - -real_t TextServerGDNative::font_get_ascent(RID p_font_rid, int p_size) const { - ERR_FAIL_COND_V(interface == nullptr, 0.0f); - return interface->font_get_ascent(data, (godot_rid *)&p_font_rid, p_size); -} - -void TextServerGDNative::font_set_descent(RID p_font_rid, int p_size, real_t p_descent) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_descent(data, (godot_rid *)&p_font_rid, p_size, p_descent); -} - -real_t TextServerGDNative::font_get_descent(RID p_font_rid, int p_size) const { - ERR_FAIL_COND_V(interface == nullptr, 0.0f); - return interface->font_get_descent(data, (godot_rid *)&p_font_rid, p_size); -} - -void TextServerGDNative::font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_underline_position(data, (godot_rid *)&p_font_rid, p_size, p_underline_position); -} - -real_t TextServerGDNative::font_get_underline_position(RID p_font_rid, int p_size) const { - ERR_FAIL_COND_V(interface == nullptr, 0.0f); - return interface->font_get_underline_position(data, (godot_rid *)&p_font_rid, p_size); -} - -void TextServerGDNative::font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_underline_thickness(data, (godot_rid *)&p_font_rid, p_size, p_underline_thickness); -} - -real_t TextServerGDNative::font_get_underline_thickness(RID p_font_rid, int p_size) const { - ERR_FAIL_COND_V(interface == nullptr, 0.0f); - return interface->font_get_underline_thickness(data, (godot_rid *)&p_font_rid, p_size); -} - -void TextServerGDNative::font_set_scale(RID p_font_rid, int p_size, real_t p_scale) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_scale(data, (godot_rid *)&p_font_rid, p_size, p_scale); -} - -real_t TextServerGDNative::font_get_scale(RID p_font_rid, int p_size) const { - ERR_FAIL_COND_V(interface == nullptr, 0.0f); - return interface->font_get_scale(data, (godot_rid *)&p_font_rid, p_size); -} - -void TextServerGDNative::font_set_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing, int p_value) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_spacing(data, (godot_rid *)&p_font_rid, p_size, (godot_int)p_spacing, p_value); -} - -int TextServerGDNative::font_get_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing) const { - ERR_FAIL_COND_V(interface == nullptr, 0); - return interface->font_get_spacing(data, (godot_rid *)&p_font_rid, p_size, (godot_int)p_spacing); -} - -int TextServerGDNative::font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const { - ERR_FAIL_COND_V(interface == nullptr, -1); - return interface->font_get_texture_count(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size); -} - -void TextServerGDNative::font_clear_textures(RID p_font_rid, const Vector2i &p_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_clear_textures(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size); -} - -void TextServerGDNative::font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) { - ERR_FAIL_COND(interface == nullptr); - interface->font_remove_texture(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_texture_index); -} - -void TextServerGDNative::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_texture_image(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_texture_index, (const godot_object *)p_image.ptr()); -} - -Ref<Image> TextServerGDNative::font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { - ERR_FAIL_COND_V(interface == nullptr, Ref<Image>()); - godot_object *result = interface->font_get_texture_image(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_texture_index); - return Ref<Image>((Image *)result); -} - -void TextServerGDNative::font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_texture_offsets(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_texture_index, (const godot_packed_int32_array *)&p_offset); -} - -PackedInt32Array TextServerGDNative::font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { - ERR_FAIL_COND_V(interface == nullptr, PackedInt32Array()); - godot_packed_int32_array result = interface->font_get_texture_offsets(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_texture_index); - PackedInt32Array offset = *(PackedInt32Array *)&result; - godot_packed_int32_array_destroy(&result); - return offset; -} - -Array TextServerGDNative::font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const { - ERR_FAIL_COND_V(interface == nullptr, Array()); - godot_array result = interface->font_get_glyph_list(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size); - Array list = *(Array *)&result; - godot_array_destroy(&result); - return list; -} - -void TextServerGDNative::font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_clear_glyphs(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size); -} - -void TextServerGDNative::font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) { - ERR_FAIL_COND(interface == nullptr); - interface->font_remove_glyph(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph); -} - -Vector2 TextServerGDNative::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const { - ERR_FAIL_COND_V(interface == nullptr, Vector2()); - godot_vector2 result = interface->font_get_glyph_advance(data, (godot_rid *)&p_font_rid, p_size, p_glyph); - Vector2 adv = *(Vector2 *)&result; - return adv; -} - -void TextServerGDNative::font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_glyph_advance(data, (godot_rid *)&p_font_rid, p_size, p_glyph, (const godot_vector2 *)&p_advance); -} - -Vector2 TextServerGDNative::font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - ERR_FAIL_COND_V(interface == nullptr, Vector2()); - godot_vector2 result = interface->font_get_glyph_offset(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph); - Vector2 off = *(Vector2 *)&result; - return off; -} - -void TextServerGDNative::font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_glyph_offset(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph, (const godot_vector2 *)&p_offset); -} - -Vector2 TextServerGDNative::font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - ERR_FAIL_COND_V(interface == nullptr, Vector2()); - godot_vector2 result = interface->font_get_glyph_size(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph); - Vector2 sz = *(Vector2 *)&result; - return sz; -} - -void TextServerGDNative::font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_glyph_size(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph, (const godot_vector2 *)&p_gl_size); -} - -Rect2 TextServerGDNative::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - ERR_FAIL_COND_V(interface == nullptr, Rect2()); - godot_rect2 result = interface->font_get_glyph_uv_rect(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph); - Rect2 uv = *(Rect2 *)&result; - return uv; -} - -void TextServerGDNative::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_glyph_uv_rect(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph, (const godot_rect2 *)&p_uv_rect); -} - -int TextServerGDNative::font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - ERR_FAIL_COND_V(interface == nullptr, -1); - return interface->font_get_glyph_texture_idx(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph); -} - -void TextServerGDNative::font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_glyph_texture_idx(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_glyph, p_texture_idx); -} - -bool TextServerGDNative::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_get_glyph_contours(data, (godot_rid *)&p_font_rid, p_size, p_index, (godot_packed_vector3_array *)&r_points, (godot_packed_int32_array *)&r_contours, &r_orientation); -} - -Array TextServerGDNative::font_get_kerning_list(RID p_font_rid, int p_size) const { - ERR_FAIL_COND_V(interface == nullptr, Array()); - godot_array result = interface->font_get_kerning_list(data, (godot_rid *)&p_font_rid, p_size); - Array list = *(Array *)&result; - godot_array_destroy(&result); - return list; -} - -void TextServerGDNative::font_clear_kerning_map(RID p_font_rid, int p_size) { - ERR_FAIL_COND(interface == nullptr); - interface->font_clear_kerning_map(data, (godot_rid *)&p_font_rid, p_size); -} - -void TextServerGDNative::font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) { - ERR_FAIL_COND(interface == nullptr); - interface->font_remove_kerning(data, (godot_rid *)&p_font_rid, p_size, (const godot_vector2i *)&p_glyph_pair); -} - -void TextServerGDNative::font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_kerning(data, (godot_rid *)&p_font_rid, p_size, (const godot_vector2i *)&p_glyph_pair, (const godot_vector2 *)&p_kerning); -} - -Vector2 TextServerGDNative::font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const { - ERR_FAIL_COND_V(interface == nullptr, Vector2()); - godot_vector2 result = interface->font_get_kerning(data, (godot_rid *)&p_font_rid, p_size, (const godot_vector2i *)&p_glyph_pair); - Vector2 kern = *(Vector2 *)&result; - return kern; -} - -int32_t TextServerGDNative::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const { - ERR_FAIL_COND_V(interface == nullptr, 0); - return interface->font_get_glyph_index(data, (godot_rid *)&p_font_rid, p_size, p_char, p_variation_selector); -} - -bool TextServerGDNative::font_has_char(RID p_font_rid, char32_t p_char) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_has_char(data, (godot_rid *)&p_font_rid, p_char); -} - -String TextServerGDNative::font_get_supported_chars(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, String()); - godot_string result = interface->font_get_supported_chars(data, (godot_rid *)&p_font_rid); - String chars = *(String *)&result; - godot_string_destroy(&result); - return chars; -} - -void TextServerGDNative::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) { - ERR_FAIL_COND(interface == nullptr); - interface->font_render_range(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_start, p_end); -} - -void TextServerGDNative::font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) { - ERR_FAIL_COND(interface == nullptr); - interface->font_render_glyph(data, (godot_rid *)&p_font_rid, (const godot_vector2i *)&p_size, p_index); -} - -void TextServerGDNative::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - ERR_FAIL_COND(interface == nullptr); - interface->font_draw_glyph(data, (godot_rid *)&p_font_rid, (godot_rid *)&p_canvas, p_size, (const godot_vector2 *)&p_pos, p_index, (const godot_color *)&p_color); -} - -void TextServerGDNative::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - ERR_FAIL_COND(interface == nullptr); - interface->font_draw_glyph_outline(data, (godot_rid *)&p_font_rid, (godot_rid *)&p_canvas, p_size, p_outline_size, (const godot_vector2 *)&p_pos, p_index, (const godot_color *)&p_color); -} - -bool TextServerGDNative::font_is_language_supported(RID p_font_rid, const String &p_language) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_is_language_supported(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_language); -} - -void TextServerGDNative::font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_language_support_override(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_language, p_supported); -} - -bool TextServerGDNative::font_get_language_support_override(RID p_font_rid, const String &p_language) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_get_language_support_override(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_language); -} - -void TextServerGDNative::font_remove_language_support_override(RID p_font_rid, const String &p_language) { - ERR_FAIL_COND(interface == nullptr); - interface->font_remove_language_support_override(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_language); -} - -Vector<String> TextServerGDNative::font_get_language_support_overrides(RID p_font_rid) { - ERR_FAIL_COND_V(interface == nullptr, PackedStringArray()); - godot_packed_string_array result = interface->font_get_language_support_overrides(data, (godot_rid *)&p_font_rid); - PackedStringArray list = *(PackedStringArray *)&result; - godot_packed_string_array_destroy(&result); - return list; -} - -bool TextServerGDNative::font_is_script_supported(RID p_font_rid, const String &p_script) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_is_script_supported(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_script); -} - -void TextServerGDNative::font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_script_support_override(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_script, p_supported); -} - -bool TextServerGDNative::font_get_script_support_override(RID p_font_rid, const String &p_script) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->font_get_script_support_override(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_script); -} - -void TextServerGDNative::font_remove_script_support_override(RID p_font_rid, const String &p_script) { - ERR_FAIL_COND(interface == nullptr); - interface->font_remove_script_support_override(data, (godot_rid *)&p_font_rid, (const godot_string *)&p_script); -} - -Vector<String> TextServerGDNative::font_get_script_support_overrides(RID p_font_rid) { - ERR_FAIL_COND_V(interface == nullptr, PackedStringArray()); - godot_packed_string_array result = interface->font_get_script_support_overrides(data, (godot_rid *)&p_font_rid); - PackedStringArray list = *(PackedStringArray *)&result; - godot_packed_string_array_destroy(&result); - return list; -} - -Dictionary TextServerGDNative::font_supported_feature_list(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, Dictionary()); - godot_dictionary result = interface->font_supported_feature_list(data, (godot_rid *)&p_font_rid); - Dictionary dict = *(Dictionary *)&result; - godot_dictionary_destroy(&result); - return dict; -} - -Dictionary TextServerGDNative::font_supported_variation_list(RID p_font_rid) const { - ERR_FAIL_COND_V(interface == nullptr, Dictionary()); - godot_dictionary result = interface->font_supported_variation_list(data, (godot_rid *)&p_font_rid); - Dictionary dict = *(Dictionary *)&result; - godot_dictionary_destroy(&result); - return dict; -} - -real_t TextServerGDNative::font_get_global_oversampling() const { - ERR_FAIL_COND_V(interface == nullptr, 0.0f); - return interface->font_get_global_oversampling(data); -} - -void TextServerGDNative::font_set_global_oversampling(real_t p_oversampling) { - ERR_FAIL_COND(interface == nullptr); - interface->font_set_global_oversampling(data, p_oversampling); -} - -/*************************************************************************/ -/* Shaped text buffer interface */ -/*************************************************************************/ - -RID TextServerGDNative::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) { - ERR_FAIL_COND_V(interface == nullptr, RID()); - godot_rid result = interface->create_shaped_text(data, (godot_int)p_direction, (godot_int)p_orientation); - RID rid = *(RID *)&result; - return rid; -} - -void TextServerGDNative::shaped_text_clear(RID p_shaped) { - ERR_FAIL_COND(interface == nullptr); - interface->shaped_text_clear(data, (godot_rid *)&p_shaped); -} - -void TextServerGDNative::shaped_text_set_direction(RID p_shaped, TextServer::Direction p_direction) { - ERR_FAIL_COND(interface == nullptr); - interface->shaped_text_set_direction(data, (godot_rid *)&p_shaped, (godot_int)p_direction); -} - -TextServer::Direction TextServerGDNative::shaped_text_get_direction(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, TextServer::DIRECTION_LTR); - return (TextServer::Direction)interface->shaped_text_get_direction(data, (godot_rid *)&p_shaped); -} - -void TextServerGDNative::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) { - ERR_FAIL_COND(interface == nullptr); - interface->shaped_text_set_orientation(data, (godot_rid *)&p_shaped, (godot_int)p_orientation); -} - -TextServer::Orientation TextServerGDNative::shaped_text_get_orientation(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, TextServer::ORIENTATION_HORIZONTAL); - return (TextServer::Orientation)interface->shaped_text_get_orientation(data, (godot_rid *)&p_shaped); -} - -void TextServerGDNative::shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) { - ERR_FAIL_COND(interface == nullptr); - interface->shaped_text_set_bidi_override(data, (godot_rid *)&p_shaped, (const godot_packed_vector2i_array *)&p_override); -} - -void TextServerGDNative::shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) { - ERR_FAIL_COND(interface == nullptr); - interface->shaped_text_set_preserve_invalid(data, (godot_rid *)&p_shaped, p_enabled); -} - -bool TextServerGDNative::shaped_text_get_preserve_invalid(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return (TextServer::Orientation)interface->shaped_text_get_preserve_invalid(data, (godot_rid *)&p_shaped); -} - -void TextServerGDNative::shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) { - ERR_FAIL_COND(interface == nullptr); - interface->shaped_text_set_preserve_control(data, (godot_rid *)&p_shaped, p_enabled); -} - -bool TextServerGDNative::shaped_text_get_preserve_control(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return (TextServer::Orientation)interface->shaped_text_get_preserve_control(data, (godot_rid *)&p_shaped); -} - -bool TextServerGDNative::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->shaped_text_add_string(data, (godot_rid *)&p_shaped, (const godot_string *)&p_text, (const godot_rid **)p_fonts.ptr(), p_size, (const godot_dictionary *)&p_opentype_features, (const godot_string *)&p_language); -} - -bool TextServerGDNative::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->shaped_text_add_object(data, (godot_rid *)&p_shaped, (const godot_variant *)&p_key, (const godot_vector2 *)&p_size, (godot_int)p_inline_align, p_length); -} - -bool TextServerGDNative::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->shaped_text_resize_object(data, (godot_rid *)&p_shaped, (const godot_variant *)&p_key, (const godot_vector2 *)&p_size, (godot_int)p_inline_align); -} - -RID TextServerGDNative::shaped_text_substr(RID p_shaped, int p_start, int p_length) const { - ERR_FAIL_COND_V(interface == nullptr, RID()); - godot_rid result = interface->shaped_text_substr(data, (godot_rid *)&p_shaped, (godot_int)p_start, (godot_int)p_length); - RID rid = *(RID *)&result; - return rid; -} - -RID TextServerGDNative::shaped_text_get_parent(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, RID()); - godot_rid result = interface->shaped_text_get_parent(data, (godot_rid *)&p_shaped); - RID rid = *(RID *)&result; - return rid; -} - -real_t TextServerGDNative::shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t p_jst_flags) { - ERR_FAIL_COND_V(interface == nullptr, 0.f); - return interface->shaped_text_fit_to_width(data, (godot_rid *)&p_shaped, p_width, p_jst_flags); -} - -real_t TextServerGDNative::shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) { - ERR_FAIL_COND_V(interface == nullptr, 0.f); - return interface->shaped_text_tab_align(data, (godot_rid *)&p_shaped, (godot_packed_float32_array *)&p_tab_stops); -} - -bool TextServerGDNative::shaped_text_shape(RID p_shaped) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->shaped_text_shape(data, (godot_rid *)&p_shaped); -} - -bool TextServerGDNative::shaped_text_update_breaks(RID p_shaped) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->shaped_text_update_breaks(data, (godot_rid *)&p_shaped); -} - -bool TextServerGDNative::shaped_text_update_justification_ops(RID p_shaped) { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->shaped_text_update_justification_ops(data, (godot_rid *)&p_shaped); -} - -void TextServerGDNative::shaped_text_overrun_trim_to_width(RID p_shaped_line, real_t p_width, uint8_t p_trim_flags) { - ERR_FAIL_COND(interface == nullptr); - interface->shaped_text_overrun_trim_to_width(data, (godot_rid *)&p_shaped_line, p_width, p_trim_flags); -}; - -bool TextServerGDNative::shaped_text_is_ready(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, false); - return interface->shaped_text_is_ready(data, (godot_rid *)&p_shaped); -} - -Vector<TextServer::Glyph> TextServerGDNative::shaped_text_get_glyphs(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, Vector<TextServer::Glyph>()); - godot_packed_glyph_array result = interface->shaped_text_get_glyphs(data, (godot_rid *)&p_shaped); - Vector<TextServer::Glyph> glyphs = *(Vector<TextServer::Glyph> *)&result; - godot_packed_glyph_array_destroy(&result); - return glyphs; -} - -Vector2i TextServerGDNative::shaped_text_get_range(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, Vector2i()); - godot_vector2i result = interface->shaped_text_get_range(data, (godot_rid *)&p_shaped); - Vector2i range = *(Vector2i *)&result; - return range; -} - -Vector<TextServer::Glyph> TextServerGDNative::shaped_text_sort_logical(RID p_shaped) { - ERR_FAIL_COND_V(interface == nullptr, Vector<TextServer::Glyph>()); - godot_packed_glyph_array result = interface->shaped_text_sort_logical(data, (godot_rid *)&p_shaped); - Vector<TextServer::Glyph> glyphs = *(Vector<TextServer::Glyph> *)&result; - godot_packed_glyph_array_destroy(&result); - return glyphs; -} - -Vector<Vector2i> TextServerGDNative::shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start, bool p_once, uint8_t p_break_flags) const { - ERR_FAIL_COND_V(interface == nullptr, Vector<Vector2i>()); - if (interface->shaped_text_get_line_breaks_adv != nullptr) { - godot_packed_vector2i_array result = interface->shaped_text_get_line_breaks_adv(data, (godot_rid *)&p_shaped, (godot_packed_float32_array *)&p_width, p_start, p_once, p_break_flags); - Vector<Vector2i> breaks = *(Vector<Vector2i> *)&result; - godot_packed_vector2i_array_destroy(&result); - return breaks; - } else { - return TextServer::shaped_text_get_line_breaks_adv(p_shaped, p_width, p_break_flags); - } -} - -Vector<Vector2i> TextServerGDNative::shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t p_break_flags) const { - ERR_FAIL_COND_V(interface == nullptr, Vector<Vector2i>()); - if (interface->shaped_text_get_line_breaks != nullptr) { - godot_packed_vector2i_array result = interface->shaped_text_get_line_breaks(data, (godot_rid *)&p_shaped, p_width, p_start, p_break_flags); - Vector<Vector2i> breaks = *(Vector<Vector2i> *)&result; - godot_packed_vector2i_array_destroy(&result); - return breaks; - } else { - return TextServer::shaped_text_get_line_breaks(p_shaped, p_width, p_break_flags); - } -} - -Vector<Vector2i> TextServerGDNative::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { - ERR_FAIL_COND_V(interface == nullptr, Vector<Vector2i>()); - if (interface->shaped_text_get_word_breaks != nullptr) { - godot_packed_vector2i_array result = interface->shaped_text_get_word_breaks(data, (godot_rid *)&p_shaped, p_grapheme_flags); - Vector<Vector2i> breaks = *(Vector<Vector2i> *)&result; - godot_packed_vector2i_array_destroy(&result); - return breaks; - } else { - return TextServer::shaped_text_get_word_breaks(p_shaped, p_grapheme_flags); - } -} - -Array TextServerGDNative::shaped_text_get_objects(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, Array()); - godot_array result = interface->shaped_text_get_objects(data, (godot_rid *)&p_shaped); - Array rect = *(Array *)&result; - return rect; -} - -Rect2 TextServerGDNative::shaped_text_get_object_rect(RID p_shaped, Variant p_key) const { - ERR_FAIL_COND_V(interface == nullptr, Rect2()); - godot_rect2 result = interface->shaped_text_get_object_rect(data, (godot_rid *)&p_shaped, (const godot_variant *)&p_key); - Rect2 rect = *(Rect2 *)&result; - return rect; -} - -Size2 TextServerGDNative::shaped_text_get_size(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, Size2()); - godot_vector2 result = interface->shaped_text_get_size(data, (godot_rid *)&p_shaped); - Size2 size = *(Size2 *)&result; - return size; -} - -real_t TextServerGDNative::shaped_text_get_ascent(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, 0.f); - return interface->shaped_text_get_ascent(data, (godot_rid *)&p_shaped); -} - -real_t TextServerGDNative::shaped_text_get_descent(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, 0.f); - return interface->shaped_text_get_descent(data, (godot_rid *)&p_shaped); -} - -real_t TextServerGDNative::shaped_text_get_width(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, 0.f); - return interface->shaped_text_get_width(data, (godot_rid *)&p_shaped); -} - -real_t TextServerGDNative::shaped_text_get_underline_position(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, 0.f); - return interface->shaped_text_get_underline_position(data, (godot_rid *)&p_shaped); -} - -real_t TextServerGDNative::shaped_text_get_underline_thickness(RID p_shaped) const { - ERR_FAIL_COND_V(interface == nullptr, 0.f); - return interface->shaped_text_get_underline_thickness(data, (godot_rid *)&p_shaped); -} - -String TextServerGDNative::format_number(const String &p_string, const String &p_language) const { - ERR_FAIL_COND_V(interface == nullptr, String()); - godot_string result = interface->format_number(data, (const godot_string *)&p_string, (const godot_string *)&p_language); - if (interface->format_number == nullptr) { - return p_string; - } - String ret = *(String *)&result; - godot_string_destroy(&result); - return ret; -} - -String TextServerGDNative::parse_number(const String &p_string, const String &p_language) const { - ERR_FAIL_COND_V(interface == nullptr, String()); - if (interface->parse_number == nullptr) { - return p_string; - } - godot_string result = interface->parse_number(data, (const godot_string *)&p_string, (const godot_string *)&p_language); - String ret = *(String *)&result; - godot_string_destroy(&result); - return ret; -} - -String TextServerGDNative::percent_sign(const String &p_language) const { - ERR_FAIL_COND_V(interface == nullptr, String()); - if (interface->percent_sign == nullptr) { - return "%"; - } - godot_string result = interface->percent_sign(data, (const godot_string *)&p_language); - String ret = *(String *)&result; - godot_string_destroy(&result); - return ret; -} - -TextServer *TextServerGDNative::create_func(Error &r_error, void *p_user_data) { - const godot_text_interface_gdnative *interface = (const godot_text_interface_gdnative *)p_user_data; - r_error = OK; - - TextServerGDNative *server = memnew(TextServerGDNative()); - server->interface = interface; - server->data = interface->constructor((godot_object *)server); - - return server; -} - -TextServerGDNative::TextServerGDNative() { - data = nullptr; - interface = nullptr; -} - -TextServerGDNative::~TextServerGDNative() { - if (interface != nullptr) { - interface->destructor(data); - data = nullptr; - interface = nullptr; - } -} - -/*************************************************************************/ -/* GDNative functions */ -/*************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -static_assert(sizeof(godot_glyph) == sizeof(TextServer::Glyph), "Glyph size mismatch"); -static_assert(sizeof(godot_packed_glyph_array) == sizeof(Vector<TextServer::Glyph>), "Vector<Glyph> size mismatch"); - -void GDAPI godot_text_register_interface(const godot_text_interface_gdnative *p_interface, const godot_string *p_name, uint32_t p_features) { - ERR_FAIL_COND(p_interface->version.major != 1); - String name = *(String *)p_name; - TextServerManager::register_create_function(name + "(GDNative)", p_features, TextServerGDNative::create_func, (void *)p_interface); -} - -// Glyph - -void GDAPI godot_glyph_new(godot_glyph *r_dest) { - TextServer::Glyph *dest = (TextServer::Glyph *)r_dest; - *dest = TextServer::Glyph(); -} - -godot_vector2i GDAPI godot_glyph_get_range(const godot_glyph *p_self) { - godot_vector2i dest; - Vector2i *d = (Vector2i *)&dest; - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - d->x = self->start; - d->y = self->end; - return dest; -} - -void GDAPI godot_glyph_set_range(godot_glyph *p_self, const godot_vector2i *p_range) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - const Vector2i *range = (const Vector2i *)p_range; - self->start = range->x; - self->end = range->y; -} - -godot_int GDAPI godot_glyph_get_count(const godot_glyph *p_self) { - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - return self->count; -} - -void GDAPI godot_glyph_set_count(godot_glyph *p_self, godot_int p_count) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - self->count = p_count; -} - -godot_int GDAPI godot_glyph_get_repeat(const godot_glyph *p_self) { - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - return self->repeat; -} - -void GDAPI godot_glyph_set_repeat(godot_glyph *p_self, godot_int p_repeat) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - self->repeat = p_repeat; -} - -godot_int GDAPI godot_glyph_get_flags(const godot_glyph *p_self) { - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - return self->flags; -} - -void GDAPI godot_glyph_set_flags(godot_glyph *p_self, godot_int p_flags) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - self->flags = p_flags; -} - -godot_vector2 GDAPI godot_glyph_get_offset(const godot_glyph *p_self) { - godot_vector2 dest; - Vector2 *d = (Vector2 *)&dest; - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - d->x = self->x_off; - d->y = self->y_off; - return dest; -} - -void GDAPI godot_glyph_set_offset(godot_glyph *p_self, const godot_vector2 *p_offset) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - const Vector2 *offset = (const Vector2 *)p_offset; - self->x_off = offset->x; - self->y_off = offset->y; -} - -godot_real_t GDAPI godot_glyph_get_advance(const godot_glyph *p_self) { - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - return self->advance; -} - -void GDAPI godot_glyph_set_advance(godot_glyph *p_self, godot_real_t p_advance) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - self->advance = p_advance; -} - -godot_rid GDAPI godot_glyph_get_font(const godot_glyph *p_self) { - godot_rid dest; - RID *d = (RID *)&dest; - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - *d = self->font_rid; - return dest; -} - -void GDAPI godot_glyph_set_font(godot_glyph *p_self, godot_rid *p_font) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - const RID *font = (const RID *)p_font; - self->font_rid = *font; -} - -godot_int GDAPI godot_glyph_get_font_size(const godot_glyph *p_self) { - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - return self->font_size; -} - -void GDAPI godot_glyph_set_font_size(godot_glyph *p_self, godot_int p_size) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - self->font_size = p_size; -} - -godot_int GDAPI godot_glyph_get_index(const godot_glyph *p_self) { - const TextServer::Glyph *self = (const TextServer::Glyph *)p_self; - return self->index; -} - -void GDAPI godot_glyph_set_index(godot_glyph *p_self, godot_int p_index) { - TextServer::Glyph *self = (TextServer::Glyph *)p_self; - self->index = p_index; -} - -// GlyphArray - -void GDAPI godot_packed_glyph_array_new(godot_packed_glyph_array *r_dest) { - Vector<TextServer::Glyph> *dest = (Vector<TextServer::Glyph> *)r_dest; - memnew_placement(dest, Vector<TextServer::Glyph>); -} - -void GDAPI godot_packed_glyph_array_new_copy(godot_packed_glyph_array *r_dest, const godot_packed_glyph_array *p_src) { - Vector<TextServer::Glyph> *dest = (Vector<TextServer::Glyph> *)r_dest; - const Vector<TextServer::Glyph> *src = (const Vector<TextServer::Glyph> *)p_src; - memnew_placement(dest, Vector<TextServer::Glyph>(*src)); -} - -const godot_glyph GDAPI *godot_packed_glyph_array_ptr(const godot_packed_glyph_array *p_self) { - const Vector<TextServer::Glyph> *self = (const Vector<TextServer::Glyph> *)p_self; - return (const godot_glyph *)self->ptr(); -} - -godot_glyph GDAPI *godot_packed_glyph_array_ptrw(godot_packed_glyph_array *p_self) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - return (godot_glyph *)self->ptrw(); -} - -void GDAPI godot_packed_glyph_array_append(godot_packed_glyph_array *p_self, const godot_glyph *p_data) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - TextServer::Glyph &s = *(TextServer::Glyph *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_glyph_array_append_array(godot_packed_glyph_array *p_self, const godot_packed_glyph_array *p_array) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - Vector<TextServer::Glyph> *array = (Vector<TextServer::Glyph> *)p_array; - self->append_array(*array); -} - -godot_error GDAPI godot_packed_glyph_array_insert(godot_packed_glyph_array *p_self, const godot_int p_idx, const godot_glyph *p_data) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - TextServer::Glyph &s = *(TextServer::Glyph *)p_data; - return (godot_error)self->insert(p_idx, s); -} - -godot_bool GDAPI godot_packed_glyph_array_has(godot_packed_glyph_array *p_self, const godot_glyph *p_value) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - TextServer::Glyph &v = *(TextServer::Glyph *)p_value; - return (godot_bool)self->has(v); -} - -void GDAPI godot_packed_glyph_array_sort(godot_packed_glyph_array *p_self) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - self->sort(); -} - -void GDAPI godot_packed_glyph_array_reverse(godot_packed_glyph_array *p_self) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - self->reverse(); -} - -void GDAPI godot_packed_glyph_array_push_back(godot_packed_glyph_array *p_self, const godot_glyph *p_data) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - TextServer::Glyph &s = *(TextServer::Glyph *)p_data; - self->push_back(s); -} - -void GDAPI godot_packed_glyph_array_remove(godot_packed_glyph_array *p_self, const godot_int p_idx) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - self->remove(p_idx); -} - -void GDAPI godot_packed_glyph_array_resize(godot_packed_glyph_array *p_self, const godot_int p_size) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - self->resize(p_size); -} - -void GDAPI godot_packed_glyph_array_set(godot_packed_glyph_array *p_self, const godot_int p_idx, const godot_glyph *p_data) { - Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self; - TextServer::Glyph &s = *(TextServer::Glyph *)p_data; - self->set(p_idx, s); -} - -godot_glyph GDAPI godot_packed_glyph_array_get(const godot_packed_glyph_array *p_self, const godot_int p_idx) { - const Vector<TextServer::Glyph> *self = (const Vector<TextServer::Glyph> *)p_self; - godot_glyph v; - TextServer::Glyph *s = (TextServer::Glyph *)&v; - *s = self->get(p_idx); - return v; -} - -godot_int GDAPI godot_packed_glyph_array_size(const godot_packed_glyph_array *p_self) { - const Vector<TextServer::Glyph> *self = (const Vector<TextServer::Glyph> *)p_self; - return self->size(); -} - -godot_bool GDAPI godot_packed_glyph_array_is_empty(const godot_packed_glyph_array *p_self) { - const Vector<TextServer::Glyph> *self = (const Vector<TextServer::Glyph> *)p_self; - return self->is_empty(); -} - -void GDAPI godot_packed_glyph_array_destroy(godot_packed_glyph_array *p_self) { - ((Vector<TextServer::Glyph> *)p_self)->~Vector(); -} - -#ifdef __cplusplus -} -#endif diff --git a/modules/gdnative/text/text_server_gdnative.h b/modules/gdnative/text/text_server_gdnative.h deleted file mode 100644 index f081637e23..0000000000 --- a/modules/gdnative/text/text_server_gdnative.h +++ /dev/null @@ -1,254 +0,0 @@ -/*************************************************************************/ -/* text_server_gdnative.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef TEXT_SERVER_GDNATIVE_H -#define TEXT_SERVER_GDNATIVE_H - -#include "modules/gdnative/gdnative.h" - -#include "servers/text_server.h" - -class TextServerGDNative : public TextServer { - GDCLASS(TextServerGDNative, TextServer); - - const godot_text_interface_gdnative *interface = nullptr; - void *data = nullptr; - -protected: - static void _bind_methods(){}; - -public: - virtual bool has_feature(Feature p_feature) override; - virtual String get_name() const override; - - virtual void free(RID p_rid) override; - virtual bool has(RID p_rid) override; - virtual bool load_support_data(const String &p_filename) override; - -#ifdef TOOLS_ENABLED - virtual String get_support_data_filename() override; - virtual String get_support_data_info() override; - virtual bool save_support_data(const String &p_filename) override; -#endif - - virtual bool is_locale_right_to_left(const String &p_locale) override; - - virtual int32_t name_to_tag(const String &p_name) const override; - virtual String tag_to_name(int32_t p_tag) const override; - - /* Font interface */ - virtual RID create_font() override; - - virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override; - virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override; - - virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override; - virtual bool font_is_antialiased(RID p_font_rid) const override; - - virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) override; - virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const override; - - virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) override; - virtual int font_get_msdf_pixel_range(RID p_font_rid) const override; - - virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) override; - virtual int font_get_msdf_size(RID p_font_rid) const override; - - virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) override; - virtual int font_get_fixed_size(RID p_font_rid) const override; - - virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) override; - virtual bool font_is_force_autohinter(RID p_font_rid) const override; - - virtual void font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) override; - virtual TextServer::Hinting font_get_hinting(RID p_font_rid) const override; - - virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; - virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; - - virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) override; - virtual real_t font_get_oversampling(RID p_font_rid) const override; - - virtual Array font_get_size_cache_list(RID p_font_rid) const override; - virtual void font_clear_size_cache(RID p_font_rid) override; - virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override; - - virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) override; - virtual real_t font_get_ascent(RID p_font_rid, int p_size) const override; - - virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) override; - virtual real_t font_get_descent(RID p_font_rid, int p_size) const override; - - virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) override; - virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const override; - - virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) override; - virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const override; - - virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) override; - virtual real_t font_get_scale(RID p_font_rid, int p_size) const override; - - virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override; - virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override; - - virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const override; - virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) override; - virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) override; - - virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) override; - virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override; - - virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) override; - virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override; - - virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const override; - virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) override; - virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) override; - - virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) override; - - virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) override; - - virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) override; - - virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) override; - - virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override; - - virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override; - - virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override; - virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override; - virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) override; - - virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override; - virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const override; - - virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector = 0) const override; - - virtual bool font_has_char(RID p_font_rid, char32_t p_char) const override; - virtual String font_get_supported_chars(RID p_font_rid) const override; - - virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) override; - virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) override; - - virtual void font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override; - virtual void font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override; - - virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const override; - virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) override; - virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) override; - virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) override; - virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) override; - - virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const override; - virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) override; - virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) override; - virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override; - virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override; - - virtual Dictionary font_supported_feature_list(RID p_font_rid) const override; - virtual Dictionary font_supported_variation_list(RID p_font_rid) const override; - - virtual real_t font_get_global_oversampling() const override; - virtual void font_set_global_oversampling(real_t p_oversampling) override; - - /* Shaped text buffer interface */ - - virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; - - virtual void shaped_text_clear(RID p_shaped) override; - - virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; - virtual Direction shaped_text_get_direction(RID p_shaped) const override; - - virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) override; - - virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; - virtual Orientation shaped_text_get_orientation(RID p_shaped) const override; - - virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) override; - virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const override; - - virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override; - virtual bool shaped_text_get_preserve_control(RID p_shaped) const override; - - virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override; - virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override; - virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override; - - virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override; - virtual RID shaped_text_get_parent(RID p_shaped) const override; - - virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; - virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) override; - - virtual bool shaped_text_shape(RID p_shaped) override; - virtual bool shaped_text_update_breaks(RID p_shaped) override; - virtual bool shaped_text_update_justification_ops(RID p_shaped) override; - - virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) override; - - virtual bool shaped_text_is_ready(RID p_shaped) const override; - - virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override; - - virtual Vector2i shaped_text_get_range(RID p_shaped) const override; - - virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) override; - virtual Vector<Vector2i> shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start = 0, bool p_once = true, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; - virtual Vector<Vector2i> shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start = 0, uint8_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; - virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override; - virtual Array shaped_text_get_objects(RID p_shaped) const override; - virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override; - - virtual Size2 shaped_text_get_size(RID p_shaped) const override; - virtual real_t shaped_text_get_ascent(RID p_shaped) const override; - virtual real_t shaped_text_get_descent(RID p_shaped) const override; - virtual real_t shaped_text_get_width(RID p_shaped) const override; - virtual real_t shaped_text_get_underline_position(RID p_shaped) const override; - virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const override; - - virtual String format_number(const String &p_string, const String &p_language = "") const override; - virtual String parse_number(const String &p_string, const String &p_language = "") const override; - virtual String percent_sign(const String &p_language = "") const override; - - static TextServer *create_func(Error &r_error, void *p_user_data); - - TextServerGDNative(); - ~TextServerGDNative(); -}; - -#endif // TEXT_SERVER_GDNATIVE_H diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 51b3452a3a..631ee4d895 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -176,7 +176,8 @@ <method name="range" qualifiers="vararg"> <return type="Array" /> <description> - Returns an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial, final-1, increment). + Returns an array with the given range. Range can be 1 argument [code]N[/code] (0 to [code]N[/code] - 1), two arguments ([code]initial[/code], [code]final - 1[/code]) or three arguments ([code]initial[/code], [code]final - 1[/code], [code]increment[/code]). Returns an empty array if the range isn't valid (e.g. [code]range(2, 5, -1)[/code] or [code]range(5, 5, 1)[/code]). + Returns an array with the given range. [code]range()[/code] can have 1 argument N ([code]0[/code] to [code]N - 1[/code]), two arguments ([code]initial[/code], [code]final - 1[/code]) or three arguments ([code]initial[/code], [code]final - 1[/code], [code]increment[/code]). [code]increment[/code] can be negative. If [code]increment[/code] is negative, [code]final - 1[/code] will become [code]final + 1[/code]. Also, the initial value must be greater than the final value for the loop to run. [codeblock] print(range(4)) print(range(2, 5)) @@ -188,6 +189,20 @@ [2, 3, 4] [0, 2, 4] [/codeblock] + To iterate over an [Array] backwards, use: + [codeblock] + var array = [3, 6, 9] + var i := array.size() - 1 + while i >= 0: + print(array[i]) + i -= 1 + [/codeblock] + Output: + [codeblock] + 9 + 6 + 3 + [/codeblock] </description> </method> <method name="str" qualifiers="vararg"> diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index bc8801b8b9..2bae838543 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -122,8 +122,8 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco instance->owner_id = p_owner->get_instance_id(); #ifdef DEBUG_ENABLED //needed for hot reloading - for (Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) { - instance->member_indices_cache[E->key()] = E->get().index; + for (const KeyValue<StringName, MemberInfo> &E : member_indices) { + instance->member_indices_cache[E.key] = E.value.index; } #endif instance->owner->set_script_instance(instance); @@ -253,10 +253,10 @@ void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { void GDScript::_get_script_method_list(List<MethodInfo> *r_list, bool p_include_base) const { const GDScript *current = this; while (current) { - for (const Map<StringName, GDScriptFunction *>::Element *E = current->member_functions.front(); E; E = E->next()) { - GDScriptFunction *func = E->get(); + for (const KeyValue<StringName, GDScriptFunction *> &E : current->member_functions) { + GDScriptFunction *func = E.value; MethodInfo mi; - mi.name = E->key(); + mi.name = E.key; for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arginfo = func->get_argument_type(i); #ifdef TOOLS_ENABLED @@ -286,11 +286,11 @@ void GDScript::_get_script_property_list(List<PropertyInfo> *r_list, bool p_incl while (sptr) { Vector<_GDScriptMemberSort> msort; - for (Map<StringName, PropertyInfo>::Element *E = sptr->member_info.front(); E; E = E->next()) { + for (const KeyValue<StringName, PropertyInfo> &E : sptr->member_info) { _GDScriptMemberSort ms; - ERR_CONTINUE(!sptr->member_indices.has(E->key())); - ms.index = sptr->member_indices[E->key()].index; - ms.name = E->key(); + ERR_CONTINUE(!sptr->member_indices.has(E.key)); + ms.index = sptr->member_indices[E.key].index; + ms.name = E.key; msort.push_back(ms); } @@ -412,8 +412,8 @@ void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<Pro base_cache->_update_exports_values(values, propnames); } - for (Map<StringName, Variant>::Element *E = member_default_values_cache.front(); E; E = E->next()) { - values[E->key()] = E->get(); + for (const KeyValue<StringName, Variant> &E : member_default_values_cache) { + values[E.key] = E.value; } for (const PropertyInfo &E : members_cache) { @@ -471,9 +471,9 @@ void GDScript::_update_doc() { doc.description = doc_description; doc.tutorials = doc_tutorials; - for (Map<String, DocData::EnumDoc>::Element *E = doc_enums.front(); E; E = E->next()) { - if (E->value().description != "") { - doc.enums[E->key()] = E->value().description; + for (const KeyValue<String, DocData::EnumDoc> &E : doc_enums) { + if (E.value.description != "") { + doc.enums[E.key] = E.value.description; } } @@ -552,29 +552,29 @@ void GDScript::_update_doc() { doc.signals.push_back(signal_doc); } - for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { - if (subclasses.has(E->key())) { + for (const KeyValue<StringName, Variant> &E : constants) { + if (subclasses.has(E.key)) { continue; } // Enums. bool is_enum = false; - if (E->value().get_type() == Variant::DICTIONARY) { - if (doc_enums.has(E->key())) { + if (E.value.get_type() == Variant::DICTIONARY) { + if (doc_enums.has(E.key)) { is_enum = true; - for (int i = 0; i < doc_enums[E->key()].values.size(); i++) { - doc_enums[E->key()].values.write[i].enumeration = E->key(); - doc.constants.push_back(doc_enums[E->key()].values[i]); + for (int i = 0; i < doc_enums[E.key].values.size(); i++) { + doc_enums[E.key].values.write[i].enumeration = E.key; + doc.constants.push_back(doc_enums[E.key].values[i]); } } } if (!is_enum && doc_enums.has("@unnamed_enums")) { for (int i = 0; i < doc_enums["@unnamed_enums"].values.size(); i++) { - if (E->key() == doc_enums["@unnamed_enums"].values[i].name) { + if (E.key == doc_enums["@unnamed_enums"].values[i].name) { is_enum = true; DocData::ConstantDoc constant_doc; constant_doc.enumeration = "@unnamed_enums"; - DocData::constant_doc_from_variant(constant_doc, E->key(), E->value(), doc_enums["@unnamed_enums"].values[i].description); + DocData::constant_doc_from_variant(constant_doc, E.key, E.value, doc_enums["@unnamed_enums"].values[i].description); doc.constants.push_back(constant_doc); break; } @@ -583,16 +583,16 @@ void GDScript::_update_doc() { if (!is_enum) { DocData::ConstantDoc constant_doc; String doc_description; - if (doc_constants.has(E->key())) { - doc_description = doc_constants[E->key()]; + if (doc_constants.has(E.key)) { + doc_description = doc_constants[E.key]; } - DocData::constant_doc_from_variant(constant_doc, E->key(), E->value(), doc_description); + DocData::constant_doc_from_variant(constant_doc, E.key, E.value, doc_description); doc.constants.push_back(constant_doc); } } - for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { - E->get()->_update_doc(); + for (KeyValue<StringName, Ref<GDScript>> &E : subclasses) { + E.value->_update_doc(); } _add_doc(doc); @@ -784,8 +784,8 @@ void GDScript::update_exports() { void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) { p_sc->path = p_path; - for (Map<StringName, Ref<GDScript>>::Element *E = p_sc->subclasses.front(); E; E = E->next()) { - _set_subclass_path(E->get(), p_path); + for (KeyValue<StringName, Ref<GDScript>> &E : p_sc->subclasses) { + _set_subclass_path(E.value, p_path); } } @@ -886,8 +886,8 @@ Error GDScript::reload(bool p_keep_state) { valid = true; - for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { - _set_subclass_path(E->get(), path); + for (KeyValue<StringName, Ref<GDScript>> &E : subclasses) { + _set_subclass_path(E.value, path); } _init_rpc_methods_properties(); @@ -901,8 +901,8 @@ ScriptLanguage *GDScript::get_language() const { void GDScript::get_constants(Map<StringName, Variant> *p_constants) { if (p_constants) { - for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { - (*p_constants)[E->key()] = E->value(); + for (const KeyValue<StringName, Variant> &E : constants) { + (*p_constants)[E.key] = E.value; } } } @@ -1032,9 +1032,9 @@ const Map<StringName, GDScriptFunction *> &GDScript::debug_get_member_functions( } StringName GDScript::debug_get_member_by_index(int p_idx) const { - for (const Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) { - if (E->get().index == p_idx) { - return E->key(); + for (const KeyValue<StringName, MemberInfo> &E : member_indices) { + if (E.value.index == p_idx) { + return E.key; } } @@ -1079,12 +1079,12 @@ bool GDScript::has_script_signal(const StringName &p_signal) const { } void GDScript::_get_script_signal_list(List<MethodInfo> *r_list, bool p_include_base) const { - for (const Map<StringName, Vector<StringName>>::Element *E = _signals.front(); E; E = E->next()) { + for (const KeyValue<StringName, Vector<StringName>> &E : _signals) { MethodInfo mi; - mi.name = E->key(); - for (int i = 0; i < E->get().size(); i++) { + mi.name = E.key; + for (int i = 0; i < E.value.size(); i++) { PropertyInfo arg; - arg.name = E->get()[i]; + arg.name = E.value[i]; mi.arguments.push_back(arg); } r_list->push_back(mi); @@ -1142,11 +1142,11 @@ void GDScript::_save_orphaned_subclasses() { }; Vector<ClassRefWithName> weak_subclasses; // collect subclasses ObjectID and name - for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) { - E->get()->_owner = nullptr; //bye, you are no longer owned cause I died + for (KeyValue<StringName, Ref<GDScript>> &E : subclasses) { + E.value->_owner = nullptr; //bye, you are no longer owned cause I died ClassRefWithName subclass; - subclass.id = E->get()->get_instance_id(); - subclass.fully_qualified_name = E->get()->fully_qualified_name; + subclass.id = E.value->get_instance_id(); + subclass.fully_qualified_name = E.value->fully_qualified_name; weak_subclasses.push_back(subclass); } @@ -1178,10 +1178,10 @@ void GDScript::_init_rpc_methods_properties() { Map<StringName, Ref<GDScript>>::Element *sub_E = subclasses.front(); while (cscript) { // RPC Methods - for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) { - Multiplayer::RPCConfig config = E->get()->get_rpc_config(); + for (KeyValue<StringName, GDScriptFunction *> &E : cscript->member_functions) { + Multiplayer::RPCConfig config = E.value->get_rpc_config(); if (config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) { - config.name = E->get()->get_name(); + config.name = E.value->get_name(); if (rpc_functions.find(config) == -1) { rpc_functions.push_back(config); } @@ -1215,8 +1215,8 @@ GDScript::~GDScript() { } } - for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<StringName, GDScriptFunction *> &E : member_functions) { + memdelete(E.value); } if (GDScriptCache::singleton) { // Cache may have been already destroyed at engine shutdown. @@ -1442,11 +1442,11 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const //instance a fake script for editing the values Vector<_GDScriptMemberSort> msort; - for (Map<StringName, PropertyInfo>::Element *F = sptr->member_info.front(); F; F = F->next()) { + for (const KeyValue<StringName, PropertyInfo> &F : sptr->member_info) { _GDScriptMemberSort ms; - ERR_CONTINUE(!sptr->member_indices.has(F->key())); - ms.index = sptr->member_indices[F->key()].index; - ms.name = F->key(); + ERR_CONTINUE(!sptr->member_indices.has(F.key)); + ms.index = sptr->member_indices[F.key].index; + ms.name = F.key; msort.push_back(ms); } @@ -1467,11 +1467,11 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const { const GDScript *sptr = script.ptr(); while (sptr) { - for (Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.front(); E; E = E->next()) { + for (const KeyValue<StringName, GDScriptFunction *> &E : sptr->member_functions) { MethodInfo mi; - mi.name = E->key(); + mi.name = E.key; mi.flags |= METHOD_FLAG_FROM_SCRIPT; - for (int i = 0; i < E->get()->get_argument_count(); i++) { + for (int i = 0; i < E.value->get_argument_count(); i++) { mi.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i))); } p_list->push_back(mi); @@ -1569,10 +1569,10 @@ void GDScriptInstance::reload_members() { new_members.resize(script->member_indices.size()); //pass the values to the new indices - for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) { - if (member_indices_cache.has(E->key())) { - Variant value = members[member_indices_cache[E->key()]]; - new_members.write[E->get().index] = value; + for (KeyValue<StringName, GDScript::MemberInfo> &E : script->member_indices) { + if (member_indices_cache.has(E.key)) { + Variant value = members[member_indices_cache[E.key]]; + new_members.write[E.value.index] = value; } } @@ -1581,8 +1581,8 @@ void GDScriptInstance::reload_members() { //pass the values to the new indices member_indices_cache.clear(); - for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) { - member_indices_cache[E->key()] = E->get().index; + for (const KeyValue<StringName, GDScript::MemberInfo> &E : script->member_indices) { + member_indices_cache[E.key] = E.value.index; } #endif @@ -1890,21 +1890,21 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so #endif - for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = script->pending_reload_state.front(); F; F = F->next()) { - map[F->key()] = F->get(); //pending to reload, use this one instead + for (const KeyValue<ObjectID, List<Pair<StringName, Variant>>> &F : script->pending_reload_state) { + map[F.key] = F.value; //pending to reload, use this one instead } } } - for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>>::Element *E = to_reload.front(); E; E = E->next()) { - Ref<GDScript> scr = E->key(); + for (KeyValue<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>> &E : to_reload) { + Ref<GDScript> scr = E.key; scr->reload(p_soft_reload); //restore state if saved - for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get().front(); F; F = F->next()) { - List<Pair<StringName, Variant>> &saved_state = F->get(); + for (KeyValue<ObjectID, List<Pair<StringName, Variant>>> &F : E.value) { + List<Pair<StringName, Variant>> &saved_state = F.value; - Object *obj = ObjectDB::get_instance(F->key()); + Object *obj = ObjectDB::get_instance(F.key); if (!obj) { continue; } @@ -2210,15 +2210,15 @@ GDScriptLanguage::~GDScriptLanguage() { // is not the same as before). script->reference(); - for (Map<StringName, GDScriptFunction *>::Element *E = script->member_functions.front(); E; E = E->next()) { - GDScriptFunction *func = E->get(); + for (KeyValue<StringName, GDScriptFunction *> &E : script->member_functions) { + GDScriptFunction *func = E.value; for (int i = 0; i < func->argument_types.size(); i++) { func->argument_types.write[i].script_type_ref = Ref<Script>(); } func->return_type.script_type_ref = Ref<Script>(); } - for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) { - E->get().data_type.script_type_ref = Ref<Script>(); + for (KeyValue<StringName, GDScript::MemberInfo> &E : script->member_indices) { + E.value.data_type.script_type_ref = Ref<Script>(); } s = s->next(); diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 23e88ae059..c35af9ca5b 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -175,6 +175,11 @@ Error GDScriptAnalyzer::check_native_member_name_conflict(const StringName &p_me return ERR_PARSE_ERROR; } + if (GDScriptParser::get_builtin_type(p_member_name) != Variant::VARIANT_MAX) { + push_error(vformat(R"(The member "%s" cannot have the same name as a builtin type.)", p_member_name), p_member_node); + return ERR_PARSE_ERROR; + } + return OK; } @@ -2265,10 +2270,10 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa if (get_function_signature(p_call, base_type, p_call->function_name, return_type, par_types, default_arg_count, is_static, is_vararg)) { // If the function require typed arrays we must make literals be typed. - for (Map<int, GDScriptParser::ArrayNode *>::Element *E = arrays.front(); E; E = E->next()) { - int index = E->key(); + for (const KeyValue<int, GDScriptParser::ArrayNode *> &E : arrays) { + int index = E.key; if (index < par_types.size() && par_types[index].has_container_element_type()) { - update_array_literal_element_type(par_types[index], E->get()); + update_array_literal_element_type(par_types[index], E.value); } } validate_call_arg(par_types, default_arg_count, is_vararg, p_call); @@ -2503,7 +2508,10 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod result.enum_type = name; p_identifier->set_datatype(result); } else { - push_error(vformat(R"(Cannot find value "%s" in "%s".)", name, base.to_string()), p_identifier); + // Consider as a Dictionary + GDScriptParser::DataType dummy; + dummy.kind = GDScriptParser::DataType::VARIANT; + p_identifier->set_datatype(dummy); } } else { push_error(R"(Cannot get property from enum value.)", p_identifier); @@ -3676,6 +3684,11 @@ bool GDScriptAnalyzer::is_type_compatible(const GDScriptParser::DataType &p_targ if (p_source.kind == GDScriptParser::DataType::BUILTIN && p_source.builtin_type == Variant::INT) { return true; } + if (p_source.kind == GDScriptParser::DataType::ENUM) { + if (p_source.native_type == p_target.native_type) { + return true; + } + } if (p_source.kind == GDScriptParser::DataType::ENUM_VALUE) { if (p_source.native_type == p_target.native_type && p_target.enum_values.has(p_source.enum_type)) { return true; diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 1127488db8..b8300cd872 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -209,8 +209,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { if (name_map.size()) { function->global_names.resize(name_map.size()); function->_global_names_ptr = &function->global_names[0]; - for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) { - function->global_names.write[E->get()] = E->key(); + for (const KeyValue<StringName, int> &E : name_map) { + function->global_names.write[E.value] = E.key; } function->_global_names_count = function->global_names.size(); @@ -241,8 +241,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->operator_funcs.resize(operator_func_map.size()); function->_operator_funcs_count = function->operator_funcs.size(); function->_operator_funcs_ptr = function->operator_funcs.ptr(); - for (const Map<Variant::ValidatedOperatorEvaluator, int>::Element *E = operator_func_map.front(); E; E = E->next()) { - function->operator_funcs.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedOperatorEvaluator, int> &E : operator_func_map) { + function->operator_funcs.write[E.value] = E.key; } } else { function->_operator_funcs_count = 0; @@ -253,8 +253,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->setters.resize(setters_map.size()); function->_setters_count = function->setters.size(); function->_setters_ptr = function->setters.ptr(); - for (const Map<Variant::ValidatedSetter, int>::Element *E = setters_map.front(); E; E = E->next()) { - function->setters.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedSetter, int> &E : setters_map) { + function->setters.write[E.value] = E.key; } } else { function->_setters_count = 0; @@ -265,8 +265,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->getters.resize(getters_map.size()); function->_getters_count = function->getters.size(); function->_getters_ptr = function->getters.ptr(); - for (const Map<Variant::ValidatedGetter, int>::Element *E = getters_map.front(); E; E = E->next()) { - function->getters.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedGetter, int> &E : getters_map) { + function->getters.write[E.value] = E.key; } } else { function->_getters_count = 0; @@ -277,8 +277,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->keyed_setters.resize(keyed_setters_map.size()); function->_keyed_setters_count = function->keyed_setters.size(); function->_keyed_setters_ptr = function->keyed_setters.ptr(); - for (const Map<Variant::ValidatedKeyedSetter, int>::Element *E = keyed_setters_map.front(); E; E = E->next()) { - function->keyed_setters.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedKeyedSetter, int> &E : keyed_setters_map) { + function->keyed_setters.write[E.value] = E.key; } } else { function->_keyed_setters_count = 0; @@ -289,8 +289,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->keyed_getters.resize(keyed_getters_map.size()); function->_keyed_getters_count = function->keyed_getters.size(); function->_keyed_getters_ptr = function->keyed_getters.ptr(); - for (const Map<Variant::ValidatedKeyedGetter, int>::Element *E = keyed_getters_map.front(); E; E = E->next()) { - function->keyed_getters.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedKeyedGetter, int> &E : keyed_getters_map) { + function->keyed_getters.write[E.value] = E.key; } } else { function->_keyed_getters_count = 0; @@ -301,8 +301,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->indexed_setters.resize(indexed_setters_map.size()); function->_indexed_setters_count = function->indexed_setters.size(); function->_indexed_setters_ptr = function->indexed_setters.ptr(); - for (const Map<Variant::ValidatedIndexedSetter, int>::Element *E = indexed_setters_map.front(); E; E = E->next()) { - function->indexed_setters.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedIndexedSetter, int> &E : indexed_setters_map) { + function->indexed_setters.write[E.value] = E.key; } } else { function->_indexed_setters_count = 0; @@ -313,8 +313,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->indexed_getters.resize(indexed_getters_map.size()); function->_indexed_getters_count = function->indexed_getters.size(); function->_indexed_getters_ptr = function->indexed_getters.ptr(); - for (const Map<Variant::ValidatedIndexedGetter, int>::Element *E = indexed_getters_map.front(); E; E = E->next()) { - function->indexed_getters.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedIndexedGetter, int> &E : indexed_getters_map) { + function->indexed_getters.write[E.value] = E.key; } } else { function->_indexed_getters_count = 0; @@ -325,8 +325,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->builtin_methods.resize(builtin_method_map.size()); function->_builtin_methods_ptr = function->builtin_methods.ptr(); function->_builtin_methods_count = builtin_method_map.size(); - for (const Map<Variant::ValidatedBuiltInMethod, int>::Element *E = builtin_method_map.front(); E; E = E->next()) { - function->builtin_methods.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedBuiltInMethod, int> &E : builtin_method_map) { + function->builtin_methods.write[E.value] = E.key; } } else { function->_builtin_methods_ptr = nullptr; @@ -337,8 +337,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->constructors.resize(constructors_map.size()); function->_constructors_ptr = function->constructors.ptr(); function->_constructors_count = constructors_map.size(); - for (const Map<Variant::ValidatedConstructor, int>::Element *E = constructors_map.front(); E; E = E->next()) { - function->constructors.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedConstructor, int> &E : constructors_map) { + function->constructors.write[E.value] = E.key; } } else { function->_constructors_ptr = nullptr; @@ -349,8 +349,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->utilities.resize(utilities_map.size()); function->_utilities_ptr = function->utilities.ptr(); function->_utilities_count = utilities_map.size(); - for (const Map<Variant::ValidatedUtilityFunction, int>::Element *E = utilities_map.front(); E; E = E->next()) { - function->utilities.write[E->get()] = E->key(); + for (const KeyValue<Variant::ValidatedUtilityFunction, int> &E : utilities_map) { + function->utilities.write[E.value] = E.key; } } else { function->_utilities_ptr = nullptr; @@ -361,8 +361,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->gds_utilities.resize(gds_utilities_map.size()); function->_gds_utilities_ptr = function->gds_utilities.ptr(); function->_gds_utilities_count = gds_utilities_map.size(); - for (const Map<GDScriptUtilityFunctions::FunctionPtr, int>::Element *E = gds_utilities_map.front(); E; E = E->next()) { - function->gds_utilities.write[E->get()] = E->key(); + for (const KeyValue<GDScriptUtilityFunctions::FunctionPtr, int> &E : gds_utilities_map) { + function->gds_utilities.write[E.value] = E.key; } } else { function->_gds_utilities_ptr = nullptr; @@ -373,8 +373,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->methods.resize(method_bind_map.size()); function->_methods_ptr = function->methods.ptrw(); function->_methods_count = method_bind_map.size(); - for (const Map<MethodBind *, int>::Element *E = method_bind_map.front(); E; E = E->next()) { - function->methods.write[E->get()] = E->key(); + for (const KeyValue<MethodBind *, int> &E : method_bind_map) { + function->methods.write[E.value] = E.key; } } else { function->_methods_ptr = nullptr; @@ -385,8 +385,8 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->lambdas.resize(lambdas_map.size()); function->_lambdas_ptr = function->lambdas.ptrw(); function->_lambdas_count = lambdas_map.size(); - for (const Map<GDScriptFunction *, int>::Element *E = lambdas_map.front(); E; E = E->next()) { - function->lambdas.write[E->get()] = E->key(); + for (const KeyValue<GDScriptFunction *, int> &E : lambdas_map) { + function->lambdas.write[E.value] = E.key; } } else { function->_lambdas_ptr = nullptr; diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index dcc11ebdce..fbbf5802fd 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -153,12 +153,12 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator { #endif locals.resize(current_locals); if (debug_stack) { - for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) { + for (const KeyValue<StringName, int> &E : block_identifiers) { GDScriptFunction::StackDebug sd; sd.added = false; - sd.identifier = E->key(); + sd.identifier = E.key; sd.line = current_line; - sd.pos = E->get(); + sd.pos = E.value; stack_debug.push_back(sd); } block_identifiers = block_identifier_stack.back()->get(); diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index a8aef84db3..2c02291795 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1071,19 +1071,25 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } } - GDScriptCodeGenerator::Address assigned = _parse_expression(codegen, r_error, assignment->assigned_value); - GDScriptCodeGenerator::Address op_result; + GDScriptCodeGenerator::Address assigned_value = _parse_expression(codegen, r_error, assignment->assigned_value); if (r_error) { return GDScriptCodeGenerator::Address(); } - if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { + GDScriptCodeGenerator::Address to_assign; + bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE; + if (has_operation) { // Perform operation. - op_result = codegen.add_temporary(); - gen->write_binary_operator(op_result, assignment->variant_op, target, assigned); + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(); + GDScriptCodeGenerator::Address og_value = _parse_expression(codegen, r_error, assignment->assignee); + gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value); + to_assign = op_result; + + if (og_value.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); + } } else { - op_result = assigned; - assigned = GDScriptCodeGenerator::Address(); + to_assign = assigned_value; } GDScriptDataType assign_type = _gdtype_from_datatype(assignment->assignee->get_datatype()); @@ -1091,25 +1097,25 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code if (has_setter && !is_in_setter) { // Call setter. Vector<GDScriptCodeGenerator::Address> args; - args.push_back(op_result); + args.push_back(to_assign); gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), setter_function, args); } else { // Just assign. if (assignment->use_conversion_assign) { - gen->write_assign_with_conversion(target, op_result); + gen->write_assign_with_conversion(target, to_assign); } else { - gen->write_assign(target, op_result); + gen->write_assign(target, to_assign); } } - if (op_result.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + if (to_assign.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); // Pop assigned value or temp operation result. } - if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + if (has_operation && assigned_value.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); // Pop assigned value if not done before. } if (target.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + gen->pop_temporary(); // Pop the target to assignment. } } return GDScriptCodeGenerator::Address(); // Assignment does not return a value. @@ -2187,8 +2193,8 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->_base = nullptr; p_script->members.clear(); p_script->constants.clear(); - for (Map<StringName, GDScriptFunction *>::Element *E = p_script->member_functions.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<StringName, GDScriptFunction *> &E : p_script->member_functions) { + memdelete(E.value); } p_script->member_functions.clear(); p_script->member_indices.clear(); @@ -2513,8 +2519,8 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa instance->owner = E->get(); //needed for hot reloading - for (Map<StringName, GDScript::MemberInfo>::Element *F = p_script->member_indices.front(); F; F = F->next()) { - instance->member_indices_cache[F->key()] = F->get().index; + for (const KeyValue<StringName, GDScript::MemberInfo> &F : p_script->member_indices) { + instance->member_indices_cache[F.key] = F.value.index; } instance->owner->set_script_instance(instance); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 044ac4b661..83805f626a 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -173,8 +173,8 @@ bool GDScriptLanguage::validate(const String &p_script, const String &p_path, Li get_function_names_recursively(cl, "", funcs); - for (Map<int, String>::Element *E = funcs.front(); E; E = E->next()) { - r_functions->push_back(E->get() + ":" + itos(E->key())); + for (const KeyValue<int, String> &E : funcs) { + r_functions->push_back(E.value + ":" + itos(E.key)); } } @@ -344,9 +344,9 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> * const Map<StringName, GDScript::MemberInfo> &mi = script->debug_get_member_indices(); - for (const Map<StringName, GDScript::MemberInfo>::Element *E = mi.front(); E; E = E->next()) { - p_members->push_back(E->key()); - p_values->push_back(instance->debug_get_member_by_index(E->get().index)); + for (const KeyValue<StringName, GDScript::MemberInfo> &E : mi) { + p_members->push_back(E.key); + p_values->push_back(instance->debug_get_member_by_index(E.value.index)); } } @@ -370,14 +370,14 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> List<Pair<String, Variant>> cinfo; get_public_constants(&cinfo); - for (const Map<StringName, int>::Element *E = name_idx.front(); E; E = E->next()) { - if (ClassDB::class_exists(E->key()) || Engine::get_singleton()->has_singleton(E->key())) { + for (const KeyValue<StringName, int> &E : name_idx) { + if (ClassDB::class_exists(E.key) || Engine::get_singleton()->has_singleton(E.key)) { continue; } bool is_script_constant = false; for (List<Pair<String, Variant>>::Element *CE = cinfo.front(); CE; CE = CE->next()) { - if (CE->get().first == E->key()) { + if (CE->get().first == E.key) { is_script_constant = true; break; } @@ -386,7 +386,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> continue; } - const Variant &var = globals[E->value()]; + const Variant &var = globals[E.value]; if (Object *obj = var) { if (Object::cast_to<GDScriptNativeClass>(obj)) { continue; @@ -395,7 +395,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> bool skip = false; for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { - if (E->key() == CoreConstants::get_global_constant_name(i)) { + if (E.key == CoreConstants::get_global_constant_name(i)) { skip = true; break; } @@ -404,7 +404,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> continue; } - p_globals->push_back(E->key()); + p_globals->push_back(E.key); p_values->push_back(var); } } @@ -875,8 +875,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base } Map<StringName, Variant> constants; scr->get_constants(&constants); - for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { - ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + for (const KeyValue<StringName, Variant> &E : constants) { + ScriptCodeCompletionOption option(E.key.operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); r_result.insert(option.display, option); } @@ -1099,12 +1099,12 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool } // Native classes and global constants. - for (const Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) { + for (const KeyValue<StringName, int> &E : GDScriptLanguage::get_singleton()->get_global_map()) { ScriptCodeCompletionOption option; - if (ClassDB::class_exists(E->key()) || Engine::get_singleton()->has_singleton(E->key())) { - option = ScriptCodeCompletionOption(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + if (ClassDB::class_exists(E.key) || Engine::get_singleton()->has_singleton(E.key)) { + option = ScriptCodeCompletionOption(E.key.operator String(), ScriptCodeCompletionOption::KIND_CLASS); } else { - option = ScriptCodeCompletionOption(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + option = ScriptCodeCompletionOption(E.key.operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); } r_result.insert(option.display, option); } @@ -2680,8 +2680,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } break; } - for (Map<String, ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) { - r_options->push_back(E->get()); + for (const KeyValue<String, ScriptCodeCompletionOption> &E : options) { + r_options->push_back(E.value); } return OK; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 876c508689..a3f0c7dfef 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -120,11 +120,11 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String } List<_GDFKCS> stackpositions; - for (Map<StringName, _GDFKC>::Element *E = sdmap.front(); E; E = E->next()) { + for (const KeyValue<StringName, _GDFKC> &E : sdmap) { _GDFKCS spp; - spp.id = E->key(); - spp.order = E->get().order; - spp.pos = E->get().pos.back()->get(); + spp.id = E.key; + spp.order = E.value.order; + spp.pos = E.value.pos.back()->get(); stackpositions.push_back(spp); } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 025accf4ba..63817e970a 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -582,9 +582,9 @@ void GDScriptParser::parse_program() { parse_class_body(true); #ifdef TOOLS_ENABLED - for (Map<int, GDScriptTokenizer::CommentData>::Element *E = tokenizer.get_comments().front(); E; E = E->next()) { - if (E->get().new_line && E->get().comment.begins_with("##")) { - class_doc_line = MIN(class_doc_line, E->key()); + for (const KeyValue<int, GDScriptTokenizer::CommentData> &E : tokenizer.get_comments()) { + if (E.value.new_line && E.value.comment.begins_with("##")) { + class_doc_line = MIN(class_doc_line, E.key); } } if (has_comment(class_doc_line)) { @@ -3481,22 +3481,22 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod } for (int i = last; i >= 0; i--) { String mode = p_annotation->resolved_arguments[i].operator String(); - if (mode == "any") { - rpc_config.rpc_mode = Multiplayer::RPC_MODE_ANY; - } else if (mode == "auth") { + if (mode == "any_peer") { + rpc_config.rpc_mode = Multiplayer::RPC_MODE_ANY_PEER; + } else if (mode == "authority") { rpc_config.rpc_mode = Multiplayer::RPC_MODE_AUTHORITY; - } else if (mode == "sync") { + } else if (mode == "call_local") { rpc_config.sync = true; - } else if (mode == "nosync") { + } else if (mode == "call_remote") { rpc_config.sync = false; } else if (mode == "reliable") { rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; } else if (mode == "unreliable") { rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE; - } else if (mode == "ordered") { - rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_ORDERED; + } else if (mode == "unreliable_ordered") { + rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED; } else { - push_error(R"(Invalid RPC argument. Must be one of: 'sync'/'nosync' (local calls), 'any'/'auth' (permission), 'reliable'/'unreliable'/'ordered' (transfer mode).)", p_annotation); + push_error(R"(Invalid RPC argument. Must be one of: 'call_local'/'no_call_local' (local calls), 'any_peer'/'authority' (permission), 'reliable'/'unreliable'/'unreliable_ordered' (transfer mode).)", p_annotation); } } } diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index 62531473c3..f1b0079536 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -317,9 +317,9 @@ struct GDScriptUtilityFunctionsDefinitions { d["@subpath"] = cp; d["@path"] = p->get_path(); - for (Map<StringName, GDScript::MemberInfo>::Element *E = base->member_indices.front(); E; E = E->next()) { - if (!d.has(E->key())) { - d[E->key()] = ins->members[E->get().index]; + for (const KeyValue<StringName, GDScript::MemberInfo> &E : base->member_indices) { + if (!d.has(E.key)) { + d[E.key] = ins->members[E.value.index]; } } *r_ret = d; @@ -396,9 +396,9 @@ struct GDScriptUtilityFunctionsDefinitions { GDScriptInstance *ins = static_cast<GDScriptInstance *>(static_cast<Object *>(*r_ret)->get_script_instance()); Ref<GDScript> gd_ref = ins->get_script(); - for (Map<StringName, GDScript::MemberInfo>::Element *E = gd_ref->member_indices.front(); E; E = E->next()) { - if (d.has(E->key())) { - ins->members.write[E->get().index] = d[E->key()]; + for (KeyValue<StringName, GDScript::MemberInfo> &E : gd_ref->member_indices) { + if (d.has(E.key)) { + ins->members.write[E.value.index] = d[E.key]; } } } diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 6186d0edee..c89cf2f25c 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -531,8 +531,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a memnew_placement(&stack[ADDR_STACK_CLASS], Variant(script)); - for (const Map<int, Variant::Type>::Element *E = temporary_slots.front(); E; E = E->next()) { - type_init_function_table[E->get()](&stack[E->key()]); + for (const KeyValue<int, Variant::Type> &E : temporary_slots) { + type_init_function_table[E.value](&stack[E.key]); } String err_text; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index d106b3b541..730e554476 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -491,7 +491,7 @@ String ExtendGDScriptParser::get_text_for_completion(const lsp::Position &p_curs return longthing; } -String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_cursor, const String &p_symbol, bool p_func_requred) const { +String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_cursor, const String &p_symbol, bool p_func_required) const { String longthing; int len = lines.size(); for (int i = 0; i < len; i++) { @@ -513,7 +513,7 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c longthing += first_part; longthing += String::chr(0xFFFF); //not unicode, represents the cursor - if (p_func_requred) { + if (p_func_required) { longthing += "("; // tell the parser this is a function call } longthing += last_part; @@ -532,6 +532,9 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c String ExtendGDScriptParser::get_identifier_under_position(const lsp::Position &p_position, Vector2i &p_offset) const { ERR_FAIL_INDEX_V(p_position.line, lines.size(), ""); String line = lines[p_position.line]; + if (line.is_empty()) { + return ""; + } ERR_FAIL_INDEX_V(p_position.character, line.size(), ""); int start_pos = p_position.character; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h index 28b9b3c82a..5d7b16765b 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.h +++ b/modules/gdscript/language_server/gdscript_extend_parser.h @@ -85,7 +85,7 @@ public: Error get_left_function_call(const lsp::Position &p_position, lsp::Position &r_func_pos, int &r_arg_index) const; String get_text_for_completion(const lsp::Position &p_cursor) const; - String get_text_for_lookup_symbol(const lsp::Position &p_cursor, const String &p_symbol = "", bool p_func_requred = false) const; + String get_text_for_lookup_symbol(const lsp::Position &p_cursor, const String &p_symbol = "", bool p_func_required = false) const; String get_identifier_under_position(const lsp::Position &p_position, Vector2i &p_offset) const; String get_uri() const; diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index bd5a9f01b2..5cf1e0fc5f 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -212,11 +212,11 @@ void GDScriptLanguageProtocol::initialized(const Variant &p_params) { lsp::GodotCapabilities capabilities; DocTools *doc = EditorHelp::get_doc_data(); - for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { + for (const KeyValue<String, DocData::ClassDoc> &E : doc->class_list) { lsp::GodotNativeClassInfo gdclass; - gdclass.name = E->get().name; - gdclass.class_doc = &(E->get()); - if (ClassDB::ClassInfo *ptr = ClassDB::classes.getptr(StringName(E->get().name))) { + gdclass.name = E.value.name; + gdclass.class_doc = &(E.value); + if (ClassDB::ClassInfo *ptr = ClassDB::classes.getptr(StringName(E.value.name))) { gdclass.class_info = ptr; } capabilities.native_classes.push_back(gdclass); diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 03b1e3fa44..92ce71f395 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -217,8 +217,8 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) { } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { arr = native_member_completions.duplicate(); - for (Map<String, ExtendGDScriptParser *>::Element *E = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.front(); E; E = E->next()) { - ExtendGDScriptParser *script = E->get(); + for (KeyValue<String, ExtendGDScriptParser *> &E : GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts) { + ExtendGDScriptParser *script = E.value; const Array &items = script->get_member_completions(); const int start_size = arr.size(); @@ -428,6 +428,9 @@ GDScriptTextDocument::~GDScriptTextDocument() { void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) { String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path); + if (!path.begins_with("res://")) { + return; + } GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content); EditorFileSystem::get_singleton()->update_file(path); diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 86b3a3a326..371e3de419 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -261,9 +261,9 @@ Array GDScriptWorkspace::symbol(const Dictionary &p_params) { String query = p_params["query"]; Array arr; if (!query.is_empty()) { - for (Map<String, ExtendGDScriptParser *>::Element *E = scripts.front(); E; E = E->next()) { + for (const KeyValue<String, ExtendGDScriptParser *> &E : scripts) { Vector<lsp::DocumentedSymbolInformation> script_symbols; - E->get()->get_symbols().symbol_tree_as_list(E->key(), script_symbols); + E.value->get_symbols().symbol_tree_as_list(E.key, script_symbols); for (int i = 0; i < script_symbols.size(); ++i) { if (query.is_subsequence_ofi(script_symbols[i].name)) { lsp::DocumentedSymbolInformation symbol = script_symbols[i]; @@ -282,10 +282,10 @@ Error GDScriptWorkspace::initialize() { } DocTools *doc = EditorHelp::get_doc_data(); - for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { - const DocData::ClassDoc &class_data = E->value(); + for (const KeyValue<String, DocData::ClassDoc> &E : doc->class_list) { + const DocData::ClassDoc &class_data = E.value; lsp::DocumentSymbol class_symbol; - String class_name = E->key(); + String class_name = E.key; class_symbol.name = class_name; class_symbol.native_class = class_name; class_symbol.kind = lsp::SymbolKind::Class; @@ -393,19 +393,19 @@ Error GDScriptWorkspace::initialize() { reload_all_workspace_scripts(); if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { - for (Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.front(); E; E = E->next()) { + for (const KeyValue<StringName, lsp::DocumentSymbol> &E : native_symbols) { ClassMembers members; - const lsp::DocumentSymbol &class_symbol = E->get(); + const lsp::DocumentSymbol &class_symbol = E.value; for (int i = 0; i < class_symbol.children.size(); i++) { const lsp::DocumentSymbol &symbol = class_symbol.children[i]; members.set(symbol.name, &symbol); } - native_members.set(E->key(), members); + native_members.set(E.key, members); } // cache member completions - for (Map<String, ExtendGDScriptParser *>::Element *S = scripts.front(); S; S = S->next()) { - S->get()->get_member_completions(); + for (const KeyValue<String, ExtendGDScriptParser *> &S : scripts) { + S.value->get_member_completions(); } } @@ -603,7 +603,7 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S } } -const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_requred) { +const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_required) { const lsp::DocumentSymbol *symbol = nullptr; String path = get_file_path(p_doc_pos.textDocument.uri); @@ -628,7 +628,10 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu } else { ScriptLanguage::LookupResult ret; - if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, nullptr, ret)) { + if (symbol_identifier == "new" && parser->get_lines()[p_doc_pos.position.line].replace(" ", "").replace("\t", "").find("new(") > -1) { + symbol_identifier = "_init"; + } + if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_required), symbol_identifier, path, nullptr, ret)) { if (ret.type == ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION) { String target_script_path = path; if (!ret.script.is_null()) { @@ -682,8 +685,8 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP class_ptr = native_members.next(class_ptr); } - for (Map<String, ExtendGDScriptParser *>::Element *E = scripts.front(); E; E = E->next()) { - const ExtendGDScriptParser *script = E->get(); + for (const KeyValue<String, ExtendGDScriptParser *> &E : scripts) { + const ExtendGDScriptParser *script = E.value; const ClassMembers &members = script->get_members(); if (const lsp::DocumentSymbol *const *symbol = members.getptr(symbol_identifier)) { r_list.push_back(*symbol); @@ -783,12 +786,12 @@ GDScriptWorkspace::GDScriptWorkspace() { GDScriptWorkspace::~GDScriptWorkspace() { Set<String> cached_parsers; - for (Map<String, ExtendGDScriptParser *>::Element *E = parse_results.front(); E; E = E->next()) { - cached_parsers.insert(E->key()); + for (const KeyValue<String, ExtendGDScriptParser *> &E : parse_results) { + cached_parsers.insert(E.key); } - for (Map<String, ExtendGDScriptParser *>::Element *E = scripts.front(); E; E = E->next()) { - cached_parsers.insert(E->key()); + for (const KeyValue<String, ExtendGDScriptParser *> &E : scripts) { + cached_parsers.insert(E.key); } for (Set<String>::Element *E = cached_parsers.front(); E; E = E->next()) { diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index e5cd4d9824..6f5600b5cf 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -87,7 +87,7 @@ public: void publish_diagnostics(const String &p_path); void completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options); - const lsp::DocumentSymbol *resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name = "", bool p_func_requred = false); + const lsp::DocumentSymbol *resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name = "", bool p_func_required = false); void resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list); const lsp::DocumentSymbol *resolve_native_symbol(const lsp::NativeSymbolInspectParams &p_params); void resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list); diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 662382d279..3710a84a28 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -277,15 +277,15 @@ struct WorkspaceEdit { Dictionary dict; Dictionary out_changes; - for (Map<String, Vector<TextEdit>>::Element *E = changes.front(); E; E = E->next()) { + for (const KeyValue<String, Vector<TextEdit>> &E : changes) { Array edits; - for (int i = 0; i < E->get().size(); ++i) { + for (int i = 0; i < E.value.size(); ++i) { Dictionary text_edit; - text_edit["range"] = E->get()[i].range.to_json(); - text_edit["newText"] = E->get()[i].newText; + text_edit["range"] = E.value[i].range.to_json(); + text_edit["newText"] = E.value[i].newText; edits.push_back(text_edit); } - out_changes[E->key()] = edits; + out_changes[E.key] = edits; } dict["changes"] = out_changes; diff --git a/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..b84ccdce81 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.gd @@ -0,0 +1,5 @@ +class Vector2: + pass + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..a7c0a29a69 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.gd @@ -0,0 +1,4 @@ +const Vector2 = 0 + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..930f91b389 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.gd @@ -0,0 +1,4 @@ +enum Vector2 { A, B } + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..7cba29884c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.gd @@ -0,0 +1,4 @@ +var Vector2 + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd new file mode 100644 index 0000000000..3eb02816ed --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd @@ -0,0 +1,11 @@ +#GDTEST_OK +var prop : int = 0: + get: + return prop + set(value): + prop = value % 7 + +func test(): + for i in 7: + prop += 1 + print(prop) diff --git a/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.out b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.out new file mode 100644 index 0000000000..76157853f2 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.out @@ -0,0 +1,8 @@ +GDTEST_OK +1 +2 +3 +4 +5 +6 +0 diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index e54f055f2b..80eabc1596 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -172,8 +172,8 @@ static void test_compiler(const String &p_code, const String &p_script_path, con return; } - for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) { - const GDScriptFunction *func = E->value(); + for (const KeyValue<StringName, GDScriptFunction *> &E : script->get_member_functions()) { + const GDScriptFunction *func = E.value; String signature = "Disassembling " + func->get_name().operator String() + "("; for (int i = 0; i < func->get_argument_count(); i++) { diff --git a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp index fd9f758f10..3ce5ea23dc 100644 --- a/modules/gltf/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor_scene_exporter_gltf_plugin.cpp @@ -86,7 +86,7 @@ void SceneExporterGLTFPlugin::convert_scene_to_gltf2() { editor->show_accept(TTR("This operation can't be done without a scene."), TTR("OK")); return; } - String filename = String(root->get_filename().get_file().get_basename()); + String filename = String(root->get_scene_file_path().get_file().get_basename()); if (filename.is_empty()) { filename = root->get_name(); } diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index a92eb88edb..3f1f218e78 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -78,7 +78,10 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String &p_path) { uint64_t begin_time = OS::get_singleton()->get_ticks_usec(); - _convert_scene_node(state, p_root, p_root, -1, -1); + state->skeleton3d_to_gltf_skeleton.clear(); + state->skin_and_skeleton3d_to_gltf_skin.clear(); + + _convert_scene_node(state, p_root, -1, -1); if (!state->buffers.size()) { state->buffers.push_back(Vector<uint8_t>()); } @@ -97,11 +100,7 @@ Error GLTFDocument::serialize(Ref<GLTFState> state, Node *p_root, const String & if (err != OK) { return Error::FAILED; } - /* STEP 4 CREATE BONE ATTACHMENTS */ - err = _serialize_bone_attachment(state); - if (err != OK) { - return Error::FAILED; - } + /* STEP 5 SERIALIZE MESHES (we have enough info now) */ err = _serialize_meshes(state); if (err != OK) { @@ -249,30 +248,6 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) { return OK; } -Error GLTFDocument::_serialize_bone_attachment(Ref<GLTFState> state) { - for (int skeleton_i = 0; skeleton_i < state->skeletons.size(); skeleton_i++) { - for (int attachment_i = 0; attachment_i < state->skeletons[skeleton_i]->bone_attachments.size(); attachment_i++) { - BoneAttachment3D *bone_attachment = state->skeletons[skeleton_i]->bone_attachments[attachment_i]; - String bone_name = bone_attachment->get_bone_name(); - bone_name = _sanitize_bone_name(bone_name); - int32_t bone = state->skeletons[skeleton_i]->godot_skeleton->find_bone(bone_name); - ERR_CONTINUE(bone == -1); - for (int skin_i = 0; skin_i < state->skins.size(); skin_i++) { - if (state->skins[skin_i]->skeleton != skeleton_i) { - continue; - } - - for (int node_i = 0; node_i < bone_attachment->get_child_count(); node_i++) { - ERR_CONTINUE(bone >= state->skins[skin_i]->joints.size()); - _convert_scene_node(state, bone_attachment->get_child(node_i), bone_attachment->get_owner(), state->skins[skin_i]->joints[bone], 0); - } - break; - } - } - } - return OK; -} - Error GLTFDocument::_parse_glb(const String &p_path, Ref<GLTFState> state) { Error err; FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); @@ -2131,11 +2106,14 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { continue; } Array primitives; - Array targets; Dictionary gltf_mesh; Array target_names; Array weights; + for (int morph_i = 0; morph_i < import_mesh->get_blend_shape_count(); morph_i++) { + target_names.push_back(import_mesh->get_blend_shape_name(morph_i)); + } for (int surface_i = 0; surface_i < import_mesh->get_surface_count(); surface_i++) { + Array targets; Dictionary primitive; Mesh::PrimitiveType primitive_type = import_mesh->get_surface_primitive_type(surface_i); switch (primitive_type) { @@ -2337,10 +2315,10 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { const Array &a = array[Mesh::ARRAY_WEIGHTS]; const Vector<Vector3> &vertex_array = array[Mesh::ARRAY_VERTEX]; if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) { - const int ret_size = a.size() / JOINT_GROUP_SIZE; + int32_t vertex_count = vertex_array.size(); Vector<Color> attribs; - attribs.resize(ret_size); - for (int i = 0; i < ret_size; i++) { + attribs.resize(vertex_count); + for (int i = 0; i < vertex_count; i++) { attribs.write[i] = Color(a[(i * JOINT_GROUP_SIZE) + 0], a[(i * JOINT_GROUP_SIZE) + 1], a[(i * JOINT_GROUP_SIZE) + 2], a[(i * JOINT_GROUP_SIZE) + 3]); } attributes["WEIGHTS_0"] = _encode_accessor_as_weights(state, attribs, true); @@ -2410,7 +2388,6 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { ArrayMesh::BlendShapeMode shape_mode = import_mesh->get_blend_shape_mode(); for (int morph_i = 0; morph_i < import_mesh->get_blend_shape_count(); morph_i++) { Array array_morph = import_mesh->get_surface_blend_shape_arrays(surface_i, morph_i); - target_names.push_back(import_mesh->get_blend_shape_name(morph_i)); Dictionary t; Vector<Vector3> varr = array_morph[Mesh::ARRAY_VERTEX]; Array mesh_arrays = import_mesh->get_surface_arrays(surface_i); @@ -2427,22 +2404,21 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { } Vector<Vector3> narr = array_morph[Mesh::ARRAY_NORMAL]; - if (varr.size()) { + if (narr.size()) { t["NORMAL"] = _encode_accessor_as_vec3(state, narr, true); } Vector<real_t> tarr = array_morph[Mesh::ARRAY_TANGENT]; if (tarr.size()) { const int ret_size = tarr.size() / 4; - Vector<Color> attribs; + Vector<Vector3> attribs; attribs.resize(ret_size); for (int i = 0; i < ret_size; i++) { - Color tangent; - tangent.r = tarr[(i * 4) + 0]; - tangent.g = tarr[(i * 4) + 1]; - tangent.b = tarr[(i * 4) + 2]; - tangent.a = tarr[(i * 4) + 3]; + Vector3 vec3; + vec3.x = tarr[(i * 4) + 0]; + vec3.y = tarr[(i * 4) + 1]; + vec3.z = tarr[(i * 4) + 2]; } - t["TANGENT"] = _encode_accessor_as_color(state, attribs, true); + t["TANGENT"] = _encode_accessor_as_vec3(state, attribs, true); } targets.push_back(t); } @@ -2471,12 +2447,13 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) { Dictionary e; e["targetNames"] = target_names; - for (int j = 0; j < target_names.size(); j++) { + weights.resize(target_names.size()); + for (int name_i = 0; name_i < target_names.size(); name_i++) { real_t weight = 0.0; - if (j < state->meshes.write[gltf_mesh_i]->get_blend_weights().size()) { - weight = state->meshes.write[gltf_mesh_i]->get_blend_weights()[j]; + if (name_i < state->meshes.write[gltf_mesh_i]->get_blend_weights().size()) { + weight = state->meshes.write[gltf_mesh_i]->get_blend_weights()[name_i]; } - weights.push_back(weight); + weights[name_i] = weight; } if (weights.size()) { gltf_mesh["weights"] = weights; @@ -4285,6 +4262,7 @@ Error GLTFDocument::_create_skeletons(Ref<GLTFState> state) { Skeleton3D *skeleton = memnew(Skeleton3D); gltf_skeleton->godot_skeleton = skeleton; + state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()] = skel_i; // Make a unique name, no gltf node represents this skeleton skeleton->set_name(_gen_unique_name(state, "Skeleton3D")); @@ -4370,6 +4348,16 @@ Error GLTFDocument::_map_skin_joints_indices_to_skeleton_bone_indices(Ref<GLTFSt Error GLTFDocument::_serialize_skins(Ref<GLTFState> state) { _remove_duplicate_skins(state); + Array json_skins; + for (int skin_i = 0; skin_i < state->skins.size(); skin_i++) { + Ref<GLTFSkin> gltf_skin = state->skins[skin_i]; + Dictionary json_skin; + json_skin["inverseBindMatrices"] = _encode_accessor_as_xform(state, gltf_skin->inverse_binds, false); + json_skin["joints"] = gltf_skin->get_joints(); + json_skin["name"] = gltf_skin->get_name(); + json_skins.push_back(json_skin); + } + state->json["skins"] = json_skins; return OK; } @@ -4685,8 +4673,8 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { Array channels; Array samplers; - for (Map<int, GLTFAnimation::Track>::Element *track_i = gltf_animation->get_tracks().front(); track_i; track_i = track_i->next()) { - GLTFAnimation::Track track = track_i->get(); + for (KeyValue<int, GLTFAnimation::Track> &track_i : gltf_animation->get_tracks()) { + GLTFAnimation::Track track = track_i.value; if (track.position_track.times.size()) { Dictionary t; t["sampler"] = samplers.size(); @@ -4702,7 +4690,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { Dictionary target; target["path"] = "translation"; - target["node"] = track_i->key(); + target["node"] = track_i.key; t["target"] = target; channels.push_back(t); @@ -4722,7 +4710,7 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { Dictionary target; target["path"] = "rotation"; - target["node"] = track_i->key(); + target["node"] = track_i.key; t["target"] = target; channels.push_back(t); @@ -4742,42 +4730,86 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) { Dictionary target; target["path"] = "scale"; - target["node"] = track_i->key(); + target["node"] = track_i.key; t["target"] = target; channels.push_back(t); } if (track.weight_tracks.size()) { + double length = 0.0f; + + for (int32_t track_idx = 0; track_idx < track.weight_tracks.size(); track_idx++) { + int32_t last_time_index = track.weight_tracks[track_idx].times.size() - 1; + length = MAX(length, track.weight_tracks[track_idx].times[last_time_index]); + } + Dictionary t; t["sampler"] = samplers.size(); Dictionary s; - Vector<real_t> times; - Vector<real_t> values; + const double increment = 1.0 / BAKE_FPS; + { + double time = 0.0; + bool last = false; + while (true) { + times.push_back(time); + if (last) { + break; + } + time += increment; + if (time >= length) { + last = true; + time = length; + } + } + } - for (int32_t times_i = 0; times_i < track.weight_tracks[0].times.size(); times_i++) { - real_t time = track.weight_tracks[0].times[times_i]; - times.push_back(time); + for (int32_t track_idx = 0; track_idx < track.weight_tracks.size(); track_idx++) { + double time = 0.0; + bool last = false; + Vector<real_t> weight_track; + while (true) { + float weight = _interpolate_track<float>(track.weight_tracks[track_idx].times, + track.weight_tracks[track_idx].values, + time, + track.weight_tracks[track_idx].interpolation); + weight_track.push_back(weight); + if (last) { + break; + } + time += increment; + if (time >= length) { + last = true; + time = length; + } + } + track.weight_tracks.write[track_idx].times = times; + track.weight_tracks.write[track_idx].values = weight_track; } - values.resize(times.size() * track.weight_tracks.size()); - // TODO Sort by order in blend shapes + Vector<real_t> all_track_times = times; + Vector<real_t> all_track_values; + int32_t values_size = track.weight_tracks[0].values.size(); + int32_t weight_tracks_size = track.weight_tracks.size(); + all_track_values.resize(weight_tracks_size * values_size); for (int k = 0; k < track.weight_tracks.size(); k++) { Vector<float> wdata = track.weight_tracks[k].values; for (int l = 0; l < wdata.size(); l++) { - values.write[l * track.weight_tracks.size() + k] = wdata.write[l]; + int32_t index = l * weight_tracks_size + k; + ERR_BREAK(index >= all_track_values.size()); + all_track_values.write[index] = wdata.write[l]; } } s["interpolation"] = interpolation_to_string(track.weight_tracks[track.weight_tracks.size() - 1].interpolation); - s["input"] = _encode_accessor_as_floats(state, times, false); - s["output"] = _encode_accessor_as_floats(state, values, false); + s["input"] = _encode_accessor_as_floats(state, all_track_times, false); + s["output"] = _encode_accessor_as_floats(state, all_track_values, false); samplers.push_back(s); Dictionary target; target["path"] = "weights"; - target["node"] = track_i->key(); + target["node"] = track_i.key; t["target"] = target; channels.push_back(t); @@ -4905,7 +4937,7 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) { track->weight_tracks.resize(wc); const int expected_value_count = times.size() * output_count * wc; - ERR_FAIL_COND_V_MSG(weights.size() != expected_value_count, ERR_PARSE_ERROR, "Invalid weight data, expected " + itos(expected_value_count) + " weight values, got " + itos(weights.size()) + " instead."); + ERR_CONTINUE_MSG(weights.size() != expected_value_count, "Invalid weight data, expected " + itos(expected_value_count) + " weight values, got " + itos(weights.size()) + " instead."); const int wlen = weights.size() / wc; for (int k = 0; k < wc; k++) { //separate tracks, having them together is not such a good idea @@ -4970,7 +5002,7 @@ BoneAttachment3D *GLTFDocument::_generate_bone_attachment(Ref<GLTFState> state, return bone_attachment; } -GLTFMeshIndex GLTFDocument::_convert_mesh_instance(Ref<GLTFState> state, MeshInstance3D *p_mesh_instance) { +GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> state, MeshInstance3D *p_mesh_instance) { ERR_FAIL_NULL_V(p_mesh_instance, -1); if (p_mesh_instance->get_mesh().is_null()) { return -1; @@ -5167,17 +5199,6 @@ GLTFLightIndex GLTFDocument::_convert_light(Ref<GLTFState> state, Light3D *p_lig return light_index; } -GLTFSkeletonIndex GLTFDocument::_convert_skeleton(Ref<GLTFState> state, Skeleton3D *p_skeleton) { - print_verbose("glTF: Converting skeleton: " + p_skeleton->get_name()); - Ref<GLTFSkeleton> gltf_skeleton; - gltf_skeleton.instantiate(); - gltf_skeleton->set_name(_gen_unique_name(state, p_skeleton->get_name())); - gltf_skeleton->godot_skeleton = p_skeleton; - GLTFSkeletonIndex skeleton_i = state->skeletons.size(); - state->skeletons.push_back(gltf_skeleton); - return skeleton_i; -} - void GLTFDocument::_convert_spatial(Ref<GLTFState> state, Node3D *p_spatial, Ref<GLTFNode> p_node) { Transform3D xform = p_spatial->get_transform(); p_node->scale = xform.basis.get_scale(); @@ -5193,7 +5214,7 @@ Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, Node *scene_parent return spatial; } -void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, Node *p_root, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) { +void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) { bool retflag = true; _check_visibility(p_current, retflag); if (retflag) { @@ -5207,37 +5228,41 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No _convert_spatial(state, spatial, gltf_node); } if (cast_to<MeshInstance3D>(p_current)) { - Node3D *spatial = cast_to<Node3D>(p_current); - _convert_mesh_to_gltf(p_current, state, spatial, gltf_node); + MeshInstance3D *mi = cast_to<MeshInstance3D>(p_current); + _convert_mesh_instance_to_gltf(mi, state, gltf_node); } else if (cast_to<BoneAttachment3D>(p_current)) { - _convert_bone_attachment_to_gltf(p_current, state, gltf_node, retflag); - // TODO 2020-12-21 iFire Handle the case of objects under the bone attachment. + BoneAttachment3D *bone = cast_to<BoneAttachment3D>(p_current); + _convert_bone_attachment_to_gltf(bone, state, p_gltf_parent, p_gltf_root, gltf_node); return; } else if (cast_to<Skeleton3D>(p_current)) { - _convert_skeleton_to_gltf(p_current, state, p_gltf_parent, p_gltf_root, gltf_node, p_root); + Skeleton3D *skel = cast_to<Skeleton3D>(p_current); + _convert_skeleton_to_gltf(skel, state, p_gltf_parent, p_gltf_root, gltf_node); // We ignore the Godot Engine node that is the skeleton. return; } else if (cast_to<MultiMeshInstance3D>(p_current)) { - _convert_mult_mesh_instance_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root); + MultiMeshInstance3D *multi = cast_to<MultiMeshInstance3D>(p_current); + _convert_mult_mesh_instance_to_gltf(multi, p_gltf_parent, p_gltf_root, gltf_node, state); #ifdef MODULE_CSG_ENABLED } else if (cast_to<CSGShape3D>(p_current)) { - if (p_current->get_parent() && cast_to<CSGShape3D>(p_current)->is_root_shape()) { - _convert_csg_shape_to_gltf(p_current, p_gltf_parent, gltf_node, state); + CSGShape3D *shape = cast_to<CSGShape3D>(p_current); + if (shape->get_parent() && shape->is_root_shape()) { + _convert_csg_shape_to_gltf(shape, p_gltf_parent, gltf_node, state); } #endif // MODULE_CSG_ENABLED #ifdef MODULE_GRIDMAP_ENABLED } else if (cast_to<GridMap>(p_current)) { - _convert_grid_map_to_gltf(p_current, p_gltf_parent, p_gltf_root, gltf_node, state, p_root); + GridMap *gridmap = Object::cast_to<GridMap>(p_current); + _convert_grid_map_to_gltf(gridmap, p_gltf_parent, p_gltf_root, gltf_node, state); #endif // MODULE_GRIDMAP_ENABLED } else if (cast_to<Camera3D>(p_current)) { Camera3D *camera = Object::cast_to<Camera3D>(p_current); - _convert_camera_to_gltf(camera, state, camera, gltf_node); + _convert_camera_to_gltf(camera, state, gltf_node); } else if (cast_to<Light3D>(p_current)) { Light3D *light = Object::cast_to<Light3D>(p_current); - _convert_light_to_gltf(light, state, light, gltf_node); + _convert_light_to_gltf(light, state, gltf_node); } else if (cast_to<AnimationPlayer>(p_current)) { AnimationPlayer *animation_player = Object::cast_to<AnimationPlayer>(p_current); - _convert_animation_player_to_gltf(animation_player, state, p_gltf_parent, p_gltf_root, gltf_node, p_current, p_root); + _convert_animation_player_to_gltf(animation_player, state, p_gltf_parent, p_gltf_root, gltf_node, p_current); } GLTFNodeIndex current_node_i = state->nodes.size(); GLTFNodeIndex gltf_root = p_gltf_root; @@ -5249,13 +5274,13 @@ void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, No } _create_gltf_node(state, p_current, current_node_i, p_gltf_parent, gltf_root, gltf_node); for (int node_i = 0; node_i < p_current->get_child_count(); node_i++) { - _convert_scene_node(state, p_current->get_child(node_i), p_root, current_node_i, gltf_root); + _convert_scene_node(state, p_current->get_child(node_i), current_node_i, gltf_root); } } #ifdef MODULE_CSG_ENABLED -void GLTFDocument::_convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state) { - CSGShape3D *csg = Object::cast_to<CSGShape3D>(p_current); +void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state) { + CSGShape3D *csg = p_current; csg->call("_update_shape"); Array meshes = csg->get_meshes(); if (meshes.size() != 2) { @@ -5286,16 +5311,15 @@ void GLTFDocument::_create_gltf_node(Ref<GLTFState> state, Node *p_scene_parent, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_gltf_node, Ref<GLTFNode> gltf_node) { state->scene_nodes.insert(current_node_i, p_scene_parent); state->nodes.push_back(gltf_node); - if (current_node_i == p_parent_node_index) { - return; - } + ERR_FAIL_COND(current_node_i == p_parent_node_index); + state->nodes.write[current_node_i]->parent = p_parent_node_index; if (p_parent_node_index == -1) { return; } state->nodes.write[p_parent_node_index]->children.push_back(current_node_i); } -void GLTFDocument::_convert_animation_player_to_gltf(AnimationPlayer *animation_player, Ref<GLTFState> state, const GLTFNodeIndex &p_gltf_current, const GLTFNodeIndex &p_gltf_root_index, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent, Node *p_root) { +void GLTFDocument::_convert_animation_player_to_gltf(AnimationPlayer *animation_player, Ref<GLTFState> state, GLTFNodeIndex p_gltf_current, GLTFNodeIndex p_gltf_root_index, Ref<GLTFNode> p_gltf_node, Node *p_scene_parent) { ERR_FAIL_COND(!animation_player); state->animation_players.push_back(animation_player); print_verbose(String("glTF: Converting animation player: ") + animation_player->get_name()); @@ -5314,7 +5338,7 @@ void GLTFDocument::_check_visibility(Node *p_node, bool &retflag) { retflag = false; } -void GLTFDocument::_convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node) { +void GLTFDocument::_convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> state, Ref<GLTFNode> gltf_node) { ERR_FAIL_COND(!camera); GLTFCameraIndex camera_index = _convert_camera(state, camera); if (camera_index != -1) { @@ -5322,7 +5346,7 @@ void GLTFDocument::_convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> stat } } -void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node) { +void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> state, Ref<GLTFNode> gltf_node) { ERR_FAIL_COND(!light); GLTFLightIndex light_index = _convert_light(state, light); if (light_index != -1) { @@ -5331,43 +5355,39 @@ void GLTFDocument::_convert_light_to_gltf(Light3D *light, Ref<GLTFState> state, } #ifdef MODULE_GRIDMAP_ENABLED -void GLTFDocument::_convert_grid_map_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) { - GridMap *grid_map = Object::cast_to<GridMap>(p_scene_parent); - ERR_FAIL_COND(!grid_map); - Array cells = grid_map->get_used_cells(); +void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state) { + Array cells = p_grid_map->get_used_cells(); for (int32_t k = 0; k < cells.size(); k++) { GLTFNode *new_gltf_node = memnew(GLTFNode); gltf_node->children.push_back(state->nodes.size()); state->nodes.push_back(new_gltf_node); Vector3 cell_location = cells[k]; - int32_t cell = grid_map->get_cell_item( + int32_t cell = p_grid_map->get_cell_item( Vector3(cell_location.x, cell_location.y, cell_location.z)); EditorSceneImporterMeshNode3D *import_mesh_node = memnew(EditorSceneImporterMeshNode3D); - import_mesh_node->set_mesh(grid_map->get_mesh_library()->get_item_mesh(cell)); + import_mesh_node->set_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)); Transform3D cell_xform; cell_xform.basis.set_orthogonal_index( - grid_map->get_cell_item_orientation( + p_grid_map->get_cell_item_orientation( Vector3(cell_location.x, cell_location.y, cell_location.z))); - cell_xform.basis.scale(Vector3(grid_map->get_cell_scale(), - grid_map->get_cell_scale(), - grid_map->get_cell_scale())); - cell_xform.set_origin(grid_map->map_to_world( + cell_xform.basis.scale(Vector3(p_grid_map->get_cell_scale(), + p_grid_map->get_cell_scale(), + p_grid_map->get_cell_scale())); + cell_xform.set_origin(p_grid_map->map_to_world( Vector3(cell_location.x, cell_location.y, cell_location.z))); Ref<GLTFMesh> gltf_mesh; gltf_mesh.instantiate(); gltf_mesh = import_mesh_node; new_gltf_node->mesh = state->meshes.size(); state->meshes.push_back(gltf_mesh); - new_gltf_node->xform = cell_xform * grid_map->get_transform(); - new_gltf_node->set_name(_gen_unique_name(state, grid_map->get_mesh_library()->get_item_name(cell))); + new_gltf_node->xform = cell_xform * p_grid_map->get_transform(); + new_gltf_node->set_name(_gen_unique_name(state, p_grid_map->get_mesh_library()->get_item_name(cell))); } } #endif // MODULE_GRIDMAP_ENABLED -void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state, Node *p_root_node) { - MultiMeshInstance3D *multi_mesh_instance = Object::cast_to<MultiMeshInstance3D>(p_scene_parent); - ERR_FAIL_COND(!multi_mesh_instance); - Ref<MultiMesh> multi_mesh = multi_mesh_instance->get_multimesh(); +void GLTFDocument::_convert_mult_mesh_instance_to_gltf(MultiMeshInstance3D *p_multi_mesh_instance, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref<GLTFNode> gltf_node, Ref<GLTFState> state) { + Ref<MultiMesh> multi_mesh = p_multi_mesh_instance->get_multimesh(); if (multi_mesh.is_valid()) { for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count(); instance_i++) { @@ -5383,9 +5403,9 @@ void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, con transform.basis.set_quaternion_scale(quaternion, Vector3(scale.x, 0, scale.y)); transform = - multi_mesh_instance->get_transform() * transform; + p_multi_mesh_instance->get_transform() * transform; } else if (multi_mesh->get_transform_format() == MultiMesh::TRANSFORM_3D) { - transform = multi_mesh_instance->get_transform() * + transform = p_multi_mesh_instance->get_transform() * multi_mesh->get_instance_transform(instance_i); } Ref<ArrayMesh> mm = multi_mesh->get_mesh(); @@ -5405,56 +5425,102 @@ void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, con state->meshes.push_back(gltf_mesh); } new_gltf_node->xform = transform; - new_gltf_node->set_name(_gen_unique_name(state, multi_mesh_instance->get_name())); + new_gltf_node->set_name(_gen_unique_name(state, p_multi_mesh_instance->get_name())); gltf_node->children.push_back(state->nodes.size()); state->nodes.push_back(new_gltf_node); } } } -void GLTFDocument::_convert_skeleton_to_gltf(Node *p_scene_parent, Ref<GLTFState> state, const GLTFNodeIndex &p_parent_node_index, const GLTFNodeIndex &p_root_node_index, Ref<GLTFNode> gltf_node, Node *p_root_node) { - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_scene_parent); - if (skeleton) { - // Remove placeholder skeleton3d node by not creating the gltf node - // Skins are per mesh - for (int node_i = 0; node_i < skeleton->get_child_count(); node_i++) { - _convert_scene_node(state, skeleton->get_child(node_i), p_root_node, p_parent_node_index, p_root_node_index); +void GLTFDocument::_convert_skeleton_to_gltf(Skeleton3D *p_skeleton3d, Ref<GLTFState> state, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref<GLTFNode> gltf_node) { + Skeleton3D *skeleton = p_skeleton3d; + Ref<GLTFSkeleton> gltf_skeleton; + gltf_skeleton.instantiate(); + // GLTFSkeleton is only used to hold internal state data. It will not be written to the document. + // + gltf_skeleton->godot_skeleton = skeleton; + GLTFSkeletonIndex skeleton_i = state->skeletons.size(); + state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()] = skeleton_i; + state->skeletons.push_back(gltf_skeleton); + + BoneId bone_count = skeleton->get_bone_count(); + for (BoneId bone_i = 0; bone_i < bone_count; bone_i++) { + Ref<GLTFNode> joint_node; + joint_node.instantiate(); + // Note that we cannot use _gen_unique_bone_name here, because glTF spec requires all node + // names to be unique regardless of whether or not they are used as joints. + joint_node->set_name(_gen_unique_name(state, skeleton->get_bone_name(bone_i))); + Transform3D xform = skeleton->get_bone_rest(bone_i) * skeleton->get_bone_pose(bone_i); + joint_node->scale = xform.basis.get_scale(); + joint_node->rotation = xform.basis.get_rotation_quaternion(); + joint_node->position = xform.origin; + joint_node->joint = true; + GLTFNodeIndex current_node_i = state->nodes.size(); + state->scene_nodes.insert(current_node_i, skeleton); + state->nodes.push_back(joint_node); + + gltf_skeleton->joints.push_back(current_node_i); + if (skeleton->get_bone_parent(bone_i) == -1) { + gltf_skeleton->roots.push_back(current_node_i); + } + gltf_skeleton->godot_bone_node.insert(bone_i, current_node_i); + } + for (BoneId bone_i = 0; bone_i < bone_count; bone_i++) { + GLTFNodeIndex current_node_i = gltf_skeleton->godot_bone_node[bone_i]; + BoneId parent_bone_id = skeleton->get_bone_parent(bone_i); + if (parent_bone_id == -1) { + if (p_parent_node_index != -1) { + state->nodes.write[current_node_i]->parent = p_parent_node_index; + state->nodes.write[p_parent_node_index]->children.push_back(current_node_i); + } + } else { + GLTFNodeIndex parent_node_i = gltf_skeleton->godot_bone_node[parent_bone_id]; + state->nodes.write[current_node_i]->parent = parent_node_i; + state->nodes.write[parent_node_i]->children.push_back(current_node_i); } } + // Remove placeholder skeleton3d node by not creating the gltf node + // Skins are per mesh + for (int node_i = 0; node_i < skeleton->get_child_count(); node_i++) { + _convert_scene_node(state, skeleton->get_child(node_i), p_parent_node_index, p_root_node_index); + } } -void GLTFDocument::_convert_bone_attachment_to_gltf(Node *p_scene_parent, Ref<GLTFState> state, Ref<GLTFNode> gltf_node, bool &retflag) { - retflag = true; - BoneAttachment3D *bone_attachment = Object::cast_to<BoneAttachment3D>(p_scene_parent); - if (bone_attachment) { - Node *node = bone_attachment->get_parent(); - while (node) { - Skeleton3D *bone_attachment_skeleton = Object::cast_to<Skeleton3D>(node); - if (bone_attachment_skeleton) { - for (GLTFSkeletonIndex skeleton_i = 0; skeleton_i < state->skeletons.size(); skeleton_i++) { - if (state->skeletons[skeleton_i]->godot_skeleton != bone_attachment_skeleton) { - continue; - } - state->skeletons.write[skeleton_i]->bone_attachments.push_back(bone_attachment); - break; - } - break; - } - node = node->get_parent(); +void GLTFDocument::_convert_bone_attachment_to_gltf(BoneAttachment3D *p_bone_attachment, Ref<GLTFState> state, GLTFNodeIndex p_parent_node_index, GLTFNodeIndex p_root_node_index, Ref<GLTFNode> gltf_node) { + Skeleton3D *skeleton; + // Note that relative transforms to external skeletons and pose overrides are not supported. + if (p_bone_attachment->get_use_external_skeleton()) { + skeleton = cast_to<Skeleton3D>(p_bone_attachment->get_node_or_null(p_bone_attachment->get_external_skeleton())); + } else { + skeleton = cast_to<Skeleton3D>(p_bone_attachment->get_parent()); + } + GLTFSkeletonIndex skel_gltf_i = -1; + if (skeleton != nullptr && state->skeleton3d_to_gltf_skeleton.has(skeleton->get_instance_id())) { + skel_gltf_i = state->skeleton3d_to_gltf_skeleton[skeleton->get_instance_id()]; + } + int bone_idx = -1; + if (skeleton != nullptr) { + bone_idx = p_bone_attachment->get_bone_idx(); + if (bone_idx == -1) { + bone_idx = skeleton->find_bone(p_bone_attachment->get_bone_name()); } - gltf_node.unref(); - return; } - retflag = false; + GLTFNodeIndex par_node_index = p_parent_node_index; + if (skeleton != nullptr && bone_idx != -1 && skel_gltf_i != -1) { + Ref<GLTFSkeleton> gltf_skeleton = state->skeletons.write[skel_gltf_i]; + gltf_skeleton->bone_attachments.push_back(p_bone_attachment); + par_node_index = gltf_skeleton->joints[bone_idx]; + } + + for (int node_i = 0; node_i < p_bone_attachment->get_child_count(); node_i++) { + _convert_scene_node(state, p_bone_attachment->get_child(node_i), par_node_index, p_root_node_index); + } } -void GLTFDocument::_convert_mesh_to_gltf(Node *p_scene_parent, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node) { - MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_scene_parent); - if (mi) { - GLTFMeshIndex gltf_mesh_index = _convert_mesh_instance(state, mi); - if (gltf_mesh_index != -1) { - gltf_node->mesh = gltf_mesh_index; - } +void GLTFDocument::_convert_mesh_instance_to_gltf(MeshInstance3D *p_scene_parent, Ref<GLTFState> state, Ref<GLTFNode> gltf_node) { + GLTFMeshIndex gltf_mesh_index = _convert_mesh_to_gltf(state, p_scene_parent); + if (gltf_mesh_index != -1) { + gltf_node->mesh = gltf_mesh_index; } } @@ -5734,16 +5800,16 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, float length = 0.0; - for (Map<int, GLTFAnimation::Track>::Element *track_i = anim->get_tracks().front(); track_i; track_i = track_i->next()) { - const GLTFAnimation::Track &track = track_i->get(); + for (const KeyValue<int, GLTFAnimation::Track> &track_i : anim->get_tracks()) { + const GLTFAnimation::Track &track = track_i.value; //need to find the path: for skeletons, weight tracks will affect the mesh NodePath node_path; //for skeletons, transform tracks always affect bones NodePath transform_node_path; - GLTFNodeIndex node_index = track_i->key(); + GLTFNodeIndex node_index = track_i.key; - const Ref<GLTFNode> gltf_node = state->nodes[track_i->key()]; + const Ref<GLTFNode> gltf_node = state->nodes[track_i.key]; Node *root = ap->get_parent(); ERR_FAIL_COND(root == nullptr); @@ -5795,15 +5861,15 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap, Vector3 base_scale = Vector3(1, 1, 1); if (!track.rotation_track.values.size()) { - base_rot = state->nodes[track_i->key()]->rotation.normalized(); + base_rot = state->nodes[track_i.key]->rotation.normalized(); } if (!track.position_track.values.size()) { - base_pos = state->nodes[track_i->key()]->position; + base_pos = state->nodes[track_i.key]->position; } if (!track.scale_track.values.size()) { - base_scale = state->nodes[track_i->key()]->scale; + base_scale = state->nodes[track_i.key]->scale; } bool last = false; @@ -5908,10 +5974,6 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { if (node->mesh < 0) { continue; } - Array json_skins; - if (state->json.has("skins")) { - json_skins = state->json["skins"]; - } Map<GLTFNodeIndex, Node *>::Element *mi_element = state->scene_nodes.find(mi_node_i); if (!mi_element) { continue; @@ -5923,7 +5985,6 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { node->rotation = mi_xform.basis.get_rotation_quaternion(); node->position = mi_xform.origin; - Dictionary json_skin; Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(mi->get_node(mi->get_skeleton_path())); if (!skeleton) { continue; @@ -5932,121 +5993,75 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) { continue; } Ref<Skin> skin = mi->get_skin(); - if (skin.is_null()) { - skin = skeleton->register_skin(nullptr)->get_skin(); - } Ref<GLTFSkin> gltf_skin; gltf_skin.instantiate(); Array json_joints; - GLTFSkeletonIndex skeleton_gltf_i = -1; NodePath skeleton_path = mi->get_skeleton_path(); - bool is_unique = true; - for (int32_t skin_i = 0; skin_i < state->skins.size(); skin_i++) { - Ref<GLTFSkin> prev_gltf_skin = state->skins.write[skin_i]; - if (gltf_skin.is_null()) { - continue; - } - GLTFSkeletonIndex prev_skeleton = prev_gltf_skin->get_skeleton(); - if (prev_skeleton == -1 || prev_skeleton >= state->skeletons.size()) { - continue; - } - if (prev_gltf_skin->get_godot_skin() == skin && state->skeletons[prev_skeleton]->godot_skeleton == skeleton) { - node->skin = skin_i; - node->skeleton = prev_skeleton; - is_unique = false; - break; - } - } - if (!is_unique) { - continue; - } - GLTFSkeletonIndex skeleton_i = _convert_skeleton(state, skeleton); - skeleton_gltf_i = skeleton_i; - ERR_CONTINUE(skeleton_gltf_i == -1); - gltf_skin->skeleton = skeleton_gltf_i; - Ref<GLTFSkeleton> gltf_skeleton = state->skeletons.write[skeleton_gltf_i]; - for (int32_t bind_i = 0; bind_i < skin->get_bind_count(); bind_i++) { - String godot_bone_name = skin->get_bind_name(bind_i); - if (godot_bone_name.is_empty()) { - int32_t bone = skin->get_bind_bone(bind_i); - godot_bone_name = skeleton->get_bone_name(bone); - } - if (skeleton->find_bone(godot_bone_name) == -1) { - godot_bone_name = skeleton->get_bone_name(0); - } - BoneId bone_index = skeleton->find_bone(godot_bone_name); - ERR_CONTINUE(bone_index == -1); - Ref<GLTFNode> joint_node; - joint_node.instantiate(); - String gltf_bone_name = _gen_unique_bone_name(state, skeleton_gltf_i, godot_bone_name); - joint_node->set_name(gltf_bone_name); - - Transform3D bone_rest_xform = skeleton->get_bone_rest(bone_index); - joint_node->scale = bone_rest_xform.basis.get_scale(); - joint_node->rotation = bone_rest_xform.basis.get_rotation_quaternion(); - joint_node->position = bone_rest_xform.origin; - joint_node->joint = true; - - int32_t joint_node_i = state->nodes.size(); - state->nodes.push_back(joint_node); - gltf_skeleton->godot_bone_node.insert(bone_index, joint_node_i); - int32_t joint_index = gltf_skin->joints.size(); - gltf_skin->joint_i_to_bone_i.insert(joint_index, bone_index); - gltf_skin->joints.push_back(joint_node_i); - gltf_skin->joints_original.push_back(joint_node_i); - gltf_skin->inverse_binds.push_back(skin->get_bind_pose(bind_i)); - json_joints.push_back(joint_node_i); - for (Map<GLTFNodeIndex, Node *>::Element *skin_scene_node_i = state->scene_nodes.front(); skin_scene_node_i; skin_scene_node_i = skin_scene_node_i->next()) { - if (skin_scene_node_i->get() == skeleton) { - gltf_skin->skin_root = skin_scene_node_i->key(); - json_skin["skeleton"] = skin_scene_node_i->key(); - } - } - gltf_skin->godot_skin = skin; - gltf_skin->set_name(_gen_unique_name(state, skin->get_name())); - } - for (int32_t bind_i = 0; bind_i < skin->get_bind_count(); bind_i++) { - String bone_name = skeleton->get_bone_name(bind_i); - String godot_bone_name = skin->get_bind_name(bind_i); - int32_t bone = -1; - if (skin->get_bind_bone(bind_i) != -1) { - bone = skin->get_bind_bone(bind_i); - godot_bone_name = skeleton->get_bone_name(bone); - } - bone = skeleton->find_bone(godot_bone_name); - if (bone == -1) { - continue; - } - BoneId bone_parent = skeleton->get_bone_parent(bone); - GLTFNodeIndex joint_node_i = gltf_skeleton->godot_bone_node[bone]; - ERR_CONTINUE(joint_node_i >= state->nodes.size()); - if (bone_parent != -1) { - GLTFNodeIndex parent_joint_gltf_node = gltf_skin->joints[bone_parent]; - Ref<GLTFNode> parent_joint_node = state->nodes.write[parent_joint_gltf_node]; - parent_joint_node->children.push_back(joint_node_i); + Node *skel_node = mi->get_node_or_null(skeleton_path); + Skeleton3D *godot_skeleton = nullptr; + if (skel_node != nullptr) { + godot_skeleton = cast_to<Skeleton3D>(skel_node); + } + if (godot_skeleton != nullptr && state->skeleton3d_to_gltf_skeleton.has(godot_skeleton->get_instance_id())) { + // This is a skinned mesh. If the mesh has no ARRAY_WEIGHTS or ARRAY_BONES, it will be invisible. + const GLTFSkeletonIndex skeleton_gltf_i = state->skeleton3d_to_gltf_skeleton[godot_skeleton->get_instance_id()]; + Ref<GLTFSkeleton> gltf_skeleton = state->skeletons[skeleton_gltf_i]; + int bone_cnt = skeleton->get_bone_count(); + ERR_FAIL_COND(bone_cnt != gltf_skeleton->joints.size()); + + ObjectID gltf_skin_key = skin->get_instance_id(); + ObjectID gltf_skel_key = godot_skeleton->get_instance_id(); + GLTFSkinIndex skin_gltf_i = -1; + GLTFNodeIndex root_gltf_i = -1; + if (!gltf_skeleton->roots.is_empty()) { + root_gltf_i = gltf_skeleton->roots[0]; + } + if (state->skin_and_skeleton3d_to_gltf_skin.has(gltf_skin_key) && state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key].has(gltf_skel_key)) { + skin_gltf_i = state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key][gltf_skel_key]; } else { - Node *node_parent = skeleton->get_parent(); - ERR_CONTINUE(!node_parent); - for (Map<GLTFNodeIndex, Node *>::Element *E = state->scene_nodes.front(); E; E = E->next()) { - if (E->get() == node_parent) { - GLTFNodeIndex gltf_node_i = E->key(); - Ref<GLTFNode> gltf_node = state->nodes.write[gltf_node_i]; - gltf_node->children.push_back(joint_node_i); - break; + if (skin.is_null()) { + // Note that gltf_skin_key should remain null, so these can share a reference. + skin = skeleton->register_skin(nullptr)->get_skin(); + } + gltf_skin.instantiate(); + gltf_skin->godot_skin = skin; + gltf_skin->set_name(skin->get_name()); + gltf_skin->skeleton = skeleton_gltf_i; + gltf_skin->skin_root = root_gltf_i; + //gltf_state->godot_to_gltf_node[skel_node] + HashMap<StringName, int> bone_name_to_idx; + for (int bone_i = 0; bone_i < bone_cnt; bone_i++) { + bone_name_to_idx[skeleton->get_bone_name(bone_i)] = bone_i; + } + for (int bind_i = 0, cnt = skin->get_bind_count(); bind_i < cnt; bind_i++) { + int bone_i = skin->get_bind_bone(bind_i); + Transform3D bind_pose = skin->get_bind_pose(bind_i); + StringName bind_name = skin->get_bind_name(bind_i); + if (bind_name != StringName()) { + bone_i = bone_name_to_idx[bind_name]; + } + ERR_CONTINUE(bone_i < 0 || bone_i >= bone_cnt); + if (bind_name == StringName()) { + bind_name = skeleton->get_bone_name(bone_i); + } + GLTFNodeIndex skeleton_bone_i = gltf_skeleton->joints[bone_i]; + gltf_skin->joints_original.push_back(skeleton_bone_i); + gltf_skin->joints.push_back(skeleton_bone_i); + gltf_skin->inverse_binds.push_back(bind_pose); + if (skeleton->get_bone_parent(bone_i) == -1) { + gltf_skin->roots.push_back(skeleton_bone_i); } + gltf_skin->joint_i_to_bone_i[bind_i] = bone_i; + gltf_skin->joint_i_to_name[bind_i] = bind_name; } + skin_gltf_i = state->skins.size(); + state->skins.push_back(gltf_skin); + state->skin_and_skeleton3d_to_gltf_skin[gltf_skin_key][gltf_skel_key] = skin_gltf_i; } + node->skin = skin_gltf_i; + node->skeleton = skeleton_gltf_i; } - _expand_skin(state, gltf_skin); - node->skin = state->skins.size(); - state->skins.push_back(gltf_skin); - - json_skin["inverseBindMatrices"] = _encode_accessor_as_xform(state, gltf_skin->inverse_binds, false); - json_skin["joints"] = json_joints; - json_skin["name"] = gltf_skin->get_name(); - json_skins.push_back(json_skin); - state->json["skins"] = json_skins; } } @@ -6129,7 +6144,6 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state for (int32_t key_i = 0; key_i < key_count; key_i++) { times.write[key_i] = p_animation->track_get_key_time(p_track_i, key_i); } - const float BAKE_FPS = 30.0f; if (track_type == Animation::TYPE_TRANSFORM3D) { p_track.position_track.times = times; p_track.position_track.interpolation = gltf_interpolation; @@ -6308,9 +6322,9 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, const Vector<String> node_suffix = String(orig_track_path).split(":position"); const NodePath path = node_suffix[0]; const Node *node = ap->get_parent()->get_node_or_null(path); - for (Map<GLTFNodeIndex, Node *>::Element *position_scene_node_i = state->scene_nodes.front(); position_scene_node_i; position_scene_node_i = position_scene_node_i->next()) { - if (position_scene_node_i->get() == node) { - GLTFNodeIndex node_index = position_scene_node_i->key(); + for (const KeyValue<GLTFNodeIndex, Node *> &position_scene_node_i : state->scene_nodes) { + if (position_scene_node_i.value == node) { + GLTFNodeIndex node_index = position_scene_node_i.key; Map<int, GLTFAnimation::Track>::Element *position_track_i = gltf_animation->get_tracks().find(node_index); GLTFAnimation::Track track; if (position_track_i) { @@ -6324,9 +6338,9 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, const Vector<String> node_suffix = String(orig_track_path).split(":rotation_degrees"); const NodePath path = node_suffix[0]; const Node *node = ap->get_parent()->get_node_or_null(path); - for (Map<GLTFNodeIndex, Node *>::Element *rotation_degree_scene_node_i = state->scene_nodes.front(); rotation_degree_scene_node_i; rotation_degree_scene_node_i = rotation_degree_scene_node_i->next()) { - if (rotation_degree_scene_node_i->get() == node) { - GLTFNodeIndex node_index = rotation_degree_scene_node_i->key(); + for (const KeyValue<GLTFNodeIndex, Node *> &rotation_degree_scene_node_i : state->scene_nodes) { + if (rotation_degree_scene_node_i.value == node) { + GLTFNodeIndex node_index = rotation_degree_scene_node_i.key; Map<int, GLTFAnimation::Track>::Element *rotation_degree_track_i = gltf_animation->get_tracks().find(node_index); GLTFAnimation::Track track; if (rotation_degree_track_i) { @@ -6340,9 +6354,9 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, const Vector<String> node_suffix = String(orig_track_path).split(":scale"); const NodePath path = node_suffix[0]; const Node *node = ap->get_parent()->get_node_or_null(path); - for (Map<GLTFNodeIndex, Node *>::Element *scale_scene_node_i = state->scene_nodes.front(); scale_scene_node_i; scale_scene_node_i = scale_scene_node_i->next()) { - if (scale_scene_node_i->get() == node) { - GLTFNodeIndex node_index = scale_scene_node_i->key(); + for (const KeyValue<GLTFNodeIndex, Node *> &scale_scene_node_i : state->scene_nodes) { + if (scale_scene_node_i.value == node) { + GLTFNodeIndex node_index = scale_scene_node_i.key; Map<int, GLTFAnimation::Track>::Element *scale_track_i = gltf_animation->get_tracks().find(node_index); GLTFAnimation::Track track; if (scale_track_i) { @@ -6356,80 +6370,69 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, const Vector<String> node_suffix = String(orig_track_path).split(":transform"); const NodePath path = node_suffix[0]; const Node *node = ap->get_parent()->get_node_or_null(path); - for (Map<GLTFNodeIndex, Node *>::Element *transform_track_i = state->scene_nodes.front(); transform_track_i; transform_track_i = transform_track_i->next()) { - if (transform_track_i->get() == node) { + for (const KeyValue<GLTFNodeIndex, Node *> &transform_track_i : state->scene_nodes) { + if (transform_track_i.value == node) { GLTFAnimation::Track track; - track = _convert_animation_track(state, track, animation, Transform3D(), track_i, transform_track_i->key()); - gltf_animation->get_tracks().insert(transform_track_i->key(), track); + track = _convert_animation_track(state, track, animation, Transform3D(), track_i, transform_track_i.key); + gltf_animation->get_tracks().insert(transform_track_i.key, track); } } } else if (String(orig_track_path).find(":blend_shapes/") != -1) { const Vector<String> node_suffix = String(orig_track_path).split(":blend_shapes/"); const NodePath path = node_suffix[0]; const String suffix = node_suffix[1]; - const Node *node = ap->get_parent()->get_node_or_null(path); - for (Map<GLTFNodeIndex, Node *>::Element *transform_track_i = state->scene_nodes.front(); transform_track_i; transform_track_i = transform_track_i->next()) { - if (transform_track_i->get() == node) { - const MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(node); - if (!mi) { - continue; - } - Ref<ArrayMesh> array_mesh = mi->get_mesh(); - if (array_mesh.is_null()) { + Node *node = ap->get_parent()->get_node_or_null(path); + MeshInstance3D *mi = cast_to<MeshInstance3D>(node); + Ref<Mesh> mesh = mi->get_mesh(); + ERR_CONTINUE(mesh.is_null()); + int32_t mesh_index = -1; + for (const KeyValue<GLTFNodeIndex, Node *> &mesh_track_i : state->scene_nodes) { + if (mesh_track_i.value == node) { + mesh_index = mesh_track_i.key; + } + } + ERR_CONTINUE(mesh_index == -1); + Map<int, GLTFAnimation::Track> &tracks = gltf_animation->get_tracks(); + GLTFAnimation::Track track = gltf_animation->get_tracks().has(mesh_index) ? gltf_animation->get_tracks()[mesh_index] : GLTFAnimation::Track(); + if (!tracks.has(mesh_index)) { + for (int32_t shape_i = 0; shape_i < mesh->get_blend_shape_count(); shape_i++) { + String shape_name = mesh->get_blend_shape_name(shape_i); + NodePath shape_path = String(path) + ":blend_shapes/" + shape_name; + int32_t shape_track_i = animation->find_track(shape_path); + if (shape_track_i == -1) { + GLTFAnimation::Channel<float> weight; + weight.interpolation = GLTFAnimation::INTERP_LINEAR; + weight.times.push_back(0.0f); + weight.times.push_back(0.0f); + weight.values.push_back(0.0f); + weight.values.push_back(0.0f); + track.weight_tracks.push_back(weight); continue; } - if (node_suffix.size() != 2) { - continue; + Animation::InterpolationType interpolation = animation->track_get_interpolation_type(track_i); + GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR; + if (interpolation == Animation::InterpolationType::INTERPOLATION_LINEAR) { + gltf_interpolation = GLTFAnimation::INTERP_LINEAR; + } else if (interpolation == Animation::InterpolationType::INTERPOLATION_NEAREST) { + gltf_interpolation = GLTFAnimation::INTERP_STEP; + } else if (interpolation == Animation::InterpolationType::INTERPOLATION_CUBIC) { + gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE; } - GLTFNodeIndex mesh_index = -1; - for (GLTFNodeIndex node_i = 0; node_i < state->scene_nodes.size(); node_i++) { - if (state->scene_nodes[node_i] == node) { - mesh_index = node_i; - break; - } + int32_t key_count = animation->track_get_key_count(shape_track_i); + GLTFAnimation::Channel<float> weight; + weight.interpolation = gltf_interpolation; + weight.times.resize(key_count); + for (int32_t time_i = 0; time_i < key_count; time_i++) { + weight.times.write[time_i] = animation->track_get_key_time(shape_track_i, time_i); } - ERR_CONTINUE(mesh_index == -1); - Ref<Mesh> mesh = mi->get_mesh(); - ERR_CONTINUE(mesh.is_null()); - for (int32_t shape_i = 0; shape_i < mesh->get_blend_shape_count(); shape_i++) { - if (mesh->get_blend_shape_name(shape_i) != suffix) { - continue; - } - GLTFAnimation::Track track; - Map<int, GLTFAnimation::Track>::Element *blend_shape_track_i = gltf_animation->get_tracks().find(mesh_index); - if (blend_shape_track_i) { - track = blend_shape_track_i->get(); - } - Animation::InterpolationType interpolation = animation->track_get_interpolation_type(track_i); - - GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - if (interpolation == Animation::InterpolationType::INTERPOLATION_LINEAR) { - gltf_interpolation = GLTFAnimation::INTERP_LINEAR; - } else if (interpolation == Animation::InterpolationType::INTERPOLATION_NEAREST) { - gltf_interpolation = GLTFAnimation::INTERP_STEP; - } else if (interpolation == Animation::InterpolationType::INTERPOLATION_CUBIC) { - gltf_interpolation = GLTFAnimation::INTERP_CUBIC_SPLINE; - } - Animation::TrackType track_type = animation->track_get_type(track_i); - if (track_type == Animation::TYPE_VALUE) { - int32_t key_count = animation->track_get_key_count(track_i); - GLTFAnimation::Channel<float> weight; - weight.interpolation = gltf_interpolation; - weight.times.resize(key_count); - for (int32_t time_i = 0; time_i < key_count; time_i++) { - weight.times.write[time_i] = animation->track_get_key_time(track_i, time_i); - } - weight.values.resize(key_count); - for (int32_t value_i = 0; value_i < key_count; value_i++) { - weight.values.write[value_i] = animation->track_get_key_value(track_i, value_i); - } - track.weight_tracks.push_back(weight); - } - gltf_animation->get_tracks()[mesh_index] = track; + weight.values.resize(key_count); + for (int32_t value_i = 0; value_i < key_count; value_i++) { + weight.values.write[value_i] = animation->track_get_key_value(shape_track_i, value_i); } + track.weight_tracks.push_back(weight); } + tracks[mesh_index] = track; } - } else if (String(orig_track_path).find(":") != -1) { //Process skeleton const Vector<String> node_suffix = String(orig_track_path).split(":"); @@ -6466,9 +6469,9 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, for (int32_t node_i = 0; node_i < ap->get_parent()->get_child_count(); node_i++) { const Node *child = ap->get_parent()->get_child(node_i); const Node *node = child->get_node_or_null(orig_track_path); - for (Map<GLTFNodeIndex, Node *>::Element *scene_node_i = state->scene_nodes.front(); scene_node_i; scene_node_i = scene_node_i->next()) { - if (scene_node_i->get() == node) { - GLTFNodeIndex node_index = scene_node_i->key(); + for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : state->scene_nodes) { + if (scene_node_i.value == node) { + GLTFNodeIndex node_index = scene_node_i.key; Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index); GLTFAnimation::Track track; if (node_track_i) { diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index fb798a055a..18aeb81bc0 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -51,6 +51,9 @@ class GLTFSkin; class GLTFNode; class GLTFSpecGloss; class GLTFSkeleton; +class CSGShape3D; +class GridMap; +class MultiMeshInstance3D; using GLTFAccessorIndex = int; using GLTFAnimationIndex = int; @@ -72,6 +75,9 @@ class GLTFDocument : public Resource { friend class GLTFSkin; friend class GLTFSkeleton; +private: + const float BAKE_FPS = 30.0f; + public: const int32_t JOINT_GROUP_SIZE = 4; enum GLTFType { @@ -350,7 +356,6 @@ private: GLTFNodeIndex p_node_i); Error _encode_buffer_bins(Ref<GLTFState> state, const String &p_path); Error _encode_buffer_glb(Ref<GLTFState> state, const String &p_path); - Error _serialize_bone_attachment(Ref<GLTFState> state); Dictionary _serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material); Dictionary _serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material); Error _serialize_version(Ref<GLTFState> state); @@ -381,20 +386,17 @@ public: void _generate_skeleton_bone_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index); void _import_animation(Ref<GLTFState> state, AnimationPlayer *ap, const GLTFAnimationIndex index, const int bake_fps); - GLTFMeshIndex _convert_mesh_instance(Ref<GLTFState> state, - MeshInstance3D *p_mesh_instance); void _convert_mesh_instances(Ref<GLTFState> state); GLTFCameraIndex _convert_camera(Ref<GLTFState> state, Camera3D *p_camera); - void _convert_light_to_gltf(Light3D *light, Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node); + void _convert_light_to_gltf(Light3D *light, Ref<GLTFState> state, Ref<GLTFNode> gltf_node); GLTFLightIndex _convert_light(Ref<GLTFState> state, Light3D *p_light); - GLTFSkeletonIndex _convert_skeleton(Ref<GLTFState> state, Skeleton3D *p_skeleton); void _convert_spatial(Ref<GLTFState> state, Node3D *p_spatial, Ref<GLTFNode> p_node); - void _convert_scene_node(Ref<GLTFState> state, Node *p_current, Node *p_root, + void _convert_scene_node(Ref<GLTFState> state, Node *p_current, const GLTFNodeIndex p_gltf_current, const GLTFNodeIndex p_gltf_root); #ifdef MODULE_CSG_ENABLED - void _convert_csg_shape_to_gltf(Node *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state); + void _convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> gltf_node, Ref<GLTFState> state); #endif // MODULE_CSG_ENABLED void _create_gltf_node(Ref<GLTFState> state, @@ -405,40 +407,39 @@ public: Ref<GLTFNode> gltf_node); void _convert_animation_player_to_gltf( AnimationPlayer *animation_player, Ref<GLTFState> state, - const GLTFNodeIndex &p_gltf_current, - const GLTFNodeIndex &p_gltf_root_index, - Ref<GLTFNode> p_gltf_node, Node *p_scene_parent, - Node *p_root); + GLTFNodeIndex p_gltf_current, + GLTFNodeIndex p_gltf_root_index, + Ref<GLTFNode> p_gltf_node, Node *p_scene_parent); void _check_visibility(Node *p_node, bool &retflag); void _convert_camera_to_gltf(Camera3D *camera, Ref<GLTFState> state, - Node3D *spatial, Ref<GLTFNode> gltf_node); #ifdef MODULE_GRIDMAP_ENABLED void _convert_grid_map_to_gltf( - Node *p_scene_parent, - const GLTFNodeIndex &p_parent_node_index, - const GLTFNodeIndex &p_root_node_index, - Ref<GLTFNode> gltf_node, Ref<GLTFState> state, - Node *p_root_node); + GridMap *p_grid_map, + GLTFNodeIndex p_parent_node_index, + GLTFNodeIndex p_root_node_index, + Ref<GLTFNode> gltf_node, Ref<GLTFState> state); #endif // MODULE_GRIDMAP_ENABLED void _convert_mult_mesh_instance_to_gltf( - Node *p_scene_parent, - const GLTFNodeIndex &p_parent_node_index, - const GLTFNodeIndex &p_root_node_index, - Ref<GLTFNode> gltf_node, Ref<GLTFState> state, - Node *p_root_node); + MultiMeshInstance3D *p_scene_parent, + GLTFNodeIndex p_parent_node_index, + GLTFNodeIndex p_root_node_index, + Ref<GLTFNode> gltf_node, Ref<GLTFState> state); void _convert_skeleton_to_gltf( - Node *p_scene_parent, Ref<GLTFState> state, - const GLTFNodeIndex &p_parent_node_index, - const GLTFNodeIndex &p_root_node_index, - Ref<GLTFNode> gltf_node, Node *p_root_node); - void _convert_bone_attachment_to_gltf(Node *p_scene_parent, + Skeleton3D *p_scene_parent, Ref<GLTFState> state, + GLTFNodeIndex p_parent_node_index, + GLTFNodeIndex p_root_node_index, + Ref<GLTFNode> gltf_node); + void _convert_bone_attachment_to_gltf(BoneAttachment3D *p_bone_attachment, + Ref<GLTFState> state, + GLTFNodeIndex p_parent_node_index, + GLTFNodeIndex p_root_node_index, + Ref<GLTFNode> gltf_node); + void _convert_mesh_instance_to_gltf(MeshInstance3D *p_mesh_instance, Ref<GLTFState> state, - Ref<GLTFNode> gltf_node, - bool &retflag); - void _convert_mesh_to_gltf(Node *p_scene_parent, - Ref<GLTFState> state, Node3D *spatial, Ref<GLTFNode> gltf_node); + GLTFMeshIndex _convert_mesh_to_gltf(Ref<GLTFState> state, + MeshInstance3D *p_mesh_instance); void _convert_animation(Ref<GLTFState> state, AnimationPlayer *ap, String p_animation_track_name); Error serialize(Ref<GLTFState> state, Node *p_root, const String &p_path); diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 896ea5fc56..d6614da804 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -44,6 +44,8 @@ #include "gltf_texture.h" #include "core/io/resource.h" +#include "core/templates/map.h" +#include "core/templates/pair.h" #include "core/templates/vector.h" #include "scene/animation/animation_player.h" #include "scene/resources/texture.h" @@ -87,6 +89,9 @@ class GLTFState : public Resource { Vector<Ref<GLTFAnimation>> animations; Map<GLTFNodeIndex, Node *> scene_nodes; + Map<ObjectID, GLTFSkeletonIndex> skeleton3d_to_gltf_skeleton; + Map<ObjectID, Map<ObjectID, GLTFSkinIndex>> skin_and_skeleton3d_to_gltf_skin; + protected: static void _bind_methods(); diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 116c0e00f9..c9d8f2b42b 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -420,8 +420,8 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } //erase navigation - for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) { - NavigationServer3D::get_singleton()->free(E->get().region); + for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { + NavigationServer3D::get_singleton()->free(E.value.region); } g.navmesh_ids.clear(); @@ -512,15 +512,15 @@ bool GridMap::_octant_update(const OctantKey &p_key) { //update multimeshes, only if not baked if (baked_meshes.size() == 0) { - for (Map<int, List<Pair<Transform3D, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) { + for (const KeyValue<int, List<Pair<Transform3D, IndexKey>>> &E : multimesh_items) { Octant::MultimeshInstance mmi; RID mm = RS::get_singleton()->multimesh_create(); - RS::get_singleton()->multimesh_allocate_data(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D); - RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); + RS::get_singleton()->multimesh_allocate_data(mm, E.value.size(), RS::MULTIMESH_TRANSFORM_3D); + RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E.key)->get_rid()); int idx = 0; - for (const Pair<Transform3D, IndexKey> &F : E->get()) { + for (const Pair<Transform3D, IndexKey> &F : E.value) { RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F.first); #ifdef TOOLS_ENABLED @@ -567,9 +567,9 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } void GridMap::_reset_physic_bodies_collision_filters() { - for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { - PhysicsServer3D::get_singleton()->body_set_collision_layer(E->get()->static_body, collision_layer); - PhysicsServer3D::get_singleton()->body_set_collision_mask(E->get()->static_body, collision_mask); + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { + PhysicsServer3D::get_singleton()->body_set_collision_layer(E.value->static_body, collision_layer); + PhysicsServer3D::get_singleton()->body_set_collision_mask(E.value->static_body, collision_mask); } } @@ -590,17 +590,17 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { } if (bake_navigation && mesh_library.is_valid()) { - for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { - if (cell_map.has(F->key()) && F->get().region.is_valid() == false) { - Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item); + for (KeyValue<IndexKey, Octant::NavMesh> &F : g.navmesh_ids) { + if (cell_map.has(F.key) && F.value.region.is_valid() == false) { + Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F.key].item); if (nm.is_valid()) { RID region = NavigationServer3D::get_singleton()->region_create(); NavigationServer3D::get_singleton()->region_set_layers(region, navigation_layers); NavigationServer3D::get_singleton()->region_set_navmesh(region, nm); - NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F->get().xform); + NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F.value.xform); NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); - F->get().region = region; + F.value.region = region; } } } @@ -621,10 +621,10 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID()); } - for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { - if (F->get().region.is_valid()) { - NavigationServer3D::get_singleton()->free(F->get().region); - F->get().region = RID(); + for (KeyValue<IndexKey, Octant::NavMesh> &F : g.navmesh_ids) { + if (F.value.region.is_valid()) { + NavigationServer3D::get_singleton()->free(F.value.region); + F.value.region = RID(); } } } @@ -643,8 +643,8 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { PhysicsServer3D::get_singleton()->free(g.static_body); // Erase navigation - for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) { - NavigationServer3D::get_singleton()->free(E->get().region); + for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { + NavigationServer3D::get_singleton()->free(E.value.region); } g.navmesh_ids.clear(); @@ -662,8 +662,8 @@ void GridMap::_notification(int p_what) { case NOTIFICATION_ENTER_WORLD: { last_transform = get_global_transform(); - for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { - _octant_enter_world(E->key()); + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { + _octant_enter_world(E.key); } for (int i = 0; i < baked_meshes.size(); i++) { @@ -678,8 +678,8 @@ void GridMap::_notification(int p_what) { break; } //update run - for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { - _octant_transform(E->key()); + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { + _octant_transform(E.key); } last_transform = new_xform; @@ -689,8 +689,8 @@ void GridMap::_notification(int p_what) { } } break; case NOTIFICATION_EXIT_WORLD: { - for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { - _octant_exit_world(E->key()); + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { + _octant_exit_world(E.key); } //_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS); @@ -712,8 +712,8 @@ void GridMap::_update_visibility() { return; } - for (Map<OctantKey, Octant *>::Element *e = octant_map.front(); e; e = e->next()) { - Octant *octant = e->value(); + for (KeyValue<OctantKey, Octant *> &e : octant_map) { + Octant *octant = e.value; for (int i = 0; i < octant->multimesh_instances.size(); i++) { const Octant::MultimeshInstance &mi = octant->multimesh_instances[i]; RS::get_singleton()->instance_set_visible(mi.instance, is_visible_in_tree()); @@ -738,20 +738,20 @@ void GridMap::_recreate_octant_data() { recreating_octants = true; Map<IndexKey, Cell> cell_copy = cell_map; _clear_internal(); - for (Map<IndexKey, Cell>::Element *E = cell_copy.front(); E; E = E->next()) { - set_cell_item(Vector3i(E->key()), E->get().item, E->get().rot); + for (const KeyValue<IndexKey, Cell> &E : cell_copy) { + set_cell_item(Vector3i(E.key), E.value.item, E.value.rot); } recreating_octants = false; } void GridMap::_clear_internal() { - for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { if (is_inside_world()) { - _octant_exit_world(E->key()); + _octant_exit_world(E.key); } - _octant_clean_up(E->key()); - memdelete(E->get()); + _octant_clean_up(E.key); + memdelete(E.value); } octant_map.clear(); @@ -773,9 +773,9 @@ void GridMap::_update_octants_callback() { } List<OctantKey> to_delete; - for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { - if (_octant_update(E->key())) { - to_delete.push_back(E->key()); + for (const KeyValue<OctantKey, Octant *> &E : octant_map) { + if (_octant_update(E.key)) { + to_delete.push_back(E.key); } } @@ -883,8 +883,8 @@ void GridMap::set_clip(bool p_enabled, bool p_clip_above, int p_floor, Vector3:: clip_above = p_clip_above; //make it all update - for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { - Octant *g = E->get(); + for (KeyValue<OctantKey, Octant *> &E : octant_map) { + Octant *g = E.value; g->dirty = true; } awaiting_update = true; @@ -904,8 +904,8 @@ Array GridMap::get_used_cells() const { Array a; a.resize(cell_map.size()); int i = 0; - for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) { - Vector3 p(E->key().x, E->key().y, E->key().z); + for (const KeyValue<IndexKey, Cell> &E : cell_map) { + Vector3 p(E.key.x, E.key.y, E.key.z); a[i++] = p; } @@ -920,8 +920,8 @@ Array GridMap::get_meshes() { Vector3 ofs = _get_offset(); Array meshes; - for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) { - int id = E->get().item; + for (KeyValue<IndexKey, Cell> &E : cell_map) { + int id = E.value.item; if (!mesh_library->has_item(id)) { continue; } @@ -930,13 +930,13 @@ Array GridMap::get_meshes() { continue; } - IndexKey ik = E->key(); + IndexKey ik = E.key; Vector3 cellpos = Vector3(ik.x, ik.y, ik.z); Transform3D xform; - xform.basis.set_orthogonal_index(E->get().rot); + xform.basis.set_orthogonal_index(E.value.rot); xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); @@ -972,10 +972,10 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe //generate Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>> surface_map; - for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) { - IndexKey key = E->key(); + for (KeyValue<IndexKey, Cell> &E : cell_map) { + IndexKey key = E.key; - int item = E->get().item; + int item = E.value.item; if (!mesh_library->has_item(item)) { continue; } @@ -990,7 +990,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe Transform3D xform; - xform.basis.set_orthogonal_index(E->get().rot); + xform.basis.set_orthogonal_index(E.value.rot); xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); @@ -1023,11 +1023,11 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe } } - for (Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>>::Element *E = surface_map.front(); E; E = E->next()) { + for (KeyValue<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>> &E : surface_map) { Ref<ArrayMesh> mesh; mesh.instantiate(); - for (Map<Ref<Material>, Ref<SurfaceTool>>::Element *F = E->get().front(); F; F = F->next()) { - F->get()->commit(mesh); + for (KeyValue<Ref<Material>, Ref<SurfaceTool>> &F : E.value) { + F.value->commit(mesh); } BakedMesh bm; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index af7c54dd5b..247eee4280 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -3511,8 +3511,8 @@ int CSharpScript::get_member_line(const StringName &p_member) const { } Multiplayer::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const { - if (p_member->has_attribute(CACHED_CLASS(AnyAttribute))) { - return Multiplayer::RPC_MODE_ANY; + if (p_member->has_attribute(CACHED_CLASS(AnyPeerAttribute))) { + return Multiplayer::RPC_MODE_ANY_PEER; } if (p_member->has_attribute(CACHED_CLASS(AuthorityAttribute))) { return Multiplayer::RPC_MODE_AUTHORITY; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs index 1da91ea867..b8b9bc660c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs @@ -3,7 +3,7 @@ using System; namespace Godot { [AttributeUsage(AttributeTargets.Method)] - public class AnyAttribute : Attribute { } + public class AnyPeerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] public class AuthorityAttribute : Attribute { } diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 34e845a589..2bf55493e0 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -140,7 +140,7 @@ void CachedData::clear_godot_api_cache() { field_ExportAttribute_hintString = nullptr; class_SignalAttribute = nullptr; class_ToolAttribute = nullptr; - class_AnyAttribute = nullptr; + class_AnyPeerAttribute = nullptr; class_AuthorityAttribute = nullptr; class_GodotMethodAttribute = nullptr; field_GodotMethodAttribute_methodName = nullptr; @@ -265,7 +265,7 @@ void update_godot_api_cache() { CACHE_FIELD_AND_CHECK(ExportAttribute, hintString, CACHED_CLASS(ExportAttribute)->get_field("hintString")); CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute)); CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute)); - CACHE_CLASS_AND_CHECK(AnyAttribute, GODOT_API_CLASS(AnyAttribute)); + CACHE_CLASS_AND_CHECK(AnyPeerAttribute, GODOT_API_CLASS(AnyPeerAttribute)); CACHE_CLASS_AND_CHECK(AuthorityAttribute, GODOT_API_CLASS(AuthorityAttribute)); CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute)); CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName")); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index e60a4d5279..4b4688b4d9 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -111,7 +111,7 @@ struct CachedData { GDMonoField *field_ExportAttribute_hintString; GDMonoClass *class_SignalAttribute; GDMonoClass *class_ToolAttribute; - GDMonoClass *class_AnyAttribute; + GDMonoClass *class_AnyPeerAttribute; GDMonoClass *class_AuthorityAttribute; GDMonoClass *class_GodotMethodAttribute; GDMonoField *field_GodotMethodAttribute_methodName; diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index fd965674d6..f600f07c87 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -133,13 +133,13 @@ RID GodotNavigationServer::map_create() const { GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this); MutexLock lock(mut_this->operations_mutex); RID rid = map_owner.make_rid(); - NavMap *space = map_owner.getornull(rid); + NavMap *space = map_owner.get_or_null(rid); space->set_self(rid); return rid; } COMMAND_2(map_set_active, RID, p_map, bool, p_active) { - NavMap *map = map_owner.getornull(p_map); + NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND(map == nullptr); if (p_active) { @@ -156,84 +156,84 @@ COMMAND_2(map_set_active, RID, p_map, bool, p_active) { } bool GodotNavigationServer::map_is_active(RID p_map) const { - NavMap *map = map_owner.getornull(p_map); + NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, false); return active_maps.find(map) >= 0; } COMMAND_2(map_set_up, RID, p_map, Vector3, p_up) { - NavMap *map = map_owner.getornull(p_map); + NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND(map == nullptr); map->set_up(p_up); } Vector3 GodotNavigationServer::map_get_up(RID p_map) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, Vector3()); return map->get_up(); } COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size) { - NavMap *map = map_owner.getornull(p_map); + NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND(map == nullptr); map->set_cell_size(p_cell_size); } real_t GodotNavigationServer::map_get_cell_size(RID p_map) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, 0); return map->get_cell_size(); } COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin) { - NavMap *map = map_owner.getornull(p_map); + NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND(map == nullptr); map->set_edge_connection_margin(p_connection_margin); } real_t GodotNavigationServer::map_get_edge_connection_margin(RID p_map) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, 0); return map->get_edge_connection_margin(); } Vector<Vector3> GodotNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>()); return map->get_path(p_origin, p_destination, p_optimize, p_layers); } Vector3 GodotNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, Vector3()); return map->get_closest_point_to_segment(p_from, p_to, p_use_collision); } Vector3 GodotNavigationServer::map_get_closest_point(RID p_map, const Vector3 &p_point) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, Vector3()); return map->get_closest_point(p_point); } Vector3 GodotNavigationServer::map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, Vector3()); return map->get_closest_point_normal(p_point); } RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const { - const NavMap *map = map_owner.getornull(p_map); + const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, RID()); return map->get_closest_point_owner(p_point); @@ -243,13 +243,13 @@ RID GodotNavigationServer::region_create() const { GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this); MutexLock lock(mut_this->operations_mutex); RID rid = region_owner.make_rid(); - NavRegion *reg = region_owner.getornull(rid); + NavRegion *reg = region_owner.get_or_null(rid); reg->set_self(rid); return rid; } COMMAND_2(region_set_map, RID, p_region, RID, p_map) { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND(region == nullptr); if (region->get_map() != nullptr) { @@ -262,7 +262,7 @@ COMMAND_2(region_set_map, RID, p_region, RID, p_map) { } if (p_map.is_valid()) { - NavMap *map = map_owner.getornull(p_map); + NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND(map == nullptr); map->add_region(region); @@ -271,28 +271,28 @@ COMMAND_2(region_set_map, RID, p_region, RID, p_map) { } COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform) { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND(region == nullptr); region->set_transform(p_transform); } COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers) { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND(region == nullptr); region->set_layers(p_layers); } uint32_t GodotNavigationServer::region_get_layers(RID p_region) const { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND_V(region == nullptr, 0); return region->get_layers(); } COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh) { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND(region == nullptr); region->set_mesh(p_nav_mesh); @@ -309,21 +309,21 @@ void GodotNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node } int GodotNavigationServer::region_get_connections_count(RID p_region) const { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND_V(!region, 0); return region->get_connections_count(); } Vector3 GodotNavigationServer::region_get_connection_pathway_start(RID p_region, int p_connection_id) const { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND_V(!region, Vector3()); return region->get_connection_pathway_start(p_connection_id); } Vector3 GodotNavigationServer::region_get_connection_pathway_end(RID p_region, int p_connection_id) const { - NavRegion *region = region_owner.getornull(p_region); + NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND_V(!region, Vector3()); return region->get_connection_pathway_end(p_connection_id); @@ -333,13 +333,13 @@ RID GodotNavigationServer::agent_create() const { GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this); MutexLock lock(mut_this->operations_mutex); RID rid = agent_owner.make_rid(); - RvoAgent *agent = agent_owner.getornull(rid); + RvoAgent *agent = agent_owner.get_or_null(rid); agent->set_self(rid); return rid; } COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); if (agent->get_map()) { @@ -353,7 +353,7 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { agent->set_map(nullptr); if (p_map.is_valid()) { - NavMap *map = map_owner.getornull(p_map); + NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND(map == nullptr); agent->set_map(map); @@ -366,77 +366,77 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { } COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->neighborDist_ = p_dist; } COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->maxNeighbors_ = p_count; } COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->timeHorizon_ = p_time; } COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->radius_ = p_radius; } COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->maxSpeed_ = p_max_speed; } COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->velocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); } COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->prefVelocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); } COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->position_ = RVO::Vector3(p_position.x, p_position.y, p_position.z); } COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->ignore_y_ = p_ignore; } bool GodotNavigationServer::agent_is_map_changed(RID p_agent) const { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND_V(agent == nullptr, false); return agent->is_map_changed(); } COMMAND_4(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata) { - RvoAgent *agent = agent_owner.getornull(p_agent); + RvoAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->set_callback(p_receiver == nullptr ? ObjectID() : p_receiver->get_instance_id(), p_method, p_udata); @@ -452,7 +452,7 @@ COMMAND_4(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_ COMMAND_1(free, RID, p_object) { if (map_owner.owns(p_object)) { - NavMap *map = map_owner.getornull(p_object); + NavMap *map = map_owner.get_or_null(p_object); // Removes any assigned region std::vector<NavRegion *> regions = map->get_regions(); @@ -474,7 +474,7 @@ COMMAND_1(free, RID, p_object) { map_owner.free(p_object); } else if (region_owner.owns(p_object)) { - NavRegion *region = region_owner.getornull(p_object); + NavRegion *region = region_owner.get_or_null(p_object); // Removes this region from the map if assigned if (region->get_map() != nullptr) { @@ -485,7 +485,7 @@ COMMAND_1(free, RID, p_object) { region_owner.free(p_object); } else if (agent_owner.owns(p_object)) { - RvoAgent *agent = agent_owner.getornull(p_object); + RvoAgent *agent = agent_owner.get_or_null(p_object); // Removes this agent from the map if assigned if (agent->get_map() != nullptr) { diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 962bf79150..0c8f0ed8c9 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -613,17 +613,17 @@ void NavMap::sync() { } Vector<gd::Edge::Connection> free_edges; - for (Map<gd::EdgeKey, Vector<gd::Edge::Connection>>::Element *E = connections.front(); E; E = E->next()) { - if (E->get().size() == 2) { + for (KeyValue<gd::EdgeKey, Vector<gd::Edge::Connection>> &E : connections) { + if (E.value.size() == 2) { // Connect edge that are shared in different polygons. - gd::Edge::Connection &c1 = E->get().write[0]; - gd::Edge::Connection &c2 = E->get().write[1]; + gd::Edge::Connection &c1 = E.value.write[0]; + gd::Edge::Connection &c2 = E.value.write[1]; c1.polygon->edges[c1.edge].connections.push_back(c2); c2.polygon->edges[c2.edge].connections.push_back(c1); // Note: The pathway_start/end are full for those connection and do not need to be modified. } else { - CRASH_COND_MSG(E->get().size() != 1, vformat("Number of connection != 1. Found: %d", E->get().size())); - free_edges.push_back(E->get()[0]); + CRASH_COND_MSG(E.value.size() != 1, vformat("Number of connection != 1. Found: %d", E.value.size())); + free_edges.push_back(E.value[0]); } } diff --git a/modules/raycast/SCsub b/modules/raycast/SCsub index 4820cf7608..ef4c598194 100644 --- a/modules/raycast/SCsub +++ b/modules/raycast/SCsub @@ -87,6 +87,20 @@ if env["builtin_embree"]: # Embree needs those, it will automatically use SSE2NEON in ARM env_thirdparty.Append(CPPDEFINES=["__SSE2__", "__SSE__"]) + if not env.msvc: + env_thirdparty.Append( + CPPFLAGS=[ + "-fno-strict-overflow", + "-fno-delete-null-pointer-checks", + "-fwrapv", + "-fsigned-char", + "-fno-strict-aliasing", + "-fno-tree-vectorize", + "-fvisibility=hidden", + "-fvisibility-inlines-hidden", + ] + ) + env.modules_sources += thirdparty_obj diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster.cpp index 0583acc119..fdcf509da8 100644 --- a/modules/raycast/lightmap_raycaster.cpp +++ b/modules/raycast/lightmap_raycaster.cpp @@ -168,7 +168,7 @@ void LightmapRaycasterEmbree::clear_mesh_filter() { filter_meshes.clear(); } -void embree_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { +void embree_lm_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { print_error("Embree error: " + String(p_str)); } @@ -179,16 +179,11 @@ LightmapRaycasterEmbree::LightmapRaycasterEmbree() { #endif embree_device = rtcNewDevice(nullptr); - rtcSetDeviceErrorFunction(embree_device, &embree_error_handler, nullptr); + rtcSetDeviceErrorFunction(embree_device, &embree_lm_error_handler, nullptr); embree_scene = rtcNewScene(embree_device); } LightmapRaycasterEmbree::~LightmapRaycasterEmbree() { -#ifdef __SSE2__ - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_OFF); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_OFF); -#endif - if (embree_scene != nullptr) { rtcReleaseScene(embree_scene); } diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster.h index 4c3de27837..290b0a1cf3 100644 --- a/modules/raycast/lightmap_raycaster.h +++ b/modules/raycast/lightmap_raycaster.h @@ -30,9 +30,9 @@ #ifdef TOOLS_ENABLED +#include "core/io/image.h" #include "core/object/object.h" #include "scene/3d/lightmapper.h" -#include "scene/resources/mesh.h" #include <embree3/rtcore.h> diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index a55b81c05d..75491c98e5 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -41,9 +41,14 @@ RaycastOcclusionCull *RaycastOcclusionCull::raycast_singleton = nullptr; void RaycastOcclusionCull::RaycastHZBuffer::clear() { HZBuffer::clear(); - camera_rays.clear(); + if (camera_rays_unaligned_buffer) { + memfree(camera_rays_unaligned_buffer); + camera_rays_unaligned_buffer = nullptr; + camera_rays = nullptr; + } camera_ray_masks.clear(); - packs_size = Size2i(); + camera_rays_tile_count = 0; + tile_grid_size = Size2i(); } void RaycastOcclusionCull::RaycastHZBuffer::resize(const Size2i &p_size) { @@ -58,10 +63,19 @@ void RaycastOcclusionCull::RaycastHZBuffer::resize(const Size2i &p_size) { HZBuffer::resize(p_size); - packs_size = Size2i(Math::ceil(p_size.x / (float)TILE_SIZE), Math::ceil(p_size.y / (float)TILE_SIZE)); - int ray_packets_count = packs_size.x * packs_size.y; - camera_rays.resize(ray_packets_count); - camera_ray_masks.resize(ray_packets_count * TILE_SIZE * TILE_SIZE); + tile_grid_size = Size2i(Math::ceil(p_size.x / (float)TILE_SIZE), Math::ceil(p_size.y / (float)TILE_SIZE)); + camera_rays_tile_count = tile_grid_size.x * tile_grid_size.y; + + if (camera_rays_unaligned_buffer) { + memfree(camera_rays_unaligned_buffer); + } + + const int alignment = 64; // Embree requires ray packets to be 64-aligned + camera_rays_unaligned_buffer = (uint8_t *)memalloc(camera_rays_tile_count * sizeof(CameraRayTile) + alignment); + camera_rays = (CameraRayTile *)(camera_rays_unaligned_buffer + alignment - (((uint64_t)camera_rays_unaligned_buffer) % alignment)); + + camera_ray_masks.resize(camera_rays_tile_count * TILE_RAYS); + memset(camera_ray_masks.ptr(), ~0, camera_rays_tile_count * TILE_RAYS * sizeof(uint32_t)); } void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool) { @@ -96,65 +110,55 @@ void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D } void RaycastOcclusionCull::RaycastHZBuffer::_camera_rays_threaded(uint32_t p_thread, const CameraRayThreadData *p_data) { - uint32_t packs_total = camera_rays.size(); + uint32_t total_tiles = camera_rays_tile_count; uint32_t total_threads = p_data->thread_count; - uint32_t from = p_thread * packs_total / total_threads; - uint32_t to = (p_thread + 1 == total_threads) ? packs_total : ((p_thread + 1) * packs_total / total_threads); + uint32_t from = p_thread * total_tiles / total_threads; + uint32_t to = (p_thread + 1 == total_threads) ? total_tiles : ((p_thread + 1) * total_tiles / total_threads); _generate_camera_rays(p_data, from, to); } void RaycastOcclusionCull::RaycastHZBuffer::_generate_camera_rays(const CameraRayThreadData *p_data, int p_from, int p_to) { const Size2i &buffer_size = sizes[0]; - RayPacket *ray_packets = camera_rays.ptr(); - uint32_t *ray_masks = camera_ray_masks.ptr(); - for (int i = p_from; i < p_to; i++) { - RayPacket &packet = ray_packets[i]; - int tile_x = (i % packs_size.x) * TILE_SIZE; - int tile_y = (i / packs_size.x) * TILE_SIZE; + CameraRayTile &tile = camera_rays[i]; + int tile_x = (i % tile_grid_size.x) * TILE_SIZE; + int tile_y = (i / tile_grid_size.x) * TILE_SIZE; for (int j = 0; j < TILE_RAYS; j++) { int x = tile_x + j % TILE_SIZE; int y = tile_y + j / TILE_SIZE; - if (x >= buffer_size.x || y >= buffer_size.y) { - ray_masks[i * TILE_RAYS + j] = 0U; - continue; - } - - ray_masks[i * TILE_RAYS + j] = ~0U; - float u = (float(x) + 0.5f) / buffer_size.x; float v = (float(y) + 0.5f) / buffer_size.y; Vector3 pixel_pos = p_data->pixel_corner + u * p_data->pixel_u_interp + v * p_data->pixel_v_interp; - packet.ray.tnear[j] = p_data->z_near; + tile.ray.tnear[j] = p_data->z_near; Vector3 dir; if (p_data->camera_orthogonal) { dir = -p_data->camera_dir; - packet.ray.org_x[j] = pixel_pos.x - dir.x * p_data->z_near; - packet.ray.org_y[j] = pixel_pos.y - dir.y * p_data->z_near; - packet.ray.org_z[j] = pixel_pos.z - dir.z * p_data->z_near; + tile.ray.org_x[j] = pixel_pos.x - dir.x * p_data->z_near; + tile.ray.org_y[j] = pixel_pos.y - dir.y * p_data->z_near; + tile.ray.org_z[j] = pixel_pos.z - dir.z * p_data->z_near; } else { dir = (pixel_pos - p_data->camera_pos).normalized(); - packet.ray.org_x[j] = p_data->camera_pos.x; - packet.ray.org_y[j] = p_data->camera_pos.y; - packet.ray.org_z[j] = p_data->camera_pos.z; - packet.ray.tnear[j] /= dir.dot(p_data->camera_dir); + tile.ray.org_x[j] = p_data->camera_pos.x; + tile.ray.org_y[j] = p_data->camera_pos.y; + tile.ray.org_z[j] = p_data->camera_pos.z; + tile.ray.tnear[j] /= dir.dot(p_data->camera_dir); } - packet.ray.dir_x[j] = dir.x; - packet.ray.dir_y[j] = dir.y; - packet.ray.dir_z[j] = dir.z; + tile.ray.dir_x[j] = dir.x; + tile.ray.dir_y[j] = dir.y; + tile.ray.dir_z[j] = dir.z; - packet.ray.tfar[j] = p_data->z_far; - packet.ray.time[j] = 0.0f; + tile.ray.tfar[j] = p_data->z_far; + tile.ray.time[j] = 0.0f; - packet.ray.flags[j] = 0; - packet.ray.mask[j] = -1; - packet.hit.geomID[j] = RTC_INVALID_GEOMETRY_ID; + tile.ray.flags[j] = 0; + tile.ray.mask[j] = ~0U; + tile.hit.geomID[j] = RTC_INVALID_GEOMETRY_ID; } } } @@ -163,8 +167,8 @@ void RaycastOcclusionCull::RaycastHZBuffer::sort_rays(const Vector3 &p_camera_di ERR_FAIL_COND(is_empty()); Size2i buffer_size = sizes[0]; - for (int i = 0; i < packs_size.y; i++) { - for (int j = 0; j < packs_size.x; j++) { + for (int i = 0; i < tile_grid_size.y; i++) { + for (int j = 0; j < tile_grid_size.x; j++) { for (int tile_i = 0; tile_i < TILE_SIZE; tile_i++) { for (int tile_j = 0; tile_j < TILE_SIZE; tile_j++) { int x = j * TILE_SIZE + tile_j; @@ -173,13 +177,13 @@ void RaycastOcclusionCull::RaycastHZBuffer::sort_rays(const Vector3 &p_camera_di continue; } int k = tile_i * TILE_SIZE + tile_j; - int packet_index = i * packs_size.x + j; - float d = camera_rays[packet_index].ray.tfar[k]; + int tile_index = i * tile_grid_size.x + j; + float d = camera_rays[tile_index].ray.tfar[k]; if (!p_orthogonal) { - const float &dir_x = camera_rays[packet_index].ray.dir_x[k]; - const float &dir_y = camera_rays[packet_index].ray.dir_y[k]; - const float &dir_z = camera_rays[packet_index].ray.dir_z[k]; + const float &dir_x = camera_rays[tile_index].ray.dir_x[k]; + const float &dir_y = camera_rays[tile_index].ray.dir_y[k]; + const float &dir_z = camera_rays[tile_index].ray.dir_z[k]; float cos_theta = p_camera_dir.x * dir_x + p_camera_dir.y * dir_y + p_camera_dir.z * dir_z; d *= cos_theta; } @@ -191,6 +195,12 @@ void RaycastOcclusionCull::RaycastHZBuffer::sort_rays(const Vector3 &p_camera_di } } +RaycastOcclusionCull::RaycastHZBuffer::~RaycastHZBuffer() { + if (camera_rays_unaligned_buffer) { + memfree(camera_rays_unaligned_buffer); + } +} + //////////////////////////////////////////////////////// bool RaycastOcclusionCull::is_occluder(RID p_rid) { @@ -207,7 +217,7 @@ void RaycastOcclusionCull::occluder_initialize(RID p_occluder) { } void RaycastOcclusionCull::occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) { - Occluder *occluder = occluder_owner.getornull(p_occluder); + Occluder *occluder = occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); occluder->vertices = p_vertices; @@ -228,7 +238,7 @@ void RaycastOcclusionCull::occluder_set_mesh(RID p_occluder, const PackedVector3 } void RaycastOcclusionCull::free_occluder(RID p_occluder) { - Occluder *occluder = occluder_owner.getornull(p_occluder); + Occluder *occluder = occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); memdelete(occluder); occluder_owner.free(p_occluder); @@ -268,7 +278,7 @@ void RaycastOcclusionCull::scenario_set_instance(RID p_scenario, RID p_instance, bool changed = false; if (instance.occluder != p_occluder) { - Occluder *old_occluder = occluder_owner.getornull(instance.occluder); + Occluder *old_occluder = occluder_owner.get_or_null(instance.occluder); if (old_occluder) { old_occluder->users.erase(InstanceID(p_scenario, p_instance)); } @@ -276,7 +286,7 @@ void RaycastOcclusionCull::scenario_set_instance(RID p_scenario, RID p_instance, instance.occluder = p_occluder; if (p_occluder.is_valid()) { - Occluder *occluder = occluder_owner.getornull(p_occluder); + Occluder *occluder = occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); occluder->users.insert(InstanceID(p_scenario, p_instance)); } @@ -308,7 +318,7 @@ void RaycastOcclusionCull::scenario_remove_instance(RID p_scenario, RID p_instan OccluderInstance &instance = scenario.instances[p_instance]; if (!instance.removed) { - Occluder *occluder = occluder_owner.getornull(instance.occluder); + Occluder *occluder = occluder_owner.get_or_null(instance.occluder); if (occluder) { occluder->users.erase(InstanceID(p_scenario, p_instance)); } @@ -330,7 +340,7 @@ void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_in return; } - Occluder *occ = raycast_singleton->occluder_owner.getornull(occ_inst->occluder); + Occluder *occ = raycast_singleton->occluder_owner.get_or_null(occ_inst->occluder); if (!occ) { return; @@ -446,7 +456,7 @@ bool RaycastOcclusionCull::Scenario::update(ThreadWorkPool &p_thread_pool) { const RID *inst_rid = nullptr; while ((inst_rid = instances.next(inst_rid))) { OccluderInstance *occ_inst = instances.getptr(*inst_rid); - Occluder *occ = raycast_singleton->occluder_owner.getornull(occ_inst->occluder); + Occluder *occ = raycast_singleton->occluder_owner.get_or_null(occ_inst->occluder); if (!occ || !occ_inst->enabled) { continue; @@ -474,7 +484,7 @@ void RaycastOcclusionCull::Scenario::_raycast(uint32_t p_idx, const RaycastThrea rtcIntersect16((const int *)&p_raycast_data->masks[p_idx * TILE_RAYS], ebr_scene[current_scene_idx], &ctx, &p_raycast_data->rays[p_idx]); } -void RaycastOcclusionCull::Scenario::raycast(LocalVector<RayPacket> &r_rays, const LocalVector<uint32_t> p_valid_masks, ThreadWorkPool &p_thread_pool) const { +void RaycastOcclusionCull::Scenario::raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count, ThreadWorkPool &p_thread_pool) const { ERR_FAIL_COND(singleton == nullptr); if (raycast_singleton->ebr_device == nullptr) { return; // Embree is initialized on demand when there is some scenario with occluders in it. @@ -485,10 +495,10 @@ void RaycastOcclusionCull::Scenario::raycast(LocalVector<RayPacket> &r_rays, con } RaycastThreadData td; - td.rays = r_rays.ptr(); - td.masks = p_valid_masks.ptr(); + td.rays = r_rays; + td.masks = p_valid_masks; - p_thread_pool.do_work(r_rays.size(), this, &Scenario::_raycast, &td); + p_thread_pool.do_work(p_tile_count, this, &Scenario::_raycast, &td); } //////////////////////////////////////////////////////// @@ -536,7 +546,7 @@ void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_ buffer.update_camera_rays(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_thread_pool); - scenario.raycast(buffer.camera_rays, buffer.camera_ray_masks, p_thread_pool); + scenario.raycast(buffer.camera_rays, buffer.camera_ray_masks.ptr(), buffer.camera_rays_tile_count, p_thread_pool); buffer.sort_rays(-p_cam_transform.basis.get_axis(2), p_cam_orthogonal); buffer.update_mips(); } @@ -592,13 +602,15 @@ RaycastOcclusionCull::~RaycastOcclusionCull() { scenario.commit_thread->wait_to_finish(); memdelete(scenario.commit_thread); } + + for (int i = 0; i < 2; i++) { + if (scenario.ebr_scene[i]) { + rtcReleaseScene(scenario.ebr_scene[i]); + } + } } if (ebr_device != nullptr) { -#ifdef __SSE2__ - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_OFF); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_OFF); -#endif rtcReleaseDevice(ebr_device); } diff --git a/modules/raycast/raycast_occlusion_cull.h b/modules/raycast/raycast_occlusion_cull.h index cc87a6342c..ea96df5ff6 100644 --- a/modules/raycast/raycast_occlusion_cull.h +++ b/modules/raycast/raycast_occlusion_cull.h @@ -43,12 +43,12 @@ #include <embree3/rtcore.h> class RaycastOcclusionCull : public RendererSceneOcclusionCull { - typedef RTCRayHit16 RayPacket; + typedef RTCRayHit16 CameraRayTile; public: class RaycastHZBuffer : public HZBuffer { private: - Size2i packs_size; + Size2i tile_grid_size; struct CameraRayThreadData { int thread_count; @@ -67,7 +67,9 @@ public: void _generate_camera_rays(const CameraRayThreadData *p_data, int p_from, int p_to); public: - LocalVector<RayPacket> camera_rays; + unsigned int camera_rays_tile_count = 0; + uint8_t *camera_rays_unaligned_buffer = nullptr; + CameraRayTile *camera_rays = nullptr; LocalVector<uint32_t> camera_ray_masks; RID scenario_rid; @@ -75,6 +77,8 @@ public: virtual void resize(const Size2i &p_size) override; void sort_rays(const Vector3 &p_camera_dir, bool p_orthogonal); void update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool); + + ~RaycastHZBuffer(); }; private: @@ -111,7 +115,7 @@ private: struct Scenario { struct RaycastThreadData { - RayPacket *rays; + CameraRayTile *rays; const uint32_t *masks; }; @@ -144,7 +148,7 @@ private: bool update(ThreadWorkPool &p_thread_pool); void _raycast(uint32_t p_thread, const RaycastThreadData *p_raycast_data) const; - void raycast(LocalVector<RayPacket> &r_rays, const LocalVector<uint32_t> p_valid_masks, ThreadWorkPool &p_thread_pool) const; + void raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count, ThreadWorkPool &p_thread_pool) const; }; static RaycastOcclusionCull *raycast_singleton; diff --git a/modules/raycast/register_types.cpp b/modules/raycast/register_types.cpp index 78ca91309f..ed99e635e1 100644 --- a/modules/raycast/register_types.cpp +++ b/modules/raycast/register_types.cpp @@ -32,12 +32,14 @@ #include "lightmap_raycaster.h" #include "raycast_occlusion_cull.h" +#include "static_raycaster.h" RaycastOcclusionCull *raycast_occlusion_cull = nullptr; void register_raycast_types() { #ifdef TOOLS_ENABLED LightmapRaycasterEmbree::make_default_raycaster(); + StaticRaycasterEmbree::make_default_raycaster(); #endif raycast_occlusion_cull = memnew(RaycastOcclusionCull); } @@ -46,4 +48,7 @@ void unregister_raycast_types() { if (raycast_occlusion_cull) { memdelete(raycast_occlusion_cull); } +#ifdef TOOLS_ENABLED + StaticRaycasterEmbree::free(); +#endif } diff --git a/modules/raycast/static_raycaster.cpp b/modules/raycast/static_raycaster.cpp new file mode 100644 index 0000000000..2ba65eebf8 --- /dev/null +++ b/modules/raycast/static_raycaster.cpp @@ -0,0 +1,137 @@ +/*************************************************************************/ +/* static_raycaster.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef TOOLS_ENABLED + +#include "static_raycaster.h" + +#ifdef __SSE2__ +#include <pmmintrin.h> +#endif + +RTCDevice StaticRaycasterEmbree::embree_device; + +StaticRaycaster *StaticRaycasterEmbree::create_embree_raycaster() { + return memnew(StaticRaycasterEmbree); +} + +void StaticRaycasterEmbree::make_default_raycaster() { + create_function = create_embree_raycaster; +} + +void StaticRaycasterEmbree::free() { + if (embree_device) { + rtcReleaseDevice(embree_device); + } +} + +bool StaticRaycasterEmbree::intersect(Ray &r_ray) { + RTCIntersectContext context; + rtcInitIntersectContext(&context); + rtcIntersect1(embree_scene, &context, (RTCRayHit *)&r_ray); + return r_ray.geomID != RTC_INVALID_GEOMETRY_ID; +} + +void StaticRaycasterEmbree::intersect(Vector<Ray> &r_rays) { + Ray *rays = r_rays.ptrw(); + for (int i = 0; i < r_rays.size(); ++i) { + intersect(rays[i]); + } +} + +void StaticRaycasterEmbree::add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) { + RTCGeometry embree_mesh = rtcNewGeometry(embree_device, RTC_GEOMETRY_TYPE_TRIANGLE); + + int vertex_count = p_vertices.size(); + + Vector3 *embree_vertices = (Vector3 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, sizeof(Vector3), vertex_count); + memcpy(embree_vertices, p_vertices.ptr(), sizeof(Vector3) * vertex_count); + + if (p_indices.is_empty()) { + ERR_FAIL_COND(vertex_count % 3 != 0); + uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, vertex_count / 3); + for (int i = 0; i < vertex_count; i++) { + embree_triangles[i] = i; + } + } else { + uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, p_indices.size() / 3); + memcpy(embree_triangles, p_indices.ptr(), sizeof(uint32_t) * p_indices.size()); + } + + rtcCommitGeometry(embree_mesh); + rtcAttachGeometryByID(embree_scene, embree_mesh, p_id); + rtcReleaseGeometry(embree_mesh); +} + +void StaticRaycasterEmbree::commit() { + rtcCommitScene(embree_scene); +} + +void StaticRaycasterEmbree::set_mesh_filter(const Set<int> &p_mesh_ids) { + for (Set<int>::Element *E = p_mesh_ids.front(); E; E = E->next()) { + rtcDisableGeometry(rtcGetGeometry(embree_scene, E->get())); + } + rtcCommitScene(embree_scene); + filter_meshes = p_mesh_ids; +} + +void StaticRaycasterEmbree::clear_mesh_filter() { + for (Set<int>::Element *E = filter_meshes.front(); E; E = E->next()) { + rtcEnableGeometry(rtcGetGeometry(embree_scene, E->get())); + } + rtcCommitScene(embree_scene); + filter_meshes.clear(); +} + +void embree_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { + print_error("Embree error: " + String(p_str)); +} + +StaticRaycasterEmbree::StaticRaycasterEmbree() { +#ifdef __SSE2__ + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); +#endif + + if (!embree_device) { + embree_device = rtcNewDevice(nullptr); + rtcSetDeviceErrorFunction(embree_device, &embree_error_handler, nullptr); + } + + embree_scene = rtcNewScene(embree_device); +} + +StaticRaycasterEmbree::~StaticRaycasterEmbree() { + if (embree_scene != nullptr) { + rtcReleaseScene(embree_scene); + } +} + +#endif diff --git a/modules/raycast/static_raycaster.h b/modules/raycast/static_raycaster.h new file mode 100644 index 0000000000..6b13ecf690 --- /dev/null +++ b/modules/raycast/static_raycaster.h @@ -0,0 +1,64 @@ +/*************************************************************************/ +/* static_raycaster.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef TOOLS_ENABLED + +#include "core/math/static_raycaster.h" + +#include <embree3/rtcore.h> + +class StaticRaycasterEmbree : public StaticRaycaster { + GDCLASS(StaticRaycasterEmbree, StaticRaycaster); + +private: + static RTCDevice embree_device; + RTCScene embree_scene; + + Set<int> filter_meshes; + +public: + virtual bool intersect(Ray &p_ray) override; + virtual void intersect(Vector<Ray> &r_rays) override; + + virtual void add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) override; + virtual void commit() override; + + virtual void set_mesh_filter(const Set<int> &p_mesh_ids) override; + virtual void clear_mesh_filter() override; + + static StaticRaycaster *create_embree_raycaster(); + static void make_default_raycaster(); + static void free(); + + StaticRaycasterEmbree(); + ~StaticRaycasterEmbree(); +}; + +#endif diff --git a/modules/text_server_adv/config.py b/modules/text_server_adv/config.py index d22f9454ed..8c8df9b05e 100644 --- a/modules/text_server_adv/config.py +++ b/modules/text_server_adv/config.py @@ -4,3 +4,13 @@ def can_build(env, platform): def configure(env): pass + + +def get_doc_classes(): + return [ + "TextServerAdvanced", + ] + + +def get_doc_path(): + return "doc_classes" diff --git a/modules/text_server_adv/doc_classes/TextServerAdvanced.xml b/modules/text_server_adv/doc_classes/TextServerAdvanced.xml new file mode 100644 index 0000000000..eff4aa5fae --- /dev/null +++ b/modules/text_server_adv/doc_classes/TextServerAdvanced.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="TextServerAdvanced" inherits="TextServer" version="4.0"> + <brief_description> + Text Server using HarfBuzz, ICU and SIL Graphite to support BiDi, complex text layouts and contextual OpenType features. + </brief_description> + <description> + </description> + <tutorials> + </tutorials> +</class> diff --git a/modules/text_server_adv/register_types.cpp b/modules/text_server_adv/register_types.cpp index abefa83b9b..b711d1561f 100644 --- a/modules/text_server_adv/register_types.cpp +++ b/modules/text_server_adv/register_types.cpp @@ -33,7 +33,12 @@ #include "text_server_adv.h" void preregister_text_server_adv_types() { - TextServerAdvanced::register_server(); + GDREGISTER_CLASS(TextServerAdvanced); + if (TextServerManager::get_singleton()) { + Ref<TextServerAdvanced> ts; + ts.instantiate(); + TextServerManager::get_singleton()->add_interface(ts); + } } void register_text_server_adv_types() { diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index c93f353cea..f5d159040f 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -322,7 +322,7 @@ _FORCE_INLINE_ bool is_underscore(char32_t p_char) { String TextServerAdvanced::interface_name = "ICU / HarfBuzz / Graphite"; uint32_t TextServerAdvanced::interface_features = FEATURE_BIDI_LAYOUT | FEATURE_VERTICAL_LAYOUT | FEATURE_SHAPING | FEATURE_KASHIDA_JUSTIFICATION | FEATURE_BREAK_ITERATORS | FEATURE_USE_SUPPORT_DATA | FEATURE_FONT_VARIABLE; -bool TextServerAdvanced::has_feature(Feature p_feature) { +bool TextServerAdvanced::has_feature(Feature p_feature) const { return (interface_features & p_feature) == p_feature; } @@ -330,14 +330,18 @@ String TextServerAdvanced::get_name() const { return interface_name; } +uint32_t TextServerAdvanced::get_features() const { + return interface_features; +} + void TextServerAdvanced::free(RID p_rid) { _THREAD_SAFE_METHOD_ if (font_owner.owns(p_rid)) { - FontDataAdvanced *fd = font_owner.getornull(p_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_rid); font_owner.free(p_rid); memdelete(fd); } else if (shaped_owner.owns(p_rid)) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_rid); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_rid); shaped_owner.free(p_rid); memdelete(sd); } @@ -394,9 +398,23 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) { return true; } -#ifdef TOOLS_ENABLED +String TextServerAdvanced::get_support_data_filename() const { +#ifdef ICU_STATIC_DATA + return _MKSTR(ICU_DATA_NAME); +#else + return String(); +#endif +} + +String TextServerAdvanced::get_support_data_info() const { +#ifdef ICU_STATIC_DATA + return String("ICU break iteration data (") + _MKSTR(ICU_DATA_NAME) + String(")."); +#else + return String(); +#endif +} -bool TextServerAdvanced::save_support_data(const String &p_filename) { +bool TextServerAdvanced::save_support_data(const String &p_filename) const { _THREAD_SAFE_METHOD_ #ifdef ICU_STATIC_DATA @@ -415,9 +433,7 @@ bool TextServerAdvanced::save_support_data(const String &p_filename) { #endif } -#endif - -bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) { +bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) const { String l = p_locale.get_slicec('_', 0); if ((l == "ar") || (l == "dv") || (l == "he") || (l == "fa") || (l == "ff") || (l == "ku") || (l == "ur")) { return true; @@ -1142,7 +1158,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontDataAdvanced *p_font_d int error = FT_Load_Glyph(fd->face, p_glyph, flags); if (error) { fd->glyph_map[p_glyph] = FontGlyph(); - ERR_FAIL_V_MSG(false, "FreeType: Failed to load glyph."); + return false; } if (!outline) { @@ -1236,7 +1252,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced fd->oversampling = 1.0f; fd->size.x = p_font_data->msdf_source_size; } else if (p_font_data->oversampling <= 0.0f) { - fd->oversampling = TS->font_get_global_oversampling(); + fd->oversampling = font_get_global_oversampling(); } else { fd->oversampling = p_font_data->oversampling; } @@ -1244,13 +1260,13 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced if (FT_HAS_COLOR(fd->face) && fd->face->num_fixed_sizes > 0) { int best_match = 0; int diff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[0].width)); - fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width; + fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width; for (int i = 1; i < fd->face->num_fixed_sizes; i++) { int ndiff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[i].width)); if (ndiff < diff) { best_match = i; diff = ndiff; - fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width; + fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width; } } FT_Select_Size(fd->face, best_match); @@ -1585,8 +1601,8 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontDataAdvanced } _FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontDataAdvanced *p_font_data) { - for (const Map<Vector2i, FontDataForSizeAdvanced *>::Element *E = p_font_data->cache.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : p_font_data->cache) { + memdelete(E.value); } p_font_data->cache.clear(); p_font_data->face_init = false; @@ -1596,7 +1612,7 @@ _FORCE_INLINE_ void TextServerAdvanced::_font_clear_cache(FontDataAdvanced *p_fo } hb_font_t *TextServerAdvanced::_font_get_hb_handle(RID p_font_rid, int p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, nullptr); MutexLock lock(fd->mutex); @@ -1614,7 +1630,7 @@ RID TextServerAdvanced::create_font() { } void TextServerAdvanced::font_set_data(RID p_font_rid, const PackedByteArray &p_data) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1625,7 +1641,7 @@ void TextServerAdvanced::font_set_data(RID p_font_rid, const PackedByteArray &p_ } void TextServerAdvanced::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1636,7 +1652,7 @@ void TextServerAdvanced::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data } void TextServerAdvanced::font_set_antialiased(RID p_font_rid, bool p_antialiased) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1647,7 +1663,7 @@ void TextServerAdvanced::font_set_antialiased(RID p_font_rid, bool p_antialiased } bool TextServerAdvanced::font_is_antialiased(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1655,7 +1671,7 @@ bool TextServerAdvanced::font_is_antialiased(RID p_font_rid) const { } void TextServerAdvanced::font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1666,7 +1682,7 @@ void TextServerAdvanced::font_set_multichannel_signed_distance_field(RID p_font_ } bool TextServerAdvanced::font_is_multichannel_signed_distance_field(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1674,7 +1690,7 @@ bool TextServerAdvanced::font_is_multichannel_signed_distance_field(RID p_font_r } void TextServerAdvanced::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1685,7 +1701,7 @@ void TextServerAdvanced::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pi } int TextServerAdvanced::font_get_msdf_pixel_range(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1693,7 +1709,7 @@ int TextServerAdvanced::font_get_msdf_pixel_range(RID p_font_rid) const { } void TextServerAdvanced::font_set_msdf_size(RID p_font_rid, int p_msdf_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1704,7 +1720,7 @@ void TextServerAdvanced::font_set_msdf_size(RID p_font_rid, int p_msdf_size) { } int TextServerAdvanced::font_get_msdf_size(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1712,7 +1728,7 @@ int TextServerAdvanced::font_get_msdf_size(RID p_font_rid) const { } void TextServerAdvanced::font_set_fixed_size(RID p_font_rid, int p_fixed_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1722,7 +1738,7 @@ void TextServerAdvanced::font_set_fixed_size(RID p_font_rid, int p_fixed_size) { } int TextServerAdvanced::font_get_fixed_size(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1730,7 +1746,7 @@ int TextServerAdvanced::font_get_fixed_size(RID p_font_rid) const { } void TextServerAdvanced::font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1741,7 +1757,7 @@ void TextServerAdvanced::font_set_force_autohinter(RID p_font_rid, bool p_force_ } bool TextServerAdvanced::font_is_force_autohinter(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1749,7 +1765,7 @@ bool TextServerAdvanced::font_is_force_autohinter(RID p_font_rid) const { } void TextServerAdvanced::font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1760,7 +1776,7 @@ void TextServerAdvanced::font_set_hinting(RID p_font_rid, TextServer::Hinting p_ } TextServer::Hinting TextServerAdvanced::font_get_hinting(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, HINTING_NONE); MutexLock lock(fd->mutex); @@ -1768,7 +1784,7 @@ TextServer::Hinting TextServerAdvanced::font_get_hinting(RID p_font_rid) const { } void TextServerAdvanced::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1779,15 +1795,15 @@ void TextServerAdvanced::font_set_variation_coordinates(RID p_font_rid, const Di } Dictionary TextServerAdvanced::font_get_variation_coordinates(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); MutexLock lock(fd->mutex); return fd->variation_coordinates; } -void TextServerAdvanced::font_set_oversampling(RID p_font_rid, real_t p_oversampling) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +void TextServerAdvanced::font_set_oversampling(RID p_font_rid, float p_oversampling) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1797,8 +1813,8 @@ void TextServerAdvanced::font_set_oversampling(RID p_font_rid, real_t p_oversamp } } -real_t TextServerAdvanced::font_get_oversampling(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +float TextServerAdvanced::font_get_oversampling(RID p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1806,7 +1822,7 @@ real_t TextServerAdvanced::font_get_oversampling(RID p_font_rid) const { } Array TextServerAdvanced::font_get_size_cache_list(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Array()); MutexLock lock(fd->mutex); @@ -1818,18 +1834,18 @@ Array TextServerAdvanced::font_get_size_cache_list(RID p_font_rid) const { } void TextServerAdvanced::font_clear_size_cache(RID p_font_rid) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); - for (const Map<Vector2i, FontDataForSizeAdvanced *>::Element *E = fd->cache.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : fd->cache) { + memdelete(E.value); } fd->cache.clear(); } void TextServerAdvanced::font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1839,8 +1855,8 @@ void TextServerAdvanced::font_remove_size_cache(RID p_font_rid, const Vector2i & } } -void TextServerAdvanced::font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +void TextServerAdvanced::font_set_ascent(RID p_font_rid, int p_size, float p_ascent) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1850,8 +1866,8 @@ void TextServerAdvanced::font_set_ascent(RID p_font_rid, int p_size, real_t p_as fd->cache[size]->ascent = p_ascent; } -real_t TextServerAdvanced::font_get_ascent(RID p_font_rid, int p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +float TextServerAdvanced::font_get_ascent(RID p_font_rid, int p_size) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1860,14 +1876,14 @@ real_t TextServerAdvanced::font_get_ascent(RID p_font_rid, int p_size) const { ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->ascent * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->ascent * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->ascent; } } -void TextServerAdvanced::font_set_descent(RID p_font_rid, int p_size, real_t p_descent) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +void TextServerAdvanced::font_set_descent(RID p_font_rid, int p_size, float p_descent) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); Vector2i size = _get_size(fd, p_size); @@ -1876,8 +1892,8 @@ void TextServerAdvanced::font_set_descent(RID p_font_rid, int p_size, real_t p_d fd->cache[size]->descent = p_descent; } -real_t TextServerAdvanced::font_get_descent(RID p_font_rid, int p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +float TextServerAdvanced::font_get_descent(RID p_font_rid, int p_size) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1886,14 +1902,14 @@ real_t TextServerAdvanced::font_get_descent(RID p_font_rid, int p_size) const { ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->descent * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->descent * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->descent; } } -void TextServerAdvanced::font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +void TextServerAdvanced::font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1903,8 +1919,8 @@ void TextServerAdvanced::font_set_underline_position(RID p_font_rid, int p_size, fd->cache[size]->underline_position = p_underline_position; } -real_t TextServerAdvanced::font_get_underline_position(RID p_font_rid, int p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +float TextServerAdvanced::font_get_underline_position(RID p_font_rid, int p_size) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1913,14 +1929,14 @@ real_t TextServerAdvanced::font_get_underline_position(RID p_font_rid, int p_siz ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->underline_position * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->underline_position * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->underline_position; } } -void TextServerAdvanced::font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +void TextServerAdvanced::font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1930,8 +1946,8 @@ void TextServerAdvanced::font_set_underline_thickness(RID p_font_rid, int p_size fd->cache[size]->underline_thickness = p_underline_thickness; } -real_t TextServerAdvanced::font_get_underline_thickness(RID p_font_rid, int p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +float TextServerAdvanced::font_get_underline_thickness(RID p_font_rid, int p_size) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1940,14 +1956,14 @@ real_t TextServerAdvanced::font_get_underline_thickness(RID p_font_rid, int p_si ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->underline_thickness * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->underline_thickness * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->underline_thickness; } } -void TextServerAdvanced::font_set_scale(RID p_font_rid, int p_size, real_t p_scale) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +void TextServerAdvanced::font_set_scale(RID p_font_rid, int p_size, float p_scale) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1957,8 +1973,8 @@ void TextServerAdvanced::font_set_scale(RID p_font_rid, int p_size, real_t p_sca fd->cache[size]->scale = p_scale; } -real_t TextServerAdvanced::font_get_scale(RID p_font_rid, int p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); +float TextServerAdvanced::font_get_scale(RID p_font_rid, int p_size) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1967,14 +1983,14 @@ real_t TextServerAdvanced::font_get_scale(RID p_font_rid, int p_size) const { ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->scale * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->scale * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->scale / fd->cache[size]->oversampling; } } void TextServerAdvanced::font_set_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing, int p_value) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1995,7 +2011,7 @@ void TextServerAdvanced::font_set_spacing(RID p_font_rid, int p_size, TextServer } int TextServerAdvanced::font_get_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0); MutexLock lock(fd->mutex); @@ -2006,14 +2022,14 @@ int TextServerAdvanced::font_get_spacing(RID p_font_rid, int p_size, TextServer: switch (p_spacing) { case TextServer::SPACING_GLYPH: { if (fd->msdf) { - return fd->cache[size]->spacing_glyph * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->spacing_glyph * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->spacing_glyph; } } break; case TextServer::SPACING_SPACE: { if (fd->msdf) { - return fd->cache[size]->spacing_space * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->spacing_space * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->spacing_space; } @@ -2026,7 +2042,7 @@ int TextServerAdvanced::font_get_spacing(RID p_font_rid, int p_size, TextServer: } int TextServerAdvanced::font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0); MutexLock lock(fd->mutex); @@ -2038,7 +2054,7 @@ int TextServerAdvanced::font_get_texture_count(RID p_font_rid, const Vector2i &p } void TextServerAdvanced::font_clear_textures(RID p_font_rid, const Vector2i &p_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); @@ -2048,7 +2064,7 @@ void TextServerAdvanced::font_clear_textures(RID p_font_rid, const Vector2i &p_s } void TextServerAdvanced::font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2060,7 +2076,7 @@ void TextServerAdvanced::font_remove_texture(RID p_font_rid, const Vector2i &p_s } void TextServerAdvanced::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); ERR_FAIL_COND(p_image.is_null()); @@ -2086,7 +2102,7 @@ void TextServerAdvanced::font_set_texture_image(RID p_font_rid, const Vector2i & } Ref<Image> TextServerAdvanced::font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Ref<Image>()); MutexLock lock(fd->mutex); @@ -2101,7 +2117,7 @@ Ref<Image> TextServerAdvanced::font_get_texture_image(RID p_font_rid, const Vect } void TextServerAdvanced::font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2116,7 +2132,7 @@ void TextServerAdvanced::font_set_texture_offsets(RID p_font_rid, const Vector2i } PackedInt32Array TextServerAdvanced::font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, PackedInt32Array()); MutexLock lock(fd->mutex); @@ -2129,7 +2145,7 @@ PackedInt32Array TextServerAdvanced::font_get_texture_offsets(RID p_font_rid, co } Array TextServerAdvanced::font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Array()); MutexLock lock(fd->mutex); @@ -2146,7 +2162,7 @@ Array TextServerAdvanced::font_get_glyph_list(RID p_font_rid, const Vector2i &p_ } void TextServerAdvanced::font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2157,7 +2173,7 @@ void TextServerAdvanced::font_clear_glyphs(RID p_font_rid, const Vector2i &p_siz } void TextServerAdvanced::font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2168,7 +2184,7 @@ void TextServerAdvanced::font_remove_glyph(RID p_font_rid, const Vector2i &p_siz } Vector2 TextServerAdvanced::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -2182,14 +2198,14 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(RID p_font_rid, int p_size, i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; if (fd->msdf) { - return gl[p_glyph].advance * (real_t)p_size / (real_t)fd->msdf_source_size; + return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size; } else { return gl[p_glyph].advance; } } void TextServerAdvanced::font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2204,7 +2220,7 @@ void TextServerAdvanced::font_set_glyph_advance(RID p_font_rid, int p_size, int3 } Vector2 TextServerAdvanced::font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -2218,14 +2234,14 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(RID p_font_rid, const Vector2i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; if (fd->msdf) { - return gl[p_glyph].rect.position * (real_t)p_size.x / (real_t)fd->msdf_source_size; + return gl[p_glyph].rect.position * (float)p_size.x / (float)fd->msdf_source_size; } else { return gl[p_glyph].rect.position; } } void TextServerAdvanced::font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2240,7 +2256,7 @@ void TextServerAdvanced::font_set_glyph_offset(RID p_font_rid, const Vector2i &p } Vector2 TextServerAdvanced::font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -2254,14 +2270,14 @@ Vector2 TextServerAdvanced::font_get_glyph_size(RID p_font_rid, const Vector2i & const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; if (fd->msdf) { - return gl[p_glyph].rect.size * (real_t)p_size.x / (real_t)fd->msdf_source_size; + return gl[p_glyph].rect.size * (float)p_size.x / (float)fd->msdf_source_size; } else { return gl[p_glyph].rect.size; } } void TextServerAdvanced::font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2276,7 +2292,7 @@ void TextServerAdvanced::font_set_glyph_size(RID p_font_rid, const Vector2i &p_s } Rect2 TextServerAdvanced::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Rect2()); MutexLock lock(fd->mutex); @@ -2292,7 +2308,7 @@ Rect2 TextServerAdvanced::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i } void TextServerAdvanced::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2307,7 +2323,7 @@ void TextServerAdvanced::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i & } int TextServerAdvanced::font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, -1); MutexLock lock(fd->mutex); @@ -2323,7 +2339,7 @@ int TextServerAdvanced::font_get_glyph_texture_idx(RID p_font_rid, const Vector2 } void TextServerAdvanced::font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2337,42 +2353,50 @@ void TextServerAdvanced::font_set_glyph_texture_idx(RID p_font_rid, const Vector gl[p_glyph].found = true; } -bool TextServerAdvanced::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); - ERR_FAIL_COND_V(!fd, false); +Dictionary TextServerAdvanced::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Dictionary()); MutexLock lock(fd->mutex); Vector2i size = _get_size(fd, p_size); - ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), false); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Dictionary()); + Vector<Vector3> points; + Vector<int32_t> contours; + bool orientation; #ifdef MODULE_FREETYPE_ENABLED int error = FT_Load_Glyph(fd->cache[size]->face, p_index, FT_LOAD_NO_BITMAP | (fd->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)); - ERR_FAIL_COND_V(error, false); + ERR_FAIL_COND_V(error, Dictionary()); - r_points.clear(); - r_contours.clear(); + points.clear(); + contours.clear(); - real_t h = fd->cache[size]->ascent; - real_t scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale; + float h = fd->cache[size]->ascent; + float scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale; if (fd->msdf) { - scale = scale * (real_t)p_size / (real_t)fd->msdf_source_size; + scale = scale * (float)p_size / (float)fd->msdf_source_size; } for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_points; i++) { - r_points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i]))); + points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i]))); } for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_contours; i++) { - r_contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]); + contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]); } - r_orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT); + orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT); #else - return false; + return Dictionary(); #endif - return true; + + Dictionary out; + out["points"] = points; + out["contours"] = contours; + out["orientation"] = orientation; + return out; } Array TextServerAdvanced::font_get_kerning_list(RID p_font_rid, int p_size) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Array()); MutexLock lock(fd->mutex); @@ -2388,7 +2412,7 @@ Array TextServerAdvanced::font_get_kerning_list(RID p_font_rid, int p_size) cons } void TextServerAdvanced::font_clear_kerning_map(RID p_font_rid, int p_size) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2399,7 +2423,7 @@ void TextServerAdvanced::font_clear_kerning_map(RID p_font_rid, int p_size) { } void TextServerAdvanced::font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2410,7 +2434,7 @@ void TextServerAdvanced::font_remove_kerning(RID p_font_rid, int p_size, const V } void TextServerAdvanced::font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2421,7 +2445,7 @@ void TextServerAdvanced::font_set_kerning(RID p_font_rid, int p_size, const Vect } Vector2 TextServerAdvanced::font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -2433,7 +2457,7 @@ Vector2 TextServerAdvanced::font_get_kerning(RID p_font_rid, int p_size, const V if (kern.has(p_glyph_pair)) { if (fd->msdf) { - return kern[p_glyph_pair] * (real_t)p_size / (real_t)fd->msdf_source_size; + return kern[p_glyph_pair] * (float)p_size / (float)fd->msdf_source_size; } else { return kern[p_glyph_pair]; } @@ -2443,7 +2467,7 @@ Vector2 TextServerAdvanced::font_get_kerning(RID p_font_rid, int p_size, const V FT_Vector delta; FT_Get_Kerning(fd->cache[size]->face, p_glyph_pair.x, p_glyph_pair.y, FT_KERNING_DEFAULT, &delta); if (fd->msdf) { - return Vector2(delta.x, delta.y) * (real_t)p_size / (real_t)fd->msdf_source_size; + return Vector2(delta.x, delta.y) * (float)p_size / (float)fd->msdf_source_size; } else { return Vector2(delta.x, delta.y); } @@ -2454,7 +2478,7 @@ Vector2 TextServerAdvanced::font_get_kerning(RID p_font_rid, int p_size, const V } int32_t TextServerAdvanced::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0); MutexLock lock(fd->mutex); @@ -2477,7 +2501,7 @@ int32_t TextServerAdvanced::font_get_glyph_index(RID p_font_rid, int p_size, cha } bool TextServerAdvanced::font_has_char(RID p_font_rid, char32_t p_char) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -2495,7 +2519,7 @@ bool TextServerAdvanced::font_has_char(RID p_font_rid, char32_t p_char) const { } String TextServerAdvanced::font_get_supported_chars(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, String()); MutexLock lock(fd->mutex); @@ -2529,7 +2553,7 @@ String TextServerAdvanced::font_get_supported_chars(RID p_font_rid) const { } void TextServerAdvanced::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2547,7 +2571,7 @@ void TextServerAdvanced::font_render_range(RID p_font_rid, const Vector2i &p_siz } void TextServerAdvanced::font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2557,7 +2581,7 @@ void TextServerAdvanced::font_render_glyph(RID p_font_rid, const Vector2i &p_siz } void TextServerAdvanced::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2582,8 +2606,8 @@ void TextServerAdvanced::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; - cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size; - Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size; + cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size; + Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range); } else { Point2i cpos = p_pos; @@ -2597,7 +2621,7 @@ void TextServerAdvanced::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz } void TextServerAdvanced::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2622,8 +2646,8 @@ void TextServerAdvanced::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; - cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size; - Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size; + cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size; + Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range); } else { Point2i cpos = p_pos; @@ -2637,7 +2661,7 @@ void TextServerAdvanced::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i } bool TextServerAdvanced::font_is_language_supported(RID p_font_rid, const String &p_language) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -2649,7 +2673,7 @@ bool TextServerAdvanced::font_is_language_supported(RID p_font_rid, const String } void TextServerAdvanced::font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2657,7 +2681,7 @@ void TextServerAdvanced::font_set_language_support_override(RID p_font_rid, cons } bool TextServerAdvanced::font_get_language_support_override(RID p_font_rid, const String &p_language) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -2665,7 +2689,7 @@ bool TextServerAdvanced::font_get_language_support_override(RID p_font_rid, cons } void TextServerAdvanced::font_remove_language_support_override(RID p_font_rid, const String &p_language) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2673,19 +2697,19 @@ void TextServerAdvanced::font_remove_language_support_override(RID p_font_rid, c } Vector<String> TextServerAdvanced::font_get_language_support_overrides(RID p_font_rid) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector<String>()); MutexLock lock(fd->mutex); Vector<String> out; - for (const Map<String, bool>::Element *E = fd->language_support_overrides.front(); E; E = E->next()) { - out.push_back(E->key()); + for (const KeyValue<String, bool> &E : fd->language_support_overrides) { + out.push_back(E.key); } return out; } bool TextServerAdvanced::font_is_script_supported(RID p_font_rid, const String &p_script) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -2694,12 +2718,12 @@ bool TextServerAdvanced::font_is_script_supported(RID p_font_rid, const String & } else { Vector2i size = _get_size(fd, 16); ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), false); - return fd->supported_scripts.has(TS->name_to_tag(p_script)); + return fd->supported_scripts.has(hb_tag_from_string(p_script.ascii().get_data(), -1)); } } void TextServerAdvanced::font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2707,7 +2731,7 @@ void TextServerAdvanced::font_set_script_support_override(RID p_font_rid, const } bool TextServerAdvanced::font_get_script_support_override(RID p_font_rid, const String &p_script) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -2715,7 +2739,7 @@ bool TextServerAdvanced::font_get_script_support_override(RID p_font_rid, const } void TextServerAdvanced::font_remove_script_support_override(RID p_font_rid, const String &p_script) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -2723,7 +2747,7 @@ void TextServerAdvanced::font_remove_script_support_override(RID p_font_rid, con } Vector<String> TextServerAdvanced::font_get_script_support_overrides(RID p_font_rid) { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector<String>()); MutexLock lock(fd->mutex); @@ -2735,7 +2759,7 @@ Vector<String> TextServerAdvanced::font_get_script_support_overrides(RID p_font_ } Dictionary TextServerAdvanced::font_supported_feature_list(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); MutexLock lock(fd->mutex); @@ -2745,7 +2769,7 @@ Dictionary TextServerAdvanced::font_supported_feature_list(RID p_font_rid) const } Dictionary TextServerAdvanced::font_supported_variation_list(RID p_font_rid) const { - FontDataAdvanced *fd = font_owner.getornull(p_font_rid); + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); MutexLock lock(fd->mutex); @@ -2754,11 +2778,11 @@ Dictionary TextServerAdvanced::font_supported_variation_list(RID p_font_rid) con return fd->supported_varaitions; } -real_t TextServerAdvanced::font_get_global_oversampling() const { +float TextServerAdvanced::font_get_global_oversampling() const { return oversampling; } -void TextServerAdvanced::font_set_global_oversampling(real_t p_oversampling) { +void TextServerAdvanced::font_set_global_oversampling(float p_oversampling) { _THREAD_SAFE_METHOD_ if (oversampling != p_oversampling) { oversampling = p_oversampling; @@ -2776,7 +2800,7 @@ void TextServerAdvanced::font_set_global_oversampling(real_t p_oversampling) { List<RID> text_bufs; shaped_owner.get_owned_list(&text_bufs); for (const RID &E : text_bufs) { - invalidate(shaped_owner.getornull(E)); + invalidate(shaped_owner.get_or_null(E)); } } } @@ -2837,11 +2861,11 @@ void TextServerAdvanced::invalidate(TextServerAdvanced::ShapedTextDataAdvanced * } void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) { - ShapedTextDataAdvanced *parent = shaped_owner.getornull(p_shaped->parent); + ShapedTextDataAdvanced *parent = shaped_owner.get_or_null(p_shaped->parent); - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = parent->objects.front(); E; E = E->next()) { - if (E->get().pos >= p_shaped->start && E->get().pos < p_shaped->end) { - p_shaped->objects[E->key()] = E->get(); + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : parent->objects) { + if (E.value.pos >= p_shaped->start && E.value.pos < p_shaped->end) { + p_shaped->objects[E.key] = E.value; } } @@ -2868,7 +2892,7 @@ RID TextServerAdvanced::create_shaped_text(TextServer::Direction p_direction, Te } void TextServerAdvanced::shaped_text_clear(RID p_shaped) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2883,7 +2907,7 @@ void TextServerAdvanced::shaped_text_clear(RID p_shaped) { } void TextServerAdvanced::shaped_text_set_direction(RID p_shaped, TextServer::Direction p_direction) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2897,27 +2921,30 @@ void TextServerAdvanced::shaped_text_set_direction(RID p_shaped, TextServer::Dir } TextServer::Direction TextServerAdvanced::shaped_text_get_direction(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, TextServer::DIRECTION_LTR); MutexLock lock(sd->mutex); return sd->direction; } -void TextServerAdvanced::shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +void TextServerAdvanced::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); if (sd->parent != RID()) { full_copy(sd); } - sd->bidi_override = p_override; + sd->bidi_override.clear(); + for (int i = 0; i < p_override.size(); i++) { + sd->bidi_override.push_back(p_override[i]); + } invalidate(sd); } void TextServerAdvanced::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2931,7 +2958,7 @@ void TextServerAdvanced::shaped_text_set_orientation(RID p_shaped, TextServer::O } void TextServerAdvanced::shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2943,7 +2970,7 @@ void TextServerAdvanced::shaped_text_set_preserve_invalid(RID p_shaped, bool p_e } bool TextServerAdvanced::shaped_text_get_preserve_invalid(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2951,7 +2978,7 @@ bool TextServerAdvanced::shaped_text_get_preserve_invalid(RID p_shaped) const { } void TextServerAdvanced::shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2965,7 +2992,7 @@ void TextServerAdvanced::shaped_text_set_preserve_control(RID p_shaped, bool p_e } bool TextServerAdvanced::shaped_text_get_preserve_control(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2973,7 +3000,7 @@ bool TextServerAdvanced::shaped_text_get_preserve_control(RID p_shaped) const { } TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, TextServer::ORIENTATION_HORIZONTAL); MutexLock lock(sd->mutex); @@ -2981,13 +3008,13 @@ TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(RID p_sh } bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); ERR_FAIL_COND_V(p_size <= 0, false); MutexLock lock(sd->mutex); for (int i = 0; i < p_fonts.size(); i++) { - ERR_FAIL_COND_V(!font_owner.getornull(p_fonts[i]), false); + ERR_FAIL_COND_V(!font_owner.get_or_null(p_fonts[i]), false); } if (p_text.is_empty()) { @@ -3016,7 +3043,7 @@ bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_te bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { _THREAD_SAFE_METHOD_ - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); ERR_FAIL_COND_V(p_key == Variant(), false); ERR_FAIL_COND_V(sd->objects.has(p_key), false); @@ -3045,7 +3072,7 @@ bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, con } bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -3065,9 +3092,9 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, Glyph gl = sd->glyphs[i]; Variant key; if (gl.count == 1) { - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - if (E->get().pos == gl.start) { - key = E->key(); + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + if (E.value.pos == gl.start) { + key = E.key; break; } } @@ -3096,8 +3123,7 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, } else if (sd->preserve_invalid || (sd->preserve_control && is_control(gl.index))) { // Glyph not found, replace with hex code box. if (sd->orientation == ORIENTATION_HORIZONTAL) { - sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f)); - sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f)); + sd->ascent = MAX(sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y); } else { sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); @@ -3108,66 +3134,66 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, } // Align embedded objects to baseline. - real_t full_ascent = sd->ascent; - real_t full_descent = sd->descent; - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - if ((E->get().pos >= sd->start) && (E->get().pos < sd->end)) { + float full_ascent = sd->ascent; + float full_descent = sd->descent; + for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.y = -sd->ascent; + E.value.rect.position.y = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.y = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.y = 0; + E.value.rect.position.y = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.y = sd->descent; + E.value.rect.position.y = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.y -= E->get().rect.size.y; + E.value.rect.position.y -= E.value.rect.size.y; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.y -= E->get().rect.size.y / 2; + E.value.rect.position.y -= E.value.rect.size.y / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.y); - full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y); + full_ascent = MAX(full_ascent, -E.value.rect.position.y); + full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.x = -sd->ascent; + E.value.rect.position.x = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.x = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.x = 0; + E.value.rect.position.x = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.x = sd->descent; + E.value.rect.position.x = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.x -= E->get().rect.size.x; + E.value.rect.position.x -= E.value.rect.size.x; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.x -= E->get().rect.size.x / 2; + E.value.rect.position.x -= E.value.rect.size.x / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.x); - full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x); + full_ascent = MAX(full_ascent, -E.value.rect.position.x); + full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x); } } } @@ -3178,7 +3204,7 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, } RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_length) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, RID()); MutexLock lock(sd->mutex); @@ -3254,11 +3280,11 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng Variant key; bool find_embedded = false; if (gl.count == 1) { - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - if (E->get().pos == gl.start) { + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + if (E.value.pos == gl.start) { find_embedded = true; - key = E->key(); - new_sd->objects[key] = E->get(); + key = E.key; + new_sd->objects[key] = E.value; break; } } @@ -3283,8 +3309,7 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng } else if (new_sd->preserve_invalid || (new_sd->preserve_control && is_control(gl.index))) { // Glyph not found, replace with hex code box. if (new_sd->orientation == ORIENTATION_HORIZONTAL) { - new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f)); - new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f)); + new_sd->ascent = MAX(new_sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y); } else { new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); @@ -3299,66 +3324,66 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng } // Align embedded objects to baseline. - real_t full_ascent = new_sd->ascent; - real_t full_descent = new_sd->descent; - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = new_sd->objects.front(); E; E = E->next()) { - if ((E->get().pos >= new_sd->start) && (E->get().pos < new_sd->end)) { + float full_ascent = new_sd->ascent; + float full_descent = new_sd->descent; + for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) { + if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.y = -new_sd->ascent; + E.value.rect.position.y = -new_sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.y = (-new_sd->ascent + new_sd->descent) / 2; + E.value.rect.position.y = (-new_sd->ascent + new_sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.y = 0; + E.value.rect.position.y = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.y = new_sd->descent; + E.value.rect.position.y = new_sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.y -= E->get().rect.size.y; + E.value.rect.position.y -= E.value.rect.size.y; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.y -= E->get().rect.size.y / 2; + E.value.rect.position.y -= E.value.rect.size.y / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.y); - full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y); + full_ascent = MAX(full_ascent, -E.value.rect.position.y); + full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.x = -new_sd->ascent; + E.value.rect.position.x = -new_sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.x = (-new_sd->ascent + new_sd->descent) / 2; + E.value.rect.position.x = (-new_sd->ascent + new_sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.x = 0; + E.value.rect.position.x = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.x = new_sd->descent; + E.value.rect.position.x = new_sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.x -= E->get().rect.size.x; + E.value.rect.position.x -= E.value.rect.size.x; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.x -= E->get().rect.size.x / 2; + E.value.rect.position.x -= E.value.rect.size.x / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.x); - full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x); + full_ascent = MAX(full_ascent, -E.value.rect.position.x); + full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x); } } } @@ -3371,15 +3396,15 @@ RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_leng } RID TextServerAdvanced::shaped_text_get_parent(RID p_shaped) const { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, RID()); MutexLock lock(sd->mutex); return sd->parent; } -real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +float TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags) { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -3419,7 +3444,7 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width } } - real_t justification_width; + float justification_width; if ((p_jst_flags & JUSTIFICATION_CONSTRAIN_ELLIPSIS) == JUSTIFICATION_CONSTRAIN_ELLIPSIS) { if (sd->overrun_trim_data.trim_pos >= 0) { start_pos = sd->overrun_trim_data.trim_pos; @@ -3459,7 +3484,7 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width } if ((elongation_count > 0) && ((p_jst_flags & JUSTIFICATION_KASHIDA) == JUSTIFICATION_KASHIDA)) { - real_t delta_width_per_kashida = (p_width - justification_width) / elongation_count; + float delta_width_per_kashida = (p_width - justification_width) / elongation_count; for (int i = start_pos; i <= end_pos; i++) { Glyph &gl = sd->glyphs.write[i]; if (gl.count > 0) { @@ -3474,15 +3499,15 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width } } } - real_t adv_remain = 0; + float adv_remain = 0; if ((space_count > 0) && ((p_jst_flags & JUSTIFICATION_WORD_BOUND) == JUSTIFICATION_WORD_BOUND)) { - real_t delta_width_per_space = (p_width - justification_width) / space_count; + float delta_width_per_space = (p_width - justification_width) / space_count; for (int i = start_pos; i <= end_pos; i++) { Glyph &gl = sd->glyphs.write[i]; if (gl.count > 0) { if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) { - real_t old_adv = gl.advance; - real_t new_advance; + float old_adv = gl.advance; + float new_advance; if ((gl.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) { new_advance = MAX(gl.advance + delta_width_per_space, 0.f); } else { @@ -3514,8 +3539,8 @@ real_t TextServerAdvanced::shaped_text_fit_to_width(RID p_shaped, real_t p_width return sd->width; } -real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +float TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -3527,7 +3552,7 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real } int tab_index = 0; - real_t off = 0.f; + float off = 0.f; int start, end, delta; if (sd->para_direction == DIRECTION_LTR) { @@ -3544,7 +3569,7 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real for (int i = start; i != end; i += delta) { if ((gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB) { - real_t tab_off = 0.f; + float tab_off = 0.f; while (tab_off <= off) { tab_off += p_tab_stops[tab_index]; tab_index++; @@ -3552,7 +3577,7 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real tab_index = 0; } } - real_t old_adv = gl[i].advance; + float old_adv = gl[i].advance; gl[i].advance = tab_off - off; sd->width += gl[i].advance - old_adv; off = 0; @@ -3564,8 +3589,8 @@ real_t TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const Vector<real return 0.f; } -void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, real_t p_width, uint8_t p_trim_flags) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped_line); +void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped_line); ERR_FAIL_COND_MSG(!sd, "ShapedTextDataAdvanced invalid."); MutexLock lock(sd->mutex); @@ -3607,7 +3632,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re } int ell_min_characters = 6; - real_t width = sd->width; + float width = sd->width; bool is_rtl = sd->direction == DIRECTION_RTL || (sd->direction == DIRECTION_AUTO && sd->para_direction == DIRECTION_RTL); @@ -3663,7 +3688,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re if (add_ellipsis && (ellipsis_pos > 0 || enforce_ellipsis)) { // Insert an additional space when cutting word bound for aesthetics. if (cut_per_word && (ellipsis_pos > 0)) { - TextServer::Glyph gl; + Glyph gl; gl.count = 1; gl.advance = whitespace_adv.x; gl.index = whitespace_gl_idx; @@ -3674,7 +3699,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); } // Add ellipsis dots. - TextServer::Glyph gl; + Glyph gl; gl.count = 1; gl.repeat = 3; gl.advance = dot_adv.x; @@ -3691,16 +3716,40 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(RID p_shaped_line, re } } -TextServer::TrimData TextServerAdvanced::shaped_text_get_trim_data(RID p_shaped) const { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V_MSG(!sd, TrimData(), "ShapedTextDataAdvanced invalid."); +int TextServerAdvanced::shaped_text_get_trim_pos(RID p_shaped) const { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid."); MutexLock lock(sd->mutex); - return sd->overrun_trim_data; + return sd->overrun_trim_data.trim_pos; +} + +int TextServerAdvanced::shaped_text_get_ellipsis_pos(RID p_shaped) const { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid."); + + MutexLock lock(sd->mutex); + return sd->overrun_trim_data.ellipsis_pos; +} + +const Glyph *TextServerAdvanced::shaped_text_get_ellipsis_glyphs(RID p_shaped) const { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextDataAdvanced invalid."); + + MutexLock lock(sd->mutex); + return sd->overrun_trim_data.ellipsis_glyph_buf.ptr(); +} + +int TextServerAdvanced::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextDataAdvanced invalid."); + + MutexLock lock(sd->mutex); + return sd->overrun_trim_data.ellipsis_glyph_buf.size(); } bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -3783,7 +3832,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) { if (is_whitespace(c)) { sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT; } else { - TextServer::Glyph gl; + Glyph gl; gl.start = sd_glyphs[i].start; gl.end = sd_glyphs[i].end; gl.count = 1; @@ -3892,7 +3941,7 @@ _FORCE_INLINE_ int _generate_kashida_justification_opportunies(const String &p_d } bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -3964,7 +4013,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) { sd->glyphs.write[i].flags |= GRAPHEME_IS_ELONGATION; } else { if (sd->glyphs[i].font_rid != RID()) { - TextServer::Glyph gl = _shape_single_glyph(sd, 0x0640, HB_SCRIPT_ARABIC, HB_DIRECTION_RTL, sd->glyphs[i].font_rid, sd->glyphs[i].font_size); + Glyph gl = _shape_single_glyph(sd, 0x0640, HB_SCRIPT_ARABIC, HB_DIRECTION_RTL, sd->glyphs[i].font_rid, sd->glyphs[i].font_size); if ((gl.flags & GRAPHEME_IS_VALID) == GRAPHEME_IS_VALID) { gl.start = sd->glyphs[i].start; gl.end = sd->glyphs[i].end; @@ -3982,7 +4031,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) { } } } else if (!is_whitespace(c)) { - TextServer::Glyph gl; + Glyph gl; gl.start = sd->glyphs[i].start; gl.end = sd->glyphs[i].end; gl.count = 1; @@ -4007,9 +4056,9 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) { return sd->justification_ops_valid; } -TextServer::Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size) { +Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size) { hb_font_t *hb_font = _font_get_hb_handle(p_font, p_font_size); - ERR_FAIL_COND_V(hb_font == nullptr, TextServer::Glyph()); + ERR_FAIL_COND_V(hb_font == nullptr, Glyph()); hb_buffer_clear_contents(p_sd->hb_buffer); hb_buffer_set_direction(p_sd->hb_buffer, p_direction); @@ -4024,7 +4073,7 @@ TextServer::Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(p_sd->hb_buffer, &glyph_count); // Process glyphs. - TextServer::Glyph gl; + Glyph gl; if (p_direction == HB_DIRECTION_RTL || p_direction == HB_DIRECTION_BTT) { gl.flags |= TextServer::GRAPHEME_IS_RTL; @@ -4034,7 +4083,7 @@ TextServer::Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced gl.font_size = p_font_size; if (glyph_count > 0) { - real_t scale = font_get_scale(p_font, p_font_size); + float scale = font_get_scale(p_font, p_font_size); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale)); } else { @@ -4059,7 +4108,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star // Add fallback glyphs. for (int i = p_start; i < p_end; i++) { if (p_sd->preserve_invalid || (p_sd->preserve_control && is_control(p_sd->text[i]))) { - TextServer::Glyph gl; + Glyph gl; gl.start = i; gl.end = i + 1; gl.count = 1; @@ -4071,8 +4120,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star } if (p_sd->orientation == ORIENTATION_HORIZONTAL) { gl.advance = get_hex_code_box_size(fs, gl.index).x; - p_sd->ascent = MAX(p_sd->ascent, Math::round(get_hex_code_box_size(fs, gl.index).y * 0.75f)); - p_sd->descent = MAX(p_sd->descent, Math::round(get_hex_code_box_size(fs, gl.index).y * 0.25f)); + p_sd->ascent = MAX(p_sd->ascent, get_hex_code_box_size(fs, gl.index).y); } else { gl.advance = get_hex_code_box_size(fs, gl.index).y; p_sd->ascent = MAX(p_sd->ascent, Math::round(get_hex_code_box_size(fs, gl.index).x * 0.5f)); @@ -4126,7 +4174,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star // Process glyphs. if (glyph_count > 0) { - TextServer::Glyph *w = (TextServer::Glyph *)memalloc(glyph_count * sizeof(TextServer::Glyph)); + Glyph *w = (Glyph *)memalloc(glyph_count * sizeof(Glyph)); int end = (p_direction == HB_DIRECTION_RTL || p_direction == HB_DIRECTION_BTT) ? p_end : 0; uint32_t last_cluster_id = UINT32_MAX; @@ -4155,8 +4203,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star last_cluster_id = glyph_info[i].cluster; - TextServer::Glyph &gl = w[i]; - gl = TextServer::Glyph(); + Glyph &gl = w[i]; + gl = Glyph(); gl.start = glyph_info[i].cluster; gl.end = end; @@ -4171,7 +4219,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star gl.index = glyph_info[i].codepoint; if (gl.index != 0) { - real_t scale = font_get_scale(f, fs); + float scale = font_get_scale(f, fs); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale)); } else { @@ -4249,7 +4297,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star } bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -4411,65 +4459,65 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { } // Align embedded objects to baseline. - real_t full_ascent = sd->ascent; - real_t full_descent = sd->descent; - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { + float full_ascent = sd->ascent; + float full_descent = sd->descent; + for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.y = -sd->ascent; + E.value.rect.position.y = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.y = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.y = 0; + E.value.rect.position.y = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.y = sd->descent; + E.value.rect.position.y = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.y -= E->get().rect.size.y; + E.value.rect.position.y -= E.value.rect.size.y; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.y -= E->get().rect.size.y / 2; + E.value.rect.position.y -= E.value.rect.size.y / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.y); - full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y); + full_ascent = MAX(full_ascent, -E.value.rect.position.y); + full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.x = -sd->ascent; + E.value.rect.position.x = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.x = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.x = 0; + E.value.rect.position.x = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.x = sd->descent; + E.value.rect.position.x = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.x -= E->get().rect.size.x; + E.value.rect.position.x -= E.value.rect.size.x; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.x -= E->get().rect.size.x / 2; + E.value.rect.position.x -= E.value.rect.size.x / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.x); - full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x); + full_ascent = MAX(full_ascent, -E.value.rect.position.x); + full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x); } } sd->ascent = full_ascent; @@ -4479,35 +4527,38 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) { } bool TextServerAdvanced::shaped_text_is_ready(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); return sd->valid; } -Vector<TextServer::Glyph> TextServerAdvanced::shaped_text_get_glyphs(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>()); +const Glyph *TextServerAdvanced::shaped_text_get_glyphs(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, nullptr); MutexLock lock(sd->mutex); if (!sd->valid) { const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped); } - return sd->glyphs; + return sd->glyphs.ptr(); } -Vector2i TextServerAdvanced::shaped_text_get_range(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V(!sd, Vector2i()); +int TextServerAdvanced::shaped_text_get_glyph_count(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, 0); MutexLock lock(sd->mutex); - return Vector2(sd->start, sd->end); + if (!sd->valid) { + const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped); + } + return sd->glyphs.size(); } -Vector<TextServer::Glyph> TextServerAdvanced::shaped_text_sort_logical(RID p_shaped) { - ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>()); +const Glyph *TextServerAdvanced::shaped_text_sort_logical(RID p_shaped) { + ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, nullptr); MutexLock lock(sd->mutex); if (!sd->valid) { @@ -4516,28 +4567,36 @@ Vector<TextServer::Glyph> TextServerAdvanced::shaped_text_sort_logical(RID p_sha if (!sd->sort_valid) { sd->glyphs_logical = sd->glyphs; - sd->glyphs_logical.sort_custom<TextServer::GlyphCompare>(); + sd->glyphs_logical.sort_custom<GlyphCompare>(); sd->sort_valid = true; } - return sd->glyphs_logical; + return sd->glyphs_logical.ptr(); +} + +Vector2i TextServerAdvanced::shaped_text_get_range(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, Vector2i()); + + MutexLock lock(sd->mutex); + return Vector2(sd->start, sd->end); } Array TextServerAdvanced::shaped_text_get_objects(RID p_shaped) const { Array ret; - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, ret); MutexLock lock(sd->mutex); - for (const Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + ret.push_back(E.key); } return ret; } Rect2 TextServerAdvanced::shaped_text_get_object_rect(RID p_shaped, Variant p_key) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, Rect2()); MutexLock lock(sd->mutex); @@ -4549,7 +4608,7 @@ Rect2 TextServerAdvanced::shaped_text_get_object_rect(RID p_shaped, Variant p_ke } Size2 TextServerAdvanced::shaped_text_get_size(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, Size2()); MutexLock lock(sd->mutex); @@ -4563,8 +4622,8 @@ Size2 TextServerAdvanced::shaped_text_get_size(RID p_shaped) const { } } -real_t TextServerAdvanced::shaped_text_get_ascent(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +float TextServerAdvanced::shaped_text_get_ascent(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -4574,8 +4633,8 @@ real_t TextServerAdvanced::shaped_text_get_ascent(RID p_shaped) const { return sd->ascent; } -real_t TextServerAdvanced::shaped_text_get_descent(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +float TextServerAdvanced::shaped_text_get_descent(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -4585,8 +4644,8 @@ real_t TextServerAdvanced::shaped_text_get_descent(RID p_shaped) const { return sd->descent; } -real_t TextServerAdvanced::shaped_text_get_width(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +float TextServerAdvanced::shaped_text_get_width(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -4596,8 +4655,8 @@ real_t TextServerAdvanced::shaped_text_get_width(RID p_shaped) const { return (sd->text_trimmed ? sd->width_trimmed : sd->width); } -real_t TextServerAdvanced::shaped_text_get_underline_position(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +float TextServerAdvanced::shaped_text_get_underline_position(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -4608,8 +4667,8 @@ real_t TextServerAdvanced::shaped_text_get_underline_position(RID p_shaped) cons return sd->upos; } -real_t TextServerAdvanced::shaped_text_get_underline_thickness(RID p_shaped) const { - const ShapedTextDataAdvanced *sd = shaped_owner.getornull(p_shaped); +float TextServerAdvanced::shaped_text_get_underline_thickness(RID p_shaped) const { + const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -4752,15 +4811,6 @@ String TextServerAdvanced::percent_sign(const String &p_language) const { return "%"; } -TextServer *TextServerAdvanced::create_func(Error &r_error, void *p_user_data) { - r_error = OK; - return memnew(TextServerAdvanced()); -} - -void TextServerAdvanced::register_server() { - TextServerManager::register_create_function(interface_name, interface_features, create_func, nullptr); -} - TextServerAdvanced::TextServerAdvanced() { _insert_num_systems_lang(); _insert_feature_sets(); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index fc0e7a09a7..1feeada76d 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -115,12 +115,12 @@ class TextServerAdvanced : public TextServer { }; struct FontDataForSizeAdvanced { - real_t ascent = 0.f; - real_t descent = 0.f; - real_t underline_position = 0.f; - real_t underline_thickness = 0.f; - real_t scale = 1.f; - real_t oversampling = 1.f; + float ascent = 0.f; + float descent = 0.f; + float underline_position = 0.f; + float underline_thickness = 0.f; + float scale = 1.f; + float oversampling = 1.f; int spacing_glyph = 0; int spacing_space = 0; @@ -161,7 +161,7 @@ class TextServerAdvanced : public TextServer { bool force_autohinter = false; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; Dictionary variation_coordinates; - real_t oversampling = 0.f; + float oversampling = 0.f; Map<Vector2i, FontDataForSizeAdvanced *> cache; @@ -245,14 +245,14 @@ class TextServerAdvanced : public TextServer { // Common data. - real_t oversampling = 1.f; + float oversampling = 1.f; mutable RID_PtrOwner<FontDataAdvanced> font_owner; mutable RID_PtrOwner<ShapedTextDataAdvanced> shaped_owner; int _convert_pos(const ShapedTextDataAdvanced *p_sd, int p_pos) const; int _convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int p_pos) const; void _shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index); - TextServer::Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size); + Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size); // HarfBuzz bitmap font interface. @@ -284,20 +284,19 @@ protected: void invalidate(ShapedTextDataAdvanced *p_shaped); public: - virtual bool has_feature(Feature p_feature) override; + virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; + virtual uint32_t get_features() const override; virtual void free(RID p_rid) override; virtual bool has(RID p_rid) override; virtual bool load_support_data(const String &p_filename) override; -#ifdef TOOLS_ENABLED - virtual String get_support_data_filename() override { return _MKSTR(ICU_DATA_NAME); }; - virtual String get_support_data_info() override { return String("ICU break iteration data (") + _MKSTR(ICU_DATA_NAME) + String(")."); }; - virtual bool save_support_data(const String &p_filename) override; -#endif + virtual String get_support_data_filename() const override; + virtual String get_support_data_info() const override; + virtual bool save_support_data(const String &p_filename) const override; - virtual bool is_locale_right_to_left(const String &p_locale) override; + virtual bool is_locale_right_to_left(const String &p_locale) const override; virtual int32_t name_to_tag(const String &p_name) const override; virtual String tag_to_name(int32_t p_tag) const override; @@ -332,8 +331,8 @@ public: virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; - virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) override; - virtual real_t font_get_oversampling(RID p_font_rid) const override; + virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override; + virtual float font_get_oversampling(RID p_font_rid) const override; virtual Array font_get_size_cache_list(RID p_font_rid) const override; virtual void font_clear_size_cache(RID p_font_rid) override; @@ -341,20 +340,20 @@ public: hb_font_t *_font_get_hb_handle(RID p_font, int p_font_size) const; - virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) override; - virtual real_t font_get_ascent(RID p_font_rid, int p_size) const override; + virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override; + virtual float font_get_ascent(RID p_font_rid, int p_size) const override; - virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) override; - virtual real_t font_get_descent(RID p_font_rid, int p_size) const override; + virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override; + virtual float font_get_descent(RID p_font_rid, int p_size) const override; - virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) override; - virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const override; + virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override; + virtual float font_get_underline_position(RID p_font_rid, int p_size) const override; - virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) override; - virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const override; + virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override; + virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override; - virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) override; - virtual real_t font_get_scale(RID p_font_rid, int p_size) const override; + virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override; + virtual float font_get_scale(RID p_font_rid, int p_size) const override; virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override; virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override; @@ -388,7 +387,7 @@ public: virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override; - virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override; + virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override; virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override; virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override; @@ -423,8 +422,8 @@ public: virtual Dictionary font_supported_feature_list(RID p_font_rid) const override; virtual Dictionary font_supported_variation_list(RID p_font_rid) const override; - virtual real_t font_get_global_oversampling() const override; - virtual void font_set_global_oversampling(real_t p_oversampling) override; + virtual float font_get_global_oversampling() const override; + virtual void font_set_global_oversampling(float p_oversampling) override; /* Shaped text buffer interface */ @@ -435,7 +434,7 @@ public: virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; virtual Direction shaped_text_get_direction(RID p_shaped) const override; - virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) override; + virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; virtual Orientation shaped_text_get_orientation(RID p_shaped) const override; @@ -453,41 +452,42 @@ public: virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override; virtual RID shaped_text_get_parent(RID p_shaped) const override; - virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; - virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) override; + virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; + virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override; virtual bool shaped_text_shape(RID p_shaped) override; virtual bool shaped_text_update_breaks(RID p_shaped) override; virtual bool shaped_text_update_justification_ops(RID p_shaped) override; - virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) override; - virtual TrimData shaped_text_get_trim_data(RID p_shaped) const override; + virtual int shaped_text_get_trim_pos(RID p_shaped) const override; + virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override; + virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override; + virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override; + + virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override; virtual bool shaped_text_is_ready(RID p_shaped) const override; - virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override; + virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override; + virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override; + virtual int shaped_text_get_glyph_count(RID p_shaped) const override; virtual Vector2i shaped_text_get_range(RID p_shaped) const override; - virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) override; - virtual Array shaped_text_get_objects(RID p_shaped) const override; virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override; virtual Size2 shaped_text_get_size(RID p_shaped) const override; - virtual real_t shaped_text_get_ascent(RID p_shaped) const override; - virtual real_t shaped_text_get_descent(RID p_shaped) const override; - virtual real_t shaped_text_get_width(RID p_shaped) const override; - virtual real_t shaped_text_get_underline_position(RID p_shaped) const override; - virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const override; + virtual float shaped_text_get_ascent(RID p_shaped) const override; + virtual float shaped_text_get_descent(RID p_shaped) const override; + virtual float shaped_text_get_width(RID p_shaped) const override; + virtual float shaped_text_get_underline_position(RID p_shaped) const override; + virtual float shaped_text_get_underline_thickness(RID p_shaped) const override; virtual String format_number(const String &p_string, const String &p_language = "") const override; virtual String parse_number(const String &p_string, const String &p_language = "") const override; virtual String percent_sign(const String &p_language = "") const override; - static TextServer *create_func(Error &r_error, void *p_user_data); - static void register_server(); - TextServerAdvanced(); ~TextServerAdvanced(); }; diff --git a/modules/text_server_fb/config.py b/modules/text_server_fb/config.py index 7a73080ae9..275c2b4d53 100644 --- a/modules/text_server_fb/config.py +++ b/modules/text_server_fb/config.py @@ -9,3 +9,13 @@ def configure(env): def is_enabled(): # The module is disabled by default. Use module_text_server_fb_enabled=yes to enable it. return False + + +def get_doc_classes(): + return [ + "TextServerFallback", + ] + + +def get_doc_path(): + return "doc_classes" diff --git a/modules/text_server_fb/doc_classes/TextServerFallback.xml b/modules/text_server_fb/doc_classes/TextServerFallback.xml new file mode 100644 index 0000000000..8aadf2b882 --- /dev/null +++ b/modules/text_server_fb/doc_classes/TextServerFallback.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="TextServerFallback" inherits="TextServer" version="4.0"> + <brief_description> + Fallback implementation of the Text Server, without BiDi and complex text layout support. + </brief_description> + <description> + </description> + <tutorials> + </tutorials> +</class> diff --git a/modules/text_server_fb/register_types.cpp b/modules/text_server_fb/register_types.cpp index 87cbd2ac2c..0b59040ce8 100644 --- a/modules/text_server_fb/register_types.cpp +++ b/modules/text_server_fb/register_types.cpp @@ -33,7 +33,12 @@ #include "text_server_fb.h" void preregister_text_server_fb_types() { - TextServerFallback::register_server(); + GDREGISTER_CLASS(TextServerFallback); + if (TextServerManager::get_singleton()) { + Ref<TextServerFallback> ts; + ts.instantiate(); + TextServerManager::get_singleton()->add_interface(ts); + } } void register_text_server_fb_types() { diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 1323aa80ce..3d868d7be3 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -69,7 +69,7 @@ _FORCE_INLINE_ bool is_underscore(char32_t p_char) { String TextServerFallback::interface_name = "Fallback"; uint32_t TextServerFallback::interface_features = 0; // Nothing is supported. -bool TextServerFallback::has_feature(Feature p_feature) { +bool TextServerFallback::has_feature(Feature p_feature) const { return (interface_features & p_feature) == p_feature; } @@ -77,14 +77,18 @@ String TextServerFallback::get_name() const { return interface_name; } +uint32_t TextServerFallback::get_features() const { + return interface_features; +} + void TextServerFallback::free(RID p_rid) { _THREAD_SAFE_METHOD_ if (font_owner.owns(p_rid)) { - FontDataFallback *fd = font_owner.getornull(p_rid); + FontDataFallback *fd = font_owner.get_or_null(p_rid); font_owner.free(p_rid); memdelete(fd); } else if (shaped_owner.owns(p_rid)) { - ShapedTextData *sd = shaped_owner.getornull(p_rid); + ShapedTextData *sd = shaped_owner.get_or_null(p_rid); shaped_owner.free(p_rid); memdelete(sd); } @@ -99,15 +103,11 @@ bool TextServerFallback::load_support_data(const String &p_filename) { return false; // No extra data used. } -#ifdef TOOLS_ENABLED - -bool TextServerFallback::save_support_data(const String &p_filename) { +bool TextServerFallback::save_support_data(const String &p_filename) const { return false; // No extra data used. } -#endif - -bool TextServerFallback::is_locale_right_to_left(const String &p_locale) { +bool TextServerFallback::is_locale_right_to_left(const String &p_locale) const { return false; // No RTL support. } @@ -420,7 +420,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( FontTexture &tex = p_data->textures.write[tex_pos.index]; edgeColoringSimple(shape, 3.0); // Max. angle. - msdfgen::Bitmap<real_t, 4> image(w, h); // Texture size. + msdfgen::Bitmap<float, 4> image(w, h); // Texture size. //msdfgen::generateMTSDF(image, shape, p_pixel_range, 1.0, msdfgen::Vector2(-bounds.l, -bounds.b)); // Range, scale, translation. DistancePixelConversion distancePixelConversion(p_pixel_range); @@ -611,14 +611,16 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontDataFallback *p_font_d flags |= FT_LOAD_COLOR; } + int32_t glyph_index = FT_Get_Char_Index(fd->face, p_glyph); + FT_Fixed v, h; - FT_Get_Advance(fd->face, p_glyph, flags, &h); - FT_Get_Advance(fd->face, p_glyph, flags | FT_LOAD_VERTICAL_LAYOUT, &v); + FT_Get_Advance(fd->face, glyph_index, flags, &h); + FT_Get_Advance(fd->face, glyph_index, flags | FT_LOAD_VERTICAL_LAYOUT, &v); - int error = FT_Load_Glyph(fd->face, p_glyph, flags); + int error = FT_Load_Glyph(fd->face, glyph_index, flags); if (error) { fd->glyph_map[p_glyph] = FontGlyph(); - ERR_FAIL_V_MSG(false, "FreeType: Failed to load glyph."); + return false; } if (!outline) { @@ -712,7 +714,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback fd->oversampling = 1.0f; fd->size.x = p_font_data->msdf_source_size; } else if (p_font_data->oversampling <= 0.0f) { - fd->oversampling = TS->font_get_global_oversampling(); + fd->oversampling = font_get_global_oversampling(); } else { fd->oversampling = p_font_data->oversampling; } @@ -720,13 +722,13 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback if (FT_HAS_COLOR(fd->face) && fd->face->num_fixed_sizes > 0) { int best_match = 0; int diff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[0].width)); - fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width; + fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[0].width; for (int i = 1; i < fd->face->num_fixed_sizes; i++) { int ndiff = ABS(fd->size.x - ((int64_t)fd->face->available_sizes[i].width)); if (ndiff < diff) { best_match = i; diff = ndiff; - fd->scale = real_t(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width; + fd->scale = float(fd->size.x * fd->oversampling) / fd->face->available_sizes[i].width; } } FT_Select_Size(fd->face, best_match); @@ -767,7 +769,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback for (FT_UInt i = 0; i < amaster->num_axis; i++) { // Reset to default. int32_t var_tag = amaster->axis[i].tag; - real_t var_value = (double)amaster->axis[i].def / 65536.f; + float var_value = (double)amaster->axis[i].def / 65536.f; coords.write[i] = amaster->axis[i].def; if (p_font_data->variation_coordinates.has(var_tag)) { @@ -793,8 +795,8 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontDataFallback } _FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontDataFallback *p_font_data) { - for (const Map<Vector2i, FontDataForSizeFallback *>::Element *E = p_font_data->cache.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : p_font_data->cache) { + memdelete(E.value); } p_font_data->cache.clear(); @@ -809,7 +811,7 @@ RID TextServerFallback::create_font() { } void TextServerFallback::font_set_data(RID p_font_rid, const PackedByteArray &p_data) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -820,7 +822,7 @@ void TextServerFallback::font_set_data(RID p_font_rid, const PackedByteArray &p_ } void TextServerFallback::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -831,7 +833,7 @@ void TextServerFallback::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data } void TextServerFallback::font_set_antialiased(RID p_font_rid, bool p_antialiased) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -842,7 +844,7 @@ void TextServerFallback::font_set_antialiased(RID p_font_rid, bool p_antialiased } bool TextServerFallback::font_is_antialiased(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -850,7 +852,7 @@ bool TextServerFallback::font_is_antialiased(RID p_font_rid) const { } void TextServerFallback::font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -861,7 +863,7 @@ void TextServerFallback::font_set_multichannel_signed_distance_field(RID p_font_ } bool TextServerFallback::font_is_multichannel_signed_distance_field(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -869,7 +871,7 @@ bool TextServerFallback::font_is_multichannel_signed_distance_field(RID p_font_r } void TextServerFallback::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -880,7 +882,7 @@ void TextServerFallback::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pi } int TextServerFallback::font_get_msdf_pixel_range(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -888,7 +890,7 @@ int TextServerFallback::font_get_msdf_pixel_range(RID p_font_rid) const { } void TextServerFallback::font_set_msdf_size(RID p_font_rid, int p_msdf_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -899,7 +901,7 @@ void TextServerFallback::font_set_msdf_size(RID p_font_rid, int p_msdf_size) { } int TextServerFallback::font_get_msdf_size(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -907,7 +909,7 @@ int TextServerFallback::font_get_msdf_size(RID p_font_rid) const { } void TextServerFallback::font_set_fixed_size(RID p_font_rid, int p_fixed_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -917,7 +919,7 @@ void TextServerFallback::font_set_fixed_size(RID p_font_rid, int p_fixed_size) { } int TextServerFallback::font_get_fixed_size(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -925,7 +927,7 @@ int TextServerFallback::font_get_fixed_size(RID p_font_rid) const { } void TextServerFallback::font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -936,7 +938,7 @@ void TextServerFallback::font_set_force_autohinter(RID p_font_rid, bool p_force_ } bool TextServerFallback::font_is_force_autohinter(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -944,7 +946,7 @@ bool TextServerFallback::font_is_force_autohinter(RID p_font_rid) const { } void TextServerFallback::font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -955,7 +957,7 @@ void TextServerFallback::font_set_hinting(RID p_font_rid, TextServer::Hinting p_ } TextServer::Hinting TextServerFallback::font_get_hinting(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, HINTING_NONE); MutexLock lock(fd->mutex); @@ -963,7 +965,7 @@ TextServer::Hinting TextServerFallback::font_get_hinting(RID p_font_rid) const { } void TextServerFallback::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -974,15 +976,15 @@ void TextServerFallback::font_set_variation_coordinates(RID p_font_rid, const Di } Dictionary TextServerFallback::font_get_variation_coordinates(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); MutexLock lock(fd->mutex); return fd->variation_coordinates; } -void TextServerFallback::font_set_oversampling(RID p_font_rid, real_t p_oversampling) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +void TextServerFallback::font_set_oversampling(RID p_font_rid, float p_oversampling) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -992,8 +994,8 @@ void TextServerFallback::font_set_oversampling(RID p_font_rid, real_t p_oversamp } } -real_t TextServerFallback::font_get_oversampling(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +float TextServerFallback::font_get_oversampling(RID p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1001,30 +1003,30 @@ real_t TextServerFallback::font_get_oversampling(RID p_font_rid) const { } Array TextServerFallback::font_get_size_cache_list(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Array()); MutexLock lock(fd->mutex); Array ret; - for (const Map<Vector2i, FontDataForSizeFallback *>::Element *E = fd->cache.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : fd->cache) { + ret.push_back(E.key); } return ret; } void TextServerFallback::font_clear_size_cache(RID p_font_rid) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); - for (const Map<Vector2i, FontDataForSizeFallback *>::Element *E = fd->cache.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : fd->cache) { + memdelete(E.value); } fd->cache.clear(); } void TextServerFallback::font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1034,8 +1036,8 @@ void TextServerFallback::font_remove_size_cache(RID p_font_rid, const Vector2i & } } -void TextServerFallback::font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +void TextServerFallback::font_set_ascent(RID p_font_rid, int p_size, float p_ascent) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1045,8 +1047,8 @@ void TextServerFallback::font_set_ascent(RID p_font_rid, int p_size, real_t p_as fd->cache[size]->ascent = p_ascent; } -real_t TextServerFallback::font_get_ascent(RID p_font_rid, int p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +float TextServerFallback::font_get_ascent(RID p_font_rid, int p_size) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1055,14 +1057,14 @@ real_t TextServerFallback::font_get_ascent(RID p_font_rid, int p_size) const { ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->ascent * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->ascent * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->ascent; } } -void TextServerFallback::font_set_descent(RID p_font_rid, int p_size, real_t p_descent) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +void TextServerFallback::font_set_descent(RID p_font_rid, int p_size, float p_descent) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); Vector2i size = _get_size(fd, p_size); @@ -1071,8 +1073,8 @@ void TextServerFallback::font_set_descent(RID p_font_rid, int p_size, real_t p_d fd->cache[size]->descent = p_descent; } -real_t TextServerFallback::font_get_descent(RID p_font_rid, int p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +float TextServerFallback::font_get_descent(RID p_font_rid, int p_size) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1081,14 +1083,14 @@ real_t TextServerFallback::font_get_descent(RID p_font_rid, int p_size) const { ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->descent * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->descent * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->descent; } } -void TextServerFallback::font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +void TextServerFallback::font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1098,8 +1100,8 @@ void TextServerFallback::font_set_underline_position(RID p_font_rid, int p_size, fd->cache[size]->underline_position = p_underline_position; } -real_t TextServerFallback::font_get_underline_position(RID p_font_rid, int p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +float TextServerFallback::font_get_underline_position(RID p_font_rid, int p_size) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1108,14 +1110,14 @@ real_t TextServerFallback::font_get_underline_position(RID p_font_rid, int p_siz ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->underline_position * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->underline_position * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->underline_position; } } -void TextServerFallback::font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +void TextServerFallback::font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1125,8 +1127,8 @@ void TextServerFallback::font_set_underline_thickness(RID p_font_rid, int p_size fd->cache[size]->underline_thickness = p_underline_thickness; } -real_t TextServerFallback::font_get_underline_thickness(RID p_font_rid, int p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +float TextServerFallback::font_get_underline_thickness(RID p_font_rid, int p_size) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1135,14 +1137,14 @@ real_t TextServerFallback::font_get_underline_thickness(RID p_font_rid, int p_si ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->underline_thickness * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->underline_thickness * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->underline_thickness; } } -void TextServerFallback::font_set_scale(RID p_font_rid, int p_size, real_t p_scale) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +void TextServerFallback::font_set_scale(RID p_font_rid, int p_size, float p_scale) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1152,8 +1154,8 @@ void TextServerFallback::font_set_scale(RID p_font_rid, int p_size, real_t p_sca fd->cache[size]->scale = p_scale; } -real_t TextServerFallback::font_get_scale(RID p_font_rid, int p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); +float TextServerFallback::font_get_scale(RID p_font_rid, int p_size) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0.f); MutexLock lock(fd->mutex); @@ -1162,14 +1164,14 @@ real_t TextServerFallback::font_get_scale(RID p_font_rid, int p_size) const { ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0.f); if (fd->msdf) { - return fd->cache[size]->scale * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->scale * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->scale / fd->cache[size]->oversampling; } } void TextServerFallback::font_set_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing, int p_value) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1190,7 +1192,7 @@ void TextServerFallback::font_set_spacing(RID p_font_rid, int p_size, TextServer } int TextServerFallback::font_get_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0); MutexLock lock(fd->mutex); @@ -1201,14 +1203,14 @@ int TextServerFallback::font_get_spacing(RID p_font_rid, int p_size, TextServer: switch (p_spacing) { case TextServer::SPACING_GLYPH: { if (fd->msdf) { - return fd->cache[size]->spacing_glyph * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->spacing_glyph * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->spacing_glyph; } } break; case TextServer::SPACING_SPACE: { if (fd->msdf) { - return fd->cache[size]->spacing_space * (real_t)p_size / (real_t)fd->msdf_source_size; + return fd->cache[size]->spacing_space * (float)p_size / (float)fd->msdf_source_size; } else { return fd->cache[size]->spacing_space; } @@ -1221,7 +1223,7 @@ int TextServerFallback::font_get_spacing(RID p_font_rid, int p_size, TextServer: } int TextServerFallback::font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, 0); MutexLock lock(fd->mutex); @@ -1233,7 +1235,7 @@ int TextServerFallback::font_get_texture_count(RID p_font_rid, const Vector2i &p } void TextServerFallback::font_clear_textures(RID p_font_rid, const Vector2i &p_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); @@ -1243,7 +1245,7 @@ void TextServerFallback::font_clear_textures(RID p_font_rid, const Vector2i &p_s } void TextServerFallback::font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1255,7 +1257,7 @@ void TextServerFallback::font_remove_texture(RID p_font_rid, const Vector2i &p_s } void TextServerFallback::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); ERR_FAIL_COND(p_image.is_null()); @@ -1281,7 +1283,7 @@ void TextServerFallback::font_set_texture_image(RID p_font_rid, const Vector2i & } Ref<Image> TextServerFallback::font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Ref<Image>()); MutexLock lock(fd->mutex); @@ -1296,7 +1298,7 @@ Ref<Image> TextServerFallback::font_get_texture_image(RID p_font_rid, const Vect } void TextServerFallback::font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1311,7 +1313,7 @@ void TextServerFallback::font_set_texture_offsets(RID p_font_rid, const Vector2i } PackedInt32Array TextServerFallback::font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, PackedInt32Array()); MutexLock lock(fd->mutex); @@ -1324,7 +1326,7 @@ PackedInt32Array TextServerFallback::font_get_texture_offsets(RID p_font_rid, co } Array TextServerFallback::font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Array()); MutexLock lock(fd->mutex); @@ -1341,7 +1343,7 @@ Array TextServerFallback::font_get_glyph_list(RID p_font_rid, const Vector2i &p_ } void TextServerFallback::font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1352,7 +1354,7 @@ void TextServerFallback::font_clear_glyphs(RID p_font_rid, const Vector2i &p_siz } void TextServerFallback::font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1363,7 +1365,7 @@ void TextServerFallback::font_remove_glyph(RID p_font_rid, const Vector2i &p_siz } Vector2 TextServerFallback::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -1377,14 +1379,14 @@ Vector2 TextServerFallback::font_get_glyph_advance(RID p_font_rid, int p_size, i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; if (fd->msdf) { - return gl[p_glyph].advance * (real_t)p_size / (real_t)fd->msdf_source_size; + return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size; } else { return gl[p_glyph].advance; } } void TextServerFallback::font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1399,7 +1401,7 @@ void TextServerFallback::font_set_glyph_advance(RID p_font_rid, int p_size, int3 } Vector2 TextServerFallback::font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -1413,14 +1415,14 @@ Vector2 TextServerFallback::font_get_glyph_offset(RID p_font_rid, const Vector2i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; if (fd->msdf) { - return gl[p_glyph].rect.position * (real_t)p_size.x / (real_t)fd->msdf_source_size; + return gl[p_glyph].rect.position * (float)p_size.x / (float)fd->msdf_source_size; } else { return gl[p_glyph].rect.position; } } void TextServerFallback::font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1435,7 +1437,7 @@ void TextServerFallback::font_set_glyph_offset(RID p_font_rid, const Vector2i &p } Vector2 TextServerFallback::font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -1449,14 +1451,14 @@ Vector2 TextServerFallback::font_get_glyph_size(RID p_font_rid, const Vector2i & const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; if (fd->msdf) { - return gl[p_glyph].rect.size * (real_t)p_size.x / (real_t)fd->msdf_source_size; + return gl[p_glyph].rect.size * (float)p_size.x / (float)fd->msdf_source_size; } else { return gl[p_glyph].rect.size; } } void TextServerFallback::font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1471,7 +1473,7 @@ void TextServerFallback::font_set_glyph_size(RID p_font_rid, const Vector2i &p_s } Rect2 TextServerFallback::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Rect2()); MutexLock lock(fd->mutex); @@ -1487,7 +1489,7 @@ Rect2 TextServerFallback::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i } void TextServerFallback::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1502,7 +1504,7 @@ void TextServerFallback::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i & } int TextServerFallback::font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, -1); MutexLock lock(fd->mutex); @@ -1518,7 +1520,7 @@ int TextServerFallback::font_get_glyph_texture_idx(RID p_font_rid, const Vector2 } void TextServerFallback::font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1532,42 +1534,50 @@ void TextServerFallback::font_set_glyph_texture_idx(RID p_font_rid, const Vector gl[p_glyph].found = true; } -bool TextServerFallback::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); - ERR_FAIL_COND_V(!fd, false); +Dictionary TextServerFallback::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Dictionary()); MutexLock lock(fd->mutex); Vector2i size = _get_size(fd, p_size); - ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), false); + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Dictionary()); + Vector<Vector3> points; + Vector<int32_t> contours; + bool orientation; #ifdef MODULE_FREETYPE_ENABLED - int error = FT_Load_Glyph(fd->cache[size]->face, p_index, FT_LOAD_NO_BITMAP | (fd->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)); - ERR_FAIL_COND_V(error, false); + int error = FT_Load_Glyph(fd->cache[size]->face, FT_Get_Char_Index(fd->cache[size]->face, p_index), FT_LOAD_NO_BITMAP | (fd->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)); + ERR_FAIL_COND_V(error, Dictionary()); - r_points.clear(); - r_contours.clear(); + points.clear(); + contours.clear(); - real_t h = fd->cache[size]->ascent; - real_t scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale; + float h = fd->cache[size]->ascent; + float scale = (1.0 / 64.0) / fd->cache[size]->oversampling * fd->cache[size]->scale; if (fd->msdf) { - scale = scale * (real_t)p_size / (real_t)fd->msdf_source_size; + scale = scale * (float)p_size / (float)fd->msdf_source_size; } for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_points; i++) { - r_points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i]))); + points.push_back(Vector3(fd->cache[size]->face->glyph->outline.points[i].x * scale, h - fd->cache[size]->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fd->cache[size]->face->glyph->outline.tags[i]))); } for (short i = 0; i < fd->cache[size]->face->glyph->outline.n_contours; i++) { - r_contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]); + contours.push_back(fd->cache[size]->face->glyph->outline.contours[i]); } - r_orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT); + orientation = (FT_Outline_Get_Orientation(&fd->cache[size]->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT); #else - return false; + return Dictionary(); #endif - return true; + + Dictionary out; + out["points"] = points; + out["contours"] = contours; + out["orientation"] = orientation; + return out; } Array TextServerFallback::font_get_kerning_list(RID p_font_rid, int p_size) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Array()); MutexLock lock(fd->mutex); @@ -1576,14 +1586,14 @@ Array TextServerFallback::font_get_kerning_list(RID p_font_rid, int p_size) cons ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Array()); Array ret; - for (const Map<Vector2i, Vector2>::Element *E = fd->cache[size]->kerning_map.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<Vector2i, Vector2> &E : fd->cache[size]->kerning_map) { + ret.push_back(E.key); } return ret; } void TextServerFallback::font_clear_kerning_map(RID p_font_rid, int p_size) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1594,7 +1604,7 @@ void TextServerFallback::font_clear_kerning_map(RID p_font_rid, int p_size) { } void TextServerFallback::font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1605,7 +1615,7 @@ void TextServerFallback::font_remove_kerning(RID p_font_rid, int p_size, const V } void TextServerFallback::font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1616,7 +1626,7 @@ void TextServerFallback::font_set_kerning(RID p_font_rid, int p_size, const Vect } Vector2 TextServerFallback::font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); MutexLock lock(fd->mutex); @@ -1628,7 +1638,7 @@ Vector2 TextServerFallback::font_get_kerning(RID p_font_rid, int p_size, const V if (kern.has(p_glyph_pair)) { if (fd->msdf) { - return kern[p_glyph_pair] * (real_t)p_size / (real_t)fd->msdf_source_size; + return kern[p_glyph_pair] * (float)p_size / (float)fd->msdf_source_size; } else { return kern[p_glyph_pair]; } @@ -1636,9 +1646,11 @@ Vector2 TextServerFallback::font_get_kerning(RID p_font_rid, int p_size, const V #ifdef MODULE_FREETYPE_ENABLED if (fd->cache[size]->face) { FT_Vector delta; - FT_Get_Kerning(fd->cache[size]->face, p_glyph_pair.x, p_glyph_pair.y, FT_KERNING_DEFAULT, &delta); + int32_t glyph_a = FT_Get_Char_Index(fd->cache[size]->face, p_glyph_pair.x); + int32_t glyph_b = FT_Get_Char_Index(fd->cache[size]->face, p_glyph_pair.y); + FT_Get_Kerning(fd->cache[size]->face, glyph_a, glyph_b, FT_KERNING_DEFAULT, &delta); if (fd->msdf) { - return Vector2(delta.x, delta.y) * (real_t)p_size / (real_t)fd->msdf_source_size; + return Vector2(delta.x, delta.y) * (float)p_size / (float)fd->msdf_source_size; } else { return Vector2(delta.x, delta.y); } @@ -1649,30 +1661,11 @@ Vector2 TextServerFallback::font_get_kerning(RID p_font_rid, int p_size, const V } int32_t TextServerFallback::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); - ERR_FAIL_COND_V(!fd, 0); - - MutexLock lock(fd->mutex); - Vector2i size = _get_size(fd, p_size); - ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), 0); - -#ifdef MODULE_FREETYPE_ENABLED - if (fd->cache[size]->face) { - if (p_variation_selector) { - return FT_Face_GetCharVariantIndex(fd->cache[size]->face, p_char, p_variation_selector); - } else { - return FT_Get_Char_Index(fd->cache[size]->face, p_char); - } - } else { - return 0; - } -#else return (int32_t)p_char; -#endif } bool TextServerFallback::font_has_char(RID p_font_rid, char32_t p_char) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1690,7 +1683,7 @@ bool TextServerFallback::font_has_char(RID p_font_rid, char32_t p_char) const { } String TextServerFallback::font_get_supported_chars(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, String()); MutexLock lock(fd->mutex); @@ -1724,25 +1717,19 @@ String TextServerFallback::font_get_supported_chars(RID p_font_rid) const { } void TextServerFallback::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); Vector2i size = _get_size_outline(fd, p_size); ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); for (char32_t i = p_start; i <= p_end; i++) { -#ifdef MODULE_FREETYPE_ENABLED - if (fd->cache[size]->face) { - _ensure_glyph(fd, size, FT_Get_Char_Index(fd->cache[size]->face, i)); - continue; - } -#endif _ensure_glyph(fd, size, (int32_t)i); } } void TextServerFallback::font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1752,7 +1739,7 @@ void TextServerFallback::font_render_glyph(RID p_font_rid, const Vector2i &p_siz } void TextServerFallback::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1777,8 +1764,8 @@ void TextServerFallback::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; - cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size; - Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size; + cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size; + Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, 0, fd->msdf_range); } else { Point2i cpos = p_pos; @@ -1792,7 +1779,7 @@ void TextServerFallback::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_siz } void TextServerFallback::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1817,8 +1804,8 @@ void TextServerFallback::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; - cpos += gl.rect.position * (real_t)p_size / (real_t)fd->msdf_source_size; - Size2 csize = gl.rect.size * (real_t)p_size / (real_t)fd->msdf_source_size; + cpos += gl.rect.position * (float)p_size / (float)fd->msdf_source_size; + Size2 csize = gl.rect.size * (float)p_size / (float)fd->msdf_source_size; RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, p_outline_size * 2, fd->msdf_range); } else { Point2i cpos = p_pos; @@ -1832,7 +1819,7 @@ void TextServerFallback::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, i } bool TextServerFallback::font_is_language_supported(RID p_font_rid, const String &p_language) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1844,7 +1831,7 @@ bool TextServerFallback::font_is_language_supported(RID p_font_rid, const String } void TextServerFallback::font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1852,7 +1839,7 @@ void TextServerFallback::font_set_language_support_override(RID p_font_rid, cons } bool TextServerFallback::font_get_language_support_override(RID p_font_rid, const String &p_language) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1860,7 +1847,7 @@ bool TextServerFallback::font_get_language_support_override(RID p_font_rid, cons } void TextServerFallback::font_remove_language_support_override(RID p_font_rid, const String &p_language) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1868,19 +1855,19 @@ void TextServerFallback::font_remove_language_support_override(RID p_font_rid, c } Vector<String> TextServerFallback::font_get_language_support_overrides(RID p_font_rid) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector<String>()); MutexLock lock(fd->mutex); Vector<String> out; - for (const Map<String, bool>::Element *E = fd->language_support_overrides.front(); E; E = E->next()) { - out.push_back(E->key()); + for (const KeyValue<String, bool> &E : fd->language_support_overrides) { + out.push_back(E.key); } return out; } bool TextServerFallback::font_is_script_supported(RID p_font_rid, const String &p_script) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1892,7 +1879,7 @@ bool TextServerFallback::font_is_script_supported(RID p_font_rid, const String & } void TextServerFallback::font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1900,7 +1887,7 @@ void TextServerFallback::font_set_script_support_override(RID p_font_rid, const } bool TextServerFallback::font_get_script_support_override(RID p_font_rid, const String &p_script) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, false); MutexLock lock(fd->mutex); @@ -1908,7 +1895,7 @@ bool TextServerFallback::font_get_script_support_override(RID p_font_rid, const } void TextServerFallback::font_remove_script_support_override(RID p_font_rid, const String &p_script) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); MutexLock lock(fd->mutex); @@ -1918,13 +1905,13 @@ void TextServerFallback::font_remove_script_support_override(RID p_font_rid, con } Vector<String> TextServerFallback::font_get_script_support_overrides(RID p_font_rid) { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector<String>()); MutexLock lock(fd->mutex); Vector<String> out; - for (const Map<String, bool>::Element *E = fd->script_support_overrides.front(); E; E = E->next()) { - out.push_back(E->key()); + for (const KeyValue<String, bool> &E : fd->script_support_overrides) { + out.push_back(E.key); } return out; } @@ -1934,7 +1921,7 @@ Dictionary TextServerFallback::font_supported_feature_list(RID p_font_rid) const } Dictionary TextServerFallback::font_supported_variation_list(RID p_font_rid) const { - FontDataFallback *fd = font_owner.getornull(p_font_rid); + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); MutexLock lock(fd->mutex); @@ -1943,11 +1930,11 @@ Dictionary TextServerFallback::font_supported_variation_list(RID p_font_rid) con return fd->supported_varaitions; } -real_t TextServerFallback::font_get_global_oversampling() const { +float TextServerFallback::font_get_global_oversampling() const { return oversampling; } -void TextServerFallback::font_set_global_oversampling(real_t p_oversampling) { +void TextServerFallback::font_set_global_oversampling(float p_oversampling) { _THREAD_SAFE_METHOD_ if (oversampling != p_oversampling) { oversampling = p_oversampling; @@ -1965,7 +1952,7 @@ void TextServerFallback::font_set_global_oversampling(real_t p_oversampling) { List<RID> text_bufs; shaped_owner.get_owned_list(&text_bufs); for (const RID &E : text_bufs) { - invalidate(shaped_owner.getornull(E)); + invalidate(shaped_owner.get_or_null(E)); } } } @@ -1990,11 +1977,11 @@ void TextServerFallback::invalidate(ShapedTextData *p_shaped) { } void TextServerFallback::full_copy(ShapedTextData *p_shaped) { - ShapedTextData *parent = shaped_owner.getornull(p_shaped->parent); + ShapedTextData *parent = shaped_owner.get_or_null(p_shaped->parent); - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = parent->objects.front(); E; E = E->next()) { - if (E->get().pos >= p_shaped->start && E->get().pos < p_shaped->end) { - p_shaped->objects[E->key()] = E->get(); + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : parent->objects) { + if (E.value.pos >= p_shaped->start && E.value.pos < p_shaped->end) { + p_shaped->objects[E.key] = E.value; } } @@ -2021,7 +2008,7 @@ RID TextServerFallback::create_shaped_text(TextServer::Direction p_direction, Te } void TextServerFallback::shaped_text_clear(RID p_shaped) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2045,7 +2032,7 @@ TextServer::Direction TextServerFallback::shaped_text_get_direction(RID p_shaped } void TextServerFallback::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2058,12 +2045,12 @@ void TextServerFallback::shaped_text_set_orientation(RID p_shaped, TextServer::O } } -void TextServerFallback::shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) { +void TextServerFallback::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) { // No BiDi support, ignore. } TextServer::Orientation TextServerFallback::shaped_text_get_orientation(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, TextServer::ORIENTATION_HORIZONTAL); MutexLock lock(sd->mutex); @@ -2071,7 +2058,7 @@ TextServer::Orientation TextServerFallback::shaped_text_get_orientation(RID p_sh } void TextServerFallback::shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); MutexLock lock(sd->mutex); ERR_FAIL_COND(!sd); @@ -2085,7 +2072,7 @@ void TextServerFallback::shaped_text_set_preserve_invalid(RID p_shaped, bool p_e } bool TextServerFallback::shaped_text_get_preserve_invalid(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2093,7 +2080,7 @@ bool TextServerFallback::shaped_text_get_preserve_invalid(RID p_shaped) const { } void TextServerFallback::shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -2107,7 +2094,7 @@ void TextServerFallback::shaped_text_set_preserve_control(RID p_shaped, bool p_e } bool TextServerFallback::shaped_text_get_preserve_control(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2115,14 +2102,14 @@ bool TextServerFallback::shaped_text_get_preserve_control(RID p_shaped) const { } bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); ERR_FAIL_COND_V(p_size <= 0, false); for (int i = 0; i < p_fonts.size(); i++) { - ERR_FAIL_COND_V(!font_owner.getornull(p_fonts[i]), false); + ERR_FAIL_COND_V(!font_owner.get_or_null(p_fonts[i]), false); } if (p_text.is_empty()) { @@ -2162,7 +2149,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te } bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2193,7 +2180,7 @@ bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, con } bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2213,9 +2200,9 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, Glyph gl = sd->glyphs[i]; Variant key; if (gl.count == 1) { - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - if (E->get().pos == gl.start) { - key = E->key(); + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + if (E.value.pos == gl.start) { + key = E.key; break; } } @@ -2244,8 +2231,7 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, } else if (sd->preserve_invalid || (sd->preserve_control && is_control(gl.index))) { // Glyph not found, replace with hex code box. if (sd->orientation == ORIENTATION_HORIZONTAL) { - sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f)); - sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f)); + sd->ascent = MAX(sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y); } else { sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); @@ -2256,66 +2242,66 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, } // Align embedded objects to baseline. - real_t full_ascent = sd->ascent; - real_t full_descent = sd->descent; - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - if ((E->get().pos >= sd->start) && (E->get().pos < sd->end)) { + float full_ascent = sd->ascent; + float full_descent = sd->descent; + for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.y = -sd->ascent; + E.value.rect.position.y = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.y = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.y = 0; + E.value.rect.position.y = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.y = sd->descent; + E.value.rect.position.y = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.y -= E->get().rect.size.y; + E.value.rect.position.y -= E.value.rect.size.y; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.y -= E->get().rect.size.y / 2; + E.value.rect.position.y -= E.value.rect.size.y / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.y); - full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y); + full_ascent = MAX(full_ascent, -E.value.rect.position.y); + full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.x = -sd->ascent; + E.value.rect.position.x = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.x = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.x = 0; + E.value.rect.position.x = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.x = sd->descent; + E.value.rect.position.x = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.x -= E->get().rect.size.x; + E.value.rect.position.x -= E.value.rect.size.x; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.x -= E->get().rect.size.x / 2; + E.value.rect.position.x -= E.value.rect.size.x / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.x); - full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x); + full_ascent = MAX(full_ascent, -E.value.rect.position.x); + full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x); } } } @@ -2326,7 +2312,7 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, } RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_length) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, RID()); MutexLock lock(sd->mutex); @@ -2365,11 +2351,11 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng Variant key; bool find_embedded = false; if (gl.count == 1) { - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - if (E->get().pos == gl.start) { + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + if (E.value.pos == gl.start) { find_embedded = true; - key = E->key(); - new_sd->objects[key] = E->get(); + key = E.key; + new_sd->objects[key] = E.value; break; } } @@ -2394,8 +2380,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng } else if (new_sd->preserve_invalid || (new_sd->preserve_control && is_control(gl.index))) { // Glyph not found, replace with hex code box. if (new_sd->orientation == ORIENTATION_HORIZONTAL) { - new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f)); - new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f)); + new_sd->ascent = MAX(new_sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y); } else { new_sd->ascent = MAX(new_sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); new_sd->descent = MAX(new_sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); @@ -2408,66 +2393,66 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng } // Align embedded objects to baseline. - real_t full_ascent = new_sd->ascent; - real_t full_descent = new_sd->descent; - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = new_sd->objects.front(); E; E = E->next()) { - if ((E->get().pos >= new_sd->start) && (E->get().pos < new_sd->end)) { + float full_ascent = new_sd->ascent; + float full_descent = new_sd->descent; + for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) { + if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.y = -new_sd->ascent; + E.value.rect.position.y = -new_sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.y = (-new_sd->ascent + new_sd->descent) / 2; + E.value.rect.position.y = (-new_sd->ascent + new_sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.y = 0; + E.value.rect.position.y = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.y = new_sd->descent; + E.value.rect.position.y = new_sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.y -= E->get().rect.size.y; + E.value.rect.position.y -= E.value.rect.size.y; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.y -= E->get().rect.size.y / 2; + E.value.rect.position.y -= E.value.rect.size.y / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.y); - full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y); + full_ascent = MAX(full_ascent, -E.value.rect.position.y); + full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.x = -new_sd->ascent; + E.value.rect.position.x = -new_sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.x = (-new_sd->ascent + new_sd->descent) / 2; + E.value.rect.position.x = (-new_sd->ascent + new_sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.x = 0; + E.value.rect.position.x = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.x = new_sd->descent; + E.value.rect.position.x = new_sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.x -= E->get().rect.size.x; + E.value.rect.position.x -= E.value.rect.size.x; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.x -= E->get().rect.size.x / 2; + E.value.rect.position.x -= E.value.rect.size.x / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.x); - full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x); + full_ascent = MAX(full_ascent, -E.value.rect.position.x); + full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x); } } } @@ -2480,15 +2465,15 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng } RID TextServerFallback::shaped_text_get_parent(RID p_shaped) const { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, RID()); MutexLock lock(sd->mutex); return sd->parent; } -real_t TextServerFallback::shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); +float TextServerFallback::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags) { + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -2551,12 +2536,12 @@ real_t TextServerFallback::shaped_text_fit_to_width(RID p_shaped, real_t p_width } if ((space_count > 0) && ((p_jst_flags & JUSTIFICATION_WORD_BOUND) == JUSTIFICATION_WORD_BOUND)) { - real_t delta_width_per_space = (p_width - sd->width) / space_count; + float delta_width_per_space = (p_width - sd->width) / space_count; for (int i = start_pos; i <= end_pos; i++) { Glyph &gl = sd->glyphs.write[i]; if (gl.count > 0) { if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) { - real_t old_adv = gl.advance; + float old_adv = gl.advance; gl.advance = MAX(gl.advance + delta_width_per_space, Math::round(0.1 * gl.font_size)); sd->width += (gl.advance - old_adv); } @@ -2567,8 +2552,8 @@ real_t TextServerFallback::shaped_text_fit_to_width(RID p_shaped, real_t p_width return sd->width; } -real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); +float TextServerFallback::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) { + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -2580,7 +2565,7 @@ real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real } int tab_index = 0; - real_t off = 0.f; + float off = 0.f; int start, end, delta; if (sd->para_direction == DIRECTION_LTR) { @@ -2597,7 +2582,7 @@ real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real for (int i = start; i != end; i += delta) { if ((gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB) { - real_t tab_off = 0.f; + float tab_off = 0.f; while (tab_off <= off) { tab_off += p_tab_stops[tab_index]; tab_index++; @@ -2605,7 +2590,7 @@ real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real tab_index = 0; } } - real_t old_adv = gl[i].advance; + float old_adv = gl[i].advance; gl[i].advance = tab_off - off; sd->width += gl[i].advance - old_adv; off = 0; @@ -2618,7 +2603,7 @@ real_t TextServerFallback::shaped_text_tab_align(RID p_shaped, const Vector<real } bool TextServerFallback::shaped_text_update_breaks(RID p_shaped) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2659,7 +2644,7 @@ bool TextServerFallback::shaped_text_update_breaks(RID p_shaped) { } bool TextServerFallback::shaped_text_update_justification_ops(RID p_shaped) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2674,8 +2659,8 @@ bool TextServerFallback::shaped_text_update_justification_ops(RID p_shaped) { return true; } -void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, real_t p_width, uint8_t p_trim_flags) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped_line); +void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) { + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped_line); ERR_FAIL_COND_MSG(!sd, "ShapedTextDataFallback invalid."); MutexLock lock(sd->mutex); @@ -2717,7 +2702,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re } int ell_min_characters = 6; - real_t width = sd->width; + float width = sd->width; int trim_pos = 0; int ellipsis_pos = (enforce_ellipsis) ? 0 : -1; @@ -2763,7 +2748,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re if (add_ellipsis && (ellipsis_pos > 0 || enforce_ellipsis)) { // Insert an additional space when cutting word bound for aesthetics. if (cut_per_word && (ellipsis_pos > 0)) { - TextServer::Glyph gl; + Glyph gl; gl.count = 1; gl.advance = whitespace_adv.x; gl.index = whitespace_gl_idx; @@ -2774,7 +2759,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re sd->overrun_trim_data.ellipsis_glyph_buf.append(gl); } // Add ellipsis dots. - TextServer::Glyph gl; + Glyph gl; gl.count = 1; gl.repeat = 3; gl.advance = dot_adv.x; @@ -2791,16 +2776,40 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, re } } -TextServer::TrimData TextServerFallback::shaped_text_get_trim_data(RID p_shaped) const { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V_MSG(!sd, TrimData(), "ShapedTextDataFallback invalid."); +int TextServerFallback::shaped_text_get_trim_pos(RID p_shaped) const { + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextData invalid."); + + MutexLock lock(sd->mutex); + return sd->overrun_trim_data.trim_pos; +} + +int TextServerFallback::shaped_text_get_ellipsis_pos(RID p_shaped) const { + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextData invalid."); + + MutexLock lock(sd->mutex); + return sd->overrun_trim_data.ellipsis_pos; +} + +const Glyph *TextServerFallback::shaped_text_get_ellipsis_glyphs(RID p_shaped) const { + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextData invalid."); + + MutexLock lock(sd->mutex); + return sd->overrun_trim_data.ellipsis_glyph_buf.ptr(); +} + +int TextServerFallback::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const { + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextData invalid."); MutexLock lock(sd->mutex); - return sd->overrun_trim_data; + return sd->overrun_trim_data.ellipsis_glyph_buf.size(); } bool TextServerFallback::shaped_text_shape(RID p_shaped) { - ShapedTextData *sd = shaped_owner.getornull(p_shaped); + ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); @@ -2911,8 +2920,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { // Glyph not found, replace with hex code box. if (sd->orientation == ORIENTATION_HORIZONTAL) { gl.advance = get_hex_code_box_size(gl.font_size, gl.index).x; - sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.75f)); - sd->descent = MAX(sd->descent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).y * 0.25f)); + sd->ascent = MAX(sd->ascent, get_hex_code_box_size(gl.font_size, gl.index).y); } else { gl.advance = get_hex_code_box_size(gl.font_size, gl.index).y; sd->ascent = MAX(sd->ascent, Math::round(get_hex_code_box_size(gl.font_size, gl.index).x * 0.5f)); @@ -2926,65 +2934,65 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { } // Align embedded objects to baseline. - real_t full_ascent = sd->ascent; - real_t full_descent = sd->descent; - for (Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { + float full_ascent = sd->ascent; + float full_descent = sd->descent; + for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { if (sd->orientation == ORIENTATION_HORIZONTAL) { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.y = -sd->ascent; + E.value.rect.position.y = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.y = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.y = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.y = 0; + E.value.rect.position.y = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.y = sd->descent; + E.value.rect.position.y = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.y -= E->get().rect.size.y; + E.value.rect.position.y -= E.value.rect.size.y; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.y -= E->get().rect.size.y / 2; + E.value.rect.position.y -= E.value.rect.size.y / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.y); - full_descent = MAX(full_descent, E->get().rect.position.y + E->get().rect.size.y); + full_ascent = MAX(full_ascent, -E.value.rect.position.y); + full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y); } else { - switch (E->get().inline_align & INLINE_ALIGN_TEXT_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_TEXT_MASK) { case INLINE_ALIGN_TO_TOP: { - E->get().rect.position.x = -sd->ascent; + E.value.rect.position.x = -sd->ascent; } break; case INLINE_ALIGN_TO_CENTER: { - E->get().rect.position.x = (-sd->ascent + sd->descent) / 2; + E.value.rect.position.x = (-sd->ascent + sd->descent) / 2; } break; case INLINE_ALIGN_TO_BASELINE: { - E->get().rect.position.x = 0; + E.value.rect.position.x = 0; } break; case INLINE_ALIGN_TO_BOTTOM: { - E->get().rect.position.x = sd->descent; + E.value.rect.position.x = sd->descent; } break; } - switch (E->get().inline_align & INLINE_ALIGN_IMAGE_MASK) { + switch (E.value.inline_align & INLINE_ALIGN_IMAGE_MASK) { case INLINE_ALIGN_BOTTOM_TO: { - E->get().rect.position.x -= E->get().rect.size.x; + E.value.rect.position.x -= E.value.rect.size.x; } break; case INLINE_ALIGN_CENTER_TO: { - E->get().rect.position.x -= E->get().rect.size.x / 2; + E.value.rect.position.x -= E.value.rect.size.x / 2; } break; case INLINE_ALIGN_TOP_TO: { //NOP } break; } - full_ascent = MAX(full_ascent, -E->get().rect.position.x); - full_descent = MAX(full_descent, E->get().rect.position.x + E->get().rect.size.x); + full_ascent = MAX(full_ascent, -E.value.rect.position.x); + full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x); } } sd->ascent = full_ascent; @@ -2994,59 +3002,70 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) { } bool TextServerFallback::shaped_text_is_ready(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, false); MutexLock lock(sd->mutex); return sd->valid; } -Vector<TextServer::Glyph> TextServerFallback::shaped_text_get_glyphs(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>()); +const Glyph *TextServerFallback::shaped_text_get_glyphs(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, nullptr); MutexLock lock(sd->mutex); if (!sd->valid) { const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped); } - return sd->glyphs; + return sd->glyphs.ptr(); } -Vector2i TextServerFallback::shaped_text_get_range(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V(!sd, Vector2i()); +int TextServerFallback::shaped_text_get_glyph_count(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, 0); MutexLock lock(sd->mutex); - return Vector2(sd->start, sd->end); + if (!sd->valid) { + const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped); + } + return sd->glyphs.size(); } -Vector<TextServer::Glyph> TextServerFallback::shaped_text_sort_logical(RID p_shaped) { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); - ERR_FAIL_COND_V(!sd, Vector<TextServer::Glyph>()); +const Glyph *TextServerFallback::shaped_text_sort_logical(RID p_shaped) { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, nullptr); MutexLock lock(sd->mutex); if (!sd->valid) { const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped); } - return sd->glyphs; // Already in the logical order, return as is. + return sd->glyphs.ptr(); // Already in the logical order, return as is. +} + +Vector2i TextServerFallback::shaped_text_get_range(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_V(!sd, Vector2i()); + + MutexLock lock(sd->mutex); + return Vector2(sd->start, sd->end); } Array TextServerFallback::shaped_text_get_objects(RID p_shaped) const { Array ret; - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, ret); MutexLock lock(sd->mutex); - for (const Map<Variant, ShapedTextData::EmbeddedObject>::Element *E = sd->objects.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) { + ret.push_back(E.key); } return ret; } Rect2 TextServerFallback::shaped_text_get_object_rect(RID p_shaped, Variant p_key) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, Rect2()); MutexLock lock(sd->mutex); @@ -3058,7 +3077,7 @@ Rect2 TextServerFallback::shaped_text_get_object_rect(RID p_shaped, Variant p_ke } Size2 TextServerFallback::shaped_text_get_size(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, Size2()); MutexLock lock(sd->mutex); @@ -3072,8 +3091,8 @@ Size2 TextServerFallback::shaped_text_get_size(RID p_shaped) const { } } -real_t TextServerFallback::shaped_text_get_ascent(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); +float TextServerFallback::shaped_text_get_ascent(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -3083,8 +3102,8 @@ real_t TextServerFallback::shaped_text_get_ascent(RID p_shaped) const { return sd->ascent; } -real_t TextServerFallback::shaped_text_get_descent(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); +float TextServerFallback::shaped_text_get_descent(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -3094,8 +3113,8 @@ real_t TextServerFallback::shaped_text_get_descent(RID p_shaped) const { return sd->descent; } -real_t TextServerFallback::shaped_text_get_width(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); +float TextServerFallback::shaped_text_get_width(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -3105,8 +3124,8 @@ real_t TextServerFallback::shaped_text_get_width(RID p_shaped) const { return sd->width; } -real_t TextServerFallback::shaped_text_get_underline_position(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); +float TextServerFallback::shaped_text_get_underline_position(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -3117,8 +3136,8 @@ real_t TextServerFallback::shaped_text_get_underline_position(RID p_shaped) cons return sd->upos; } -real_t TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) const { - const ShapedTextData *sd = shaped_owner.getornull(p_shaped); +float TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) const { + const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped); ERR_FAIL_COND_V(!sd, 0.f); MutexLock lock(sd->mutex); @@ -3129,15 +3148,6 @@ real_t TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) con return sd->uthk; } -TextServer *TextServerFallback::create_func(Error &r_error, void *p_user_data) { - r_error = OK; - return memnew(TextServerFallback()); -} - -void TextServerFallback::register_server() { - TextServerManager::register_create_function(interface_name, interface_features, create_func, nullptr); -} - TextServerFallback::TextServerFallback(){}; TextServerFallback::~TextServerFallback() { diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index fde75e7135..992ce5018f 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -93,12 +93,12 @@ class TextServerFallback : public TextServer { }; struct FontDataForSizeFallback { - real_t ascent = 0.f; - real_t descent = 0.f; - real_t underline_position = 0.f; - real_t underline_thickness = 0.f; - real_t scale = 1.f; - real_t oversampling = 1.f; + float ascent = 0.f; + float descent = 0.f; + float underline_position = 0.f; + float underline_thickness = 0.f; + float scale = 1.f; + float oversampling = 1.f; int spacing_glyph = 0; int spacing_space = 0; @@ -134,7 +134,7 @@ class TextServerFallback : public TextServer { bool force_autohinter = false; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; Dictionary variation_coordinates; - real_t oversampling = 0.f; + float oversampling = 0.f; Map<Vector2i, FontDataForSizeFallback *> cache; @@ -194,7 +194,7 @@ class TextServerFallback : public TextServer { // Common data. - real_t oversampling = 1.f; + float oversampling = 1.f; mutable RID_PtrOwner<FontDataFallback> font_owner; mutable RID_PtrOwner<ShapedTextData> shaped_owner; @@ -205,20 +205,19 @@ protected: void invalidate(ShapedTextData *p_shaped); public: - virtual bool has_feature(Feature p_feature) override; + virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; + virtual uint32_t get_features() const override; virtual void free(RID p_rid) override; virtual bool has(RID p_rid) override; virtual bool load_support_data(const String &p_filename) override; -#ifdef TOOLS_ENABLED - virtual String get_support_data_filename() override { return ""; }; - virtual String get_support_data_info() override { return "Not supported"; }; - virtual bool save_support_data(const String &p_filename) override; -#endif + virtual String get_support_data_filename() const override { return ""; }; + virtual String get_support_data_info() const override { return "Not supported"; }; + virtual bool save_support_data(const String &p_filename) const override; - virtual bool is_locale_right_to_left(const String &p_locale) override; + virtual bool is_locale_right_to_left(const String &p_locale) const override; virtual int32_t name_to_tag(const String &p_name) const override; virtual String tag_to_name(int32_t p_tag) const override; @@ -253,27 +252,27 @@ public: virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; - virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) override; - virtual real_t font_get_oversampling(RID p_font_rid) const override; + virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override; + virtual float font_get_oversampling(RID p_font_rid) const override; virtual Array font_get_size_cache_list(RID p_font_rid) const override; virtual void font_clear_size_cache(RID p_font_rid) override; virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override; - virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) override; - virtual real_t font_get_ascent(RID p_font_rid, int p_size) const override; + virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override; + virtual float font_get_ascent(RID p_font_rid, int p_size) const override; - virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) override; - virtual real_t font_get_descent(RID p_font_rid, int p_size) const override; + virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override; + virtual float font_get_descent(RID p_font_rid, int p_size) const override; - virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) override; - virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const override; + virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override; + virtual float font_get_underline_position(RID p_font_rid, int p_size) const override; - virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) override; - virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const override; + virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override; + virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override; - virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) override; - virtual real_t font_get_scale(RID p_font_rid, int p_size) const override; + virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override; + virtual float font_get_scale(RID p_font_rid, int p_size) const override; virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override; virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override; @@ -307,7 +306,7 @@ public: virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override; - virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override; + virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override; virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override; virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override; @@ -342,8 +341,8 @@ public: virtual Dictionary font_supported_feature_list(RID p_font_rid) const override; virtual Dictionary font_supported_variation_list(RID p_font_rid) const override; - virtual real_t font_get_global_oversampling() const override; - virtual void font_set_global_oversampling(real_t p_oversampling) override; + virtual float font_get_global_oversampling() const override; + virtual void font_set_global_oversampling(float p_oversampling) override; /* Shaped text buffer interface */ @@ -354,7 +353,7 @@ public: virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; virtual Direction shaped_text_get_direction(RID p_shaped) const override; - virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) override; + virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; virtual Orientation shaped_text_get_orientation(RID p_shaped) const override; @@ -372,36 +371,37 @@ public: virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override; virtual RID shaped_text_get_parent(RID p_shaped) const override; - virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; - virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) override; + virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; + virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override; virtual bool shaped_text_shape(RID p_shaped) override; virtual bool shaped_text_update_breaks(RID p_shaped) override; virtual bool shaped_text_update_justification_ops(RID p_shaped) override; - virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) override; - virtual TrimData shaped_text_get_trim_data(RID p_shaped) const override; + virtual int shaped_text_get_trim_pos(RID p_shaped) const override; + virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override; + virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override; + virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override; + + virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override; virtual bool shaped_text_is_ready(RID p_shaped) const override; - virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const override; + virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override; + virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override; + virtual int shaped_text_get_glyph_count(RID p_shaped) const override; virtual Vector2i shaped_text_get_range(RID p_shaped) const override; - virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) override; - virtual Array shaped_text_get_objects(RID p_shaped) const override; virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override; virtual Size2 shaped_text_get_size(RID p_shaped) const override; - virtual real_t shaped_text_get_ascent(RID p_shaped) const override; - virtual real_t shaped_text_get_descent(RID p_shaped) const override; - virtual real_t shaped_text_get_width(RID p_shaped) const override; - virtual real_t shaped_text_get_underline_position(RID p_shaped) const override; - virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const override; - - static TextServer *create_func(Error &r_error, void *p_user_data); - static void register_server(); + virtual float shaped_text_get_ascent(RID p_shaped) const override; + virtual float shaped_text_get_descent(RID p_shaped) const override; + virtual float shaped_text_get_width(RID p_shaped) const override; + virtual float shaped_text_get_underline_position(RID p_shaped) const override; + virtual float shaped_text_get_underline_thickness(RID p_shaped) const override; TextServerFallback(); ~TextServerFallback(); diff --git a/modules/upnp/doc_classes/UPNP.xml b/modules/upnp/doc_classes/UPNP.xml index 5b1d9dbfd1..2cd0b8843a 100644 --- a/modules/upnp/doc_classes/UPNP.xml +++ b/modules/upnp/doc_classes/UPNP.xml @@ -16,6 +16,38 @@ [codeblock] upnp.delete_port_mapping(port) [/codeblock] + [b]Note:[/b] UPnP discovery blocks the current thread. To perform discovery without blocking the main thread, use [Thread]s like this: + [codeblock] + # Emitted when UPnP port mapping setup is completed (regardless of success or failure). + signal upnp_completed(error) + + # Replace this with your own server port number between 1025 and 65535. + const SERVER_PORT = 3928 + var thread = null + + func _upnp_setup(server_port): + # UPNP queries take some time. + var upnp = UPNP.new() + var err = upnp.discover() + + if err != OK: + push_error(str(err)) + emit_signal("upnp_completed", err) + return + + if upnp.get_gateway() and upnp.get_gateway().is_valid_gateway(): + upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "UDP") + upnp.add_port_mapping(server_port, server_port, ProjectSettings.get_setting("application/config/name"), "TCP") + emit_signal("upnp_completed", OK) + + func _ready(): + thread = Thread.new() + thread.start(self, "_upnp_setup", SERVER_PORT) + + func _exit_tree(): + # Wait for thread finish here to handle game exit while the thread is running. + thread.wait_to_finish() + [/codeblock] </description> <tutorials> </tutorials> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 4d5f3420b8..54d310e636 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -702,8 +702,8 @@ void VisualScript::rename_custom_signal(const StringName &p_name, const StringNa } void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) const { - for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) { - r_custom_signals->push_back(E->key()); + for (const KeyValue<StringName, Vector<Argument>> &E : custom_signals) { + r_custom_signals->push_back(E.key); } r_custom_signals->sort_custom<StringName::AlphCompare>(); @@ -848,13 +848,13 @@ bool VisualScript::has_script_signal(const StringName &p_signal) const { } void VisualScript::get_script_signal_list(List<MethodInfo> *r_signals) const { - for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) { + for (const KeyValue<StringName, Vector<Argument>> &E : custom_signals) { MethodInfo mi; - mi.name = E->key(); - for (int i = 0; i < E->get().size(); i++) { + mi.name = E.key; + for (int i = 0; i < E.value.size(); i++) { PropertyInfo arg; - arg.type = E->get()[i].type; - arg.name = E->get()[i].name; + arg.type = E.value[i].type; + arg.name = E.value[i].name; mi.arguments.push_back(arg); } @@ -1056,13 +1056,13 @@ Dictionary VisualScript::_get_data() const { d["variables"] = vars; Array sigs; - for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) { + for (const KeyValue<StringName, Vector<Argument>> &E : custom_signals) { Dictionary cs; - cs["name"] = E->key(); + cs["name"] = E.key; Array args; - for (int i = 0; i < E->get().size(); i++) { - args.push_back(E->get()[i].name); - args.push_back(E->get()[i].type); + for (int i = 0; i < E.value.size(); i++) { + args.push_back(E.value[i].name); + args.push_back(E.value[i].type); } cs["arguments"] = args; @@ -2093,8 +2093,8 @@ VisualScriptInstance::~VisualScriptInstance() { script->instances.erase(owner); } - for (Map<int, VisualScriptNodeInstance *>::Element *E = instances.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<int, VisualScriptNodeInstance *> &E : instances) { + memdelete(E.value); } } @@ -2516,8 +2516,8 @@ Ref<VisualScriptNode> VisualScriptLanguage::create_node_from_name(const String & } void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) { - for (Map<String, VisualScriptNodeRegisterFunc>::Element *E = register_funcs.front(); E; E = E->next()) { - r_names->push_back(E->key()); + for (const KeyValue<String, VisualScriptNodeRegisterFunc> &E : register_funcs) { + r_names->push_back(E.key); } } diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 0a6bcedf31..8cb701ea20 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -3632,17 +3632,17 @@ void VisualScriptEditor::_notification(int p_what) { node_colors["constants"] = Color(0.94, 0.18, 0.49); } - for (Map<StringName, Color>::Element *E = node_colors.front(); E; E = E->next()) { + for (const KeyValue<StringName, Color> &E : node_colors) { const Ref<StyleBoxFlat> sb = tm->get_stylebox(SNAME("frame"), SNAME("GraphNode")); if (!sb.is_null()) { Ref<StyleBoxFlat> frame_style = sb->duplicate(); // Adjust the border color to be close to the GraphNode's background color. // This keeps the node's title area from being too distracting. - Color color = dark_theme ? E->get().darkened(0.75) : E->get().lightened(0.75); + Color color = dark_theme ? E.value.darkened(0.75) : E.value.lightened(0.75); color.a = 0.9; frame_style->set_border_color(color); - node_styles[E->key()] = frame_style; + node_styles[E.key] = frame_style; } } @@ -3813,15 +3813,15 @@ void VisualScriptEditor::_menu_option(int p_what) { } } - for (Map<int, Ref<VisualScriptNode>>::Element *E = clipboard->nodes.front(); E; E = E->next()) { - Ref<VisualScriptNode> node = E->get()->duplicate(); + for (KeyValue<int, Ref<VisualScriptNode>> &E : clipboard->nodes) { + Ref<VisualScriptNode> node = E.value->duplicate(); int new_id = idc++; to_select.insert(new_id); - remap[E->key()] = new_id; + remap[E.key] = new_id; - Vector2 paste_pos = clipboard->nodes_positions[E->key()]; + Vector2 paste_pos = clipboard->nodes_positions[E.key]; while (existing_positions.has(paste_pos.snapped(Vector2(2, 2)))) { paste_pos += Vector2(20, 20) * EDSCALE; @@ -3906,16 +3906,16 @@ void VisualScriptEditor::_menu_option(int p_what) { // the user wants to connect the nodes. int top_nd = -1; Vector2 top; - for (Map<int, Ref<VisualScriptNode>>::Element *E = nodes.front(); E; E = E->next()) { - Ref<VisualScriptNode> nd = script->get_node(E->key()); + for (const KeyValue<int, Ref<VisualScriptNode>> &E : nodes) { + Ref<VisualScriptNode> nd = script->get_node(E.key); if (nd.is_valid() && nd->has_input_sequence_port()) { if (top_nd < 0) { - top_nd = E->key(); + top_nd = E.key; top = script->get_node_position(top_nd); } - Vector2 pos = script->get_node_position(E->key()); + Vector2 pos = script->get_node_position(E.key); if (top.y > pos.y) { - top_nd = E->key(); + top_nd = E.key; top = pos; } } diff --git a/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml b/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml index 26a4391b83..746fabd6e5 100644 --- a/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml +++ b/modules/webrtc/doc_classes/WebRTCDataChannelExtension.xml @@ -49,7 +49,7 @@ </method> <method name="_get_packet" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="r_buffer" type="const void*" /> + <argument index="0" name="r_buffer" type="const uint8_t **" /> <argument index="1" name="r_buffer_size" type="int32_t*" /> <description> </description> @@ -86,7 +86,7 @@ </method> <method name="_put_packet" qualifiers="virtual"> <return type="int" /> - <argument index="0" name="p_buffer" type="const void*" /> + <argument index="0" name="p_buffer" type="const uint8_t*" /> <argument index="1" name="p_buffer_size" type="int" /> <description> </description> diff --git a/modules/webrtc/webrtc_multiplayer_peer.cpp b/modules/webrtc/webrtc_multiplayer_peer.cpp index 48117f05f2..133bd71ddb 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.cpp +++ b/modules/webrtc/webrtc_multiplayer_peer.cpp @@ -63,8 +63,8 @@ void WebRTCMultiplayerPeer::poll() { List<int> remove; List<int> add; - for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) { - Ref<ConnectedPeer> peer = E->get(); + for (KeyValue<int, Ref<ConnectedPeer>> &E : peer_map) { + Ref<ConnectedPeer> peer = E.value; peer->connection->poll(); // Check peer state switch (peer->connection->get_connection_state()) { @@ -77,7 +77,7 @@ void WebRTCMultiplayerPeer::poll() { break; default: // Peer is closed or in error state. Got to next peer. - remove.push_back(E->key()); + remove.push_back(E.key); continue; } // Check channels state @@ -92,7 +92,7 @@ void WebRTCMultiplayerPeer::poll() { continue; default: // Channel was closed or in error state, remove peer id. - remove.push_back(E->key()); + remove.push_back(E.key); } // We got a closed channel break out, the peer will be removed. break; @@ -100,7 +100,7 @@ void WebRTCMultiplayerPeer::poll() { // This peer has newly connected, and all channels are now open. if (ready == peer->channels.size() && !peer->connected) { peer->connected = true; - add.push_back(E->key()); + add.push_back(E.key); } } // Remove disconnected peers @@ -125,9 +125,9 @@ void WebRTCMultiplayerPeer::poll() { emit_signal(SNAME("peer_connected"), TARGET_PEER_SERVER); emit_signal(SNAME("connection_succeeded")); // Notify of all previously connected peers - for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) { - if (F->key() != 1 && F->get()->connected) { - emit_signal(SNAME("peer_connected"), F->key()); + for (const KeyValue<int, Ref<ConnectedPeer>> &F : peer_map) { + if (F.key != 1 && F.value->connected) { + emit_signal(SNAME("peer_connected"), F.key); } } break; // Because we already notified of all newly added peers. @@ -189,7 +189,7 @@ Error WebRTCMultiplayerPeer::initialize(int p_self_id, bool p_server_compat, Arr cfg["ordered"] = true; switch (mode) { - case Multiplayer::TRANSFER_MODE_ORDERED: + case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: cfg["maxPacketLifetime"] = 1; break; case Multiplayer::TRANSFER_MODE_UNRELIABLE: @@ -244,10 +244,10 @@ Dictionary WebRTCMultiplayerPeer::get_peer(int p_peer_id) { Dictionary WebRTCMultiplayerPeer::get_peers() { Dictionary out; - for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) { + for (const KeyValue<int, Ref<ConnectedPeer>> &E : peer_map) { Dictionary d; - _peer_to_dict(E->get(), d); - out[E->key()] = d; + _peer_to_dict(E.value, d); + out[E.key] = d; } return out; } @@ -334,7 +334,7 @@ Error WebRTCMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_si case Multiplayer::TRANSFER_MODE_RELIABLE: ch = CH_RELIABLE; break; - case Multiplayer::TRANSFER_MODE_ORDERED: + case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: ch = CH_ORDERED; break; case Multiplayer::TRANSFER_MODE_UNRELIABLE: @@ -358,15 +358,15 @@ Error WebRTCMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_si } else { int exclude = -target_peer; - for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) { + for (KeyValue<int, Ref<ConnectedPeer>> &F : peer_map) { // Exclude packet. If target_peer == 0 then don't exclude any packets - if (target_peer != 0 && F->key() == exclude) { + if (target_peer != 0 && F.key == exclude) { continue; } - ERR_CONTINUE_MSG(F->value()->channels.size() <= ch, vformat("Unable to send packet on channel %d, max channels: %d", ch, E->value()->channels.size())); - ERR_CONTINUE(F->value()->channels[ch].is_null()); - F->value()->channels[ch]->put_packet(p_buffer, p_buffer_size); + ERR_CONTINUE_MSG(F.value->channels.size() <= ch, vformat("Unable to send packet on channel %d, max channels: %d", ch, E->value()->channels.size())); + ERR_CONTINUE(F.value->channels[ch].is_null()); + F.value->channels[ch]->put_packet(p_buffer, p_buffer_size); } } return OK; @@ -377,8 +377,8 @@ int WebRTCMultiplayerPeer::get_available_packet_count() const { return 0; // To be sure next call to get_packet works if size > 0 . } int size = 0; - for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) { - for (const Ref<WebRTCDataChannel> &F : E->get()->channels) { + for (const KeyValue<int, Ref<ConnectedPeer>> &E : peer_map) { + for (const Ref<WebRTCDataChannel> &F : E.value->channels) { size += F->get_available_packet_count(); } } diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index 3a27855a5e..e54bfbca12 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -148,8 +148,8 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) { // Then send the server peer (which will trigger connection_succeded in client) _send_sys(get_peer(p_peer_id), SYS_ADD, 1); - for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { - int32_t id = E->key(); + for (const KeyValue<int, Ref<WebSocketPeer>> &E : _peer_map) { + int32_t id = E.key; if (p_peer_id == id) { continue; // Skip the newly added peer (already confirmed) } @@ -162,8 +162,8 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) { } void WebSocketMultiplayerPeer::_send_del(int32_t p_peer_id) { - for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { - int32_t id = E->key(); + for (const KeyValue<int, Ref<WebSocketPeer>> &E : _peer_map) { + int32_t id = E.key; if (p_peer_id != id) { _send_sys(get_peer(id), SYS_DEL, p_peer_id); } @@ -186,17 +186,17 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons return OK; // Will not send to self } else if (p_to == 0) { - for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { - if (E->key() != p_from) { - E->get()->put_packet(p_buffer, p_buffer_size); + for (KeyValue<int, Ref<WebSocketPeer>> &E : _peer_map) { + if (E.key != p_from) { + E.value->put_packet(p_buffer, p_buffer_size); } } return OK; // Sent to all but sender } else if (p_to < 0) { - for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { - if (E->key() != p_from && E->key() != -p_to) { - E->get()->put_packet(p_buffer, p_buffer_size); + for (KeyValue<int, Ref<WebSocketPeer>> &E : _peer_map) { + if (E.key != p_from && E.key != -p_to) { + E.value->put_packet(p_buffer, p_buffer_size); } } return OK; // Sent to all but sender and excluded diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index 7402bbb46e..514b2d055f 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -182,12 +182,12 @@ Error WSLServer::listen(int p_port, const Vector<String> p_protocols, bool gd_mp void WSLServer::poll() { List<int> remove_ids; - for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { - Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr(); + for (const KeyValue<int, Ref<WebSocketPeer>> &E : _peer_map) { + Ref<WSLPeer> peer = (WSLPeer *)E.value.ptr(); peer->poll(); if (!peer->is_connected_to_host()) { - _on_disconnect(E->key(), peer->close_code != -1); - remove_ids.push_back(E->key()); + _on_disconnect(E.key, peer->close_code != -1); + remove_ids.push_back(E.key); } } for (int &E : remove_ids) { @@ -265,8 +265,8 @@ int WSLServer::get_max_packet_size() const { void WSLServer::stop() { _server->stop(); - for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) { - Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr(); + for (const KeyValue<int, Ref<WebSocketPeer>> &E : _peer_map) { + Ref<WSLPeer> peer = (WSLPeer *)E.value.ptr(); peer->close_now(); } _pending.clear(); diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp index 5d285a6e60..c7bd172751 100644 --- a/platform/javascript/export/export_plugin.cpp +++ b/platform/javascript/export/export_plugin.cpp @@ -99,8 +99,8 @@ void EditorExportPlatformJavaScript::_replace_strings(Map<String, String> p_repl Vector<String> lines = str_template.split("\n"); for (int i = 0; i < lines.size(); i++) { String current_line = lines[i]; - for (Map<String, String>::Element *E = p_replaces.front(); E; E = E->next()) { - current_line = current_line.replace(E->key(), E->get()); + for (const KeyValue<String, String> &E : p_replaces) { + current_line = current_line.replace(E.key, E.value); } out += current_line + "\n"; } diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 5c6824cf44..f2cd336b39 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -306,11 +306,11 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { // The only modes that show a cursor are VISIBLE and CONFINED bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + for (const KeyValue<WindowID, WindowData> &E : windows) { if (showCursor) { - XDefineCursor(x11_display, E->get().x11_window, cursors[current_cursor]); // show cursor + XDefineCursor(x11_display, E.value.x11_window, cursors[current_cursor]); // show cursor } else { - XDefineCursor(x11_display, E->get().x11_window, null_cursor); // hide cursor + XDefineCursor(x11_display, E.value.x11_window, null_cursor); // hide cursor } } mouse_mode = p_mode; @@ -785,8 +785,8 @@ Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const { _THREAD_SAFE_METHOD_ Vector<int> ret; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<WindowID, WindowData> &E : windows) { + ret.push_back(E.key); } return ret; } @@ -864,8 +864,8 @@ DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const WindowID found_window = INVALID_WINDOW_ID; WindowID parent_window = INVALID_WINDOW_ID; unsigned int focus_order = 0; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - const WindowData &wd = E->get(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + const WindowData &wd = E.value; // Discard windows with no focus. if (wd.focus_order == 0) { @@ -873,7 +873,7 @@ DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const } // Find topmost window which contains the given position. - WindowID window_id = E->key(); + WindowID window_id = E.key; Rect2i win_rect = Rect2i(window_get_position(window_id), window_get_size(window_id)); if (win_rect.has_point(p_position)) { // For siblings, pick the window which was focused last. @@ -1768,8 +1768,8 @@ bool DisplayServerX11::window_can_draw(WindowID p_window) const { bool DisplayServerX11::can_any_window_draw() const { _THREAD_SAFE_METHOD_ - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (window_get_mode(E->key()) != WINDOW_MODE_MINIMIZED) { + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (window_get_mode(E.key) != WINDOW_MODE_MINIMIZED) { return true; } } @@ -1841,12 +1841,12 @@ void DisplayServerX11::cursor_set_shape(CursorShape p_shape) { if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { if (cursors[p_shape] != None) { - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - XDefineCursor(x11_display, E->get().x11_window, cursors[p_shape]); + for (const KeyValue<WindowID, WindowData> &E : windows) { + XDefineCursor(x11_display, E.value.x11_window, cursors[p_shape]); } } else if (cursors[CURSOR_ARROW] != None) { - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - XDefineCursor(x11_display, E->get().x11_window, cursors[CURSOR_ARROW]); + for (const KeyValue<WindowID, WindowData> &E : windows) { + XDefineCursor(x11_display, E.value.x11_window, cursors[CURSOR_ARROW]); } } } @@ -1944,8 +1944,8 @@ void DisplayServerX11::cursor_set_custom_image(const RES &p_cursor, CursorShape if (p_shape == current_cursor) { if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - XDefineCursor(x11_display, E->get().x11_window, cursors[p_shape]); + for (const KeyValue<WindowID, WindowData> &E : windows) { + XDefineCursor(x11_display, E.value.x11_window, cursors[p_shape]); } } } @@ -2068,6 +2068,24 @@ String DisplayServerX11::keyboard_get_layout_name(int p_index) const { return ret; } +Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const { + unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK; + unsigned int keycode_no_mod = p_keycode & KEY_CODE_MASK; + unsigned int xkeycode = KeyMappingX11::get_xlibcode((Key)keycode_no_mod); + KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, 0, 0); + if (xkeysym >= 'a' && xkeysym <= 'z') { + xkeysym -= ('a' - 'A'); + } + + Key key = KeyMappingX11::get_keycode(xkeysym); + // If not found, fallback to QWERTY. + // This should match the behavior of the event pump + if (key == KEY_NONE) { + return p_keycode; + } + return (Key)(key | modifiers); +} + DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) { Atom actual_type = None; int actual_format = 0; @@ -2517,8 +2535,8 @@ void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data, DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data); ds->xim = nullptr; - for (Map<WindowID, WindowData>::Element *E = ds->windows.front(); E; E = E->next()) { - E->get().xic = nullptr; + for (KeyValue<WindowID, WindowData> &E : ds->windows) { + E.value.xic = nullptr; } } @@ -2526,9 +2544,9 @@ void DisplayServerX11::_window_changed(XEvent *event) { WindowID window_id = MAIN_WINDOW_ID; // Assign the event to the relevant window - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (event->xany.window == E->get().x11_window) { - window_id = E->key(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (event->xany.window == E.value.x11_window) { + window_id = E.key; break; } } @@ -2602,8 +2620,8 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) { callable.call((const Variant **)&evp, 1, ret, ce); } else { //send to all windows - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - Callable callable = E->get().input_event_callback; + for (KeyValue<WindowID, WindowData> &E : windows) { + Callable callable = E.value.input_event_callback; if (callable.is_null()) { continue; } @@ -2703,8 +2721,8 @@ void DisplayServerX11::process_events() { if (app_focused) { //verify that one of the windows has focus, else send focus out notification bool focus_found = false; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (E->get().focused) { + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (E.value.focused) { focus_found = true; break; } @@ -2749,9 +2767,9 @@ void DisplayServerX11::process_events() { WindowID window_id = MAIN_WINDOW_ID; // Assign the event to the relevant window - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (event.xany.window == E->get().x11_window) { - window_id = E->key(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (event.xany.window == E.value.x11_window) { + window_id = E.key; break; } } @@ -2990,17 +3008,17 @@ void DisplayServerX11::process_events() { if (mouse_mode_grab) { // Show and update the cursor if confined and the window regained focus. - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + for (const KeyValue<WindowID, WindowData> &E : windows) { if (mouse_mode == MOUSE_MODE_CONFINED) { - XUndefineCursor(x11_display, E->get().x11_window); + XUndefineCursor(x11_display, E.value.x11_window); } else if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { // Or re-hide it. - XDefineCursor(x11_display, E->get().x11_window, null_cursor); + XDefineCursor(x11_display, E.value.x11_window, null_cursor); } XGrabPointer( - x11_display, E->get().x11_window, True, + x11_display, E.value.x11_window, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, - GrabModeAsync, GrabModeAsync, E->get().x11_window, None, CurrentTime); + GrabModeAsync, GrabModeAsync, E.value.x11_window, None, CurrentTime); } } #ifdef TOUCH_ENABLED @@ -3036,11 +3054,11 @@ void DisplayServerX11::process_events() { _send_window_event(wd, WINDOW_EVENT_FOCUS_OUT); if (mouse_mode_grab) { - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + for (const KeyValue<WindowID, WindowData> &E : windows) { //dear X11, I try, I really try, but you never work, you do whathever you want. if (mouse_mode == MOUSE_MODE_CAPTURED) { // Show the cursor if we're in captured mode so it doesn't look weird. - XUndefineCursor(x11_display, E->get().x11_window); + XUndefineCursor(x11_display, E.value.x11_window); } } XUngrabPointer(x11_display, CurrentTime); @@ -3052,12 +3070,12 @@ void DisplayServerX11::process_events() { }*/ // Release every pointer to avoid sticky points - for (Map<int, Vector2>::Element *E = xi.state.front(); E; E = E->next()) { + for (const KeyValue<int, Vector2> &E : xi.state) { Ref<InputEventScreenTouch> st; st.instantiate(); - st->set_index(E->key()); + st->set_index(E.key); st->set_window_id(window_id); - st->set_position(E->get()); + st->set_position(E.value); Input::get_singleton()->parse_input_event(st); } xi.state.clear(); @@ -3144,9 +3162,9 @@ void DisplayServerX11::process_events() { // Note: This is needed for drag & drop to work between windows, // because the engine expects events to keep being processed // on the same window dragging started. - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - const WindowData &wd_other = E->get(); - WindowID window_id_other = E->key(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + const WindowData &wd_other = E.value; + WindowID window_id_other = E.key; if (wd_other.focused) { if (window_id_other != window_id) { int x, y; @@ -3287,8 +3305,8 @@ void DisplayServerX11::process_events() { // Note: This is needed for drag & drop to work between windows, // because the engine expects events to keep being processed // on the same window dragging started. - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - const WindowData &wd_other = E->get(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + const WindowData &wd_other = E.value; if (wd_other.focused) { int x, y; Window child; @@ -3296,7 +3314,7 @@ void DisplayServerX11::process_events() { Point2i pos_focused(x, y); - mm->set_window_id(E->key()); + mm->set_window_id(E.key); mm->set_position(pos_focused); mm->set_global_position(pos_focused); mm->set_speed(Input::get_singleton()->get_last_mouse_speed()); @@ -3487,8 +3505,8 @@ void DisplayServerX11::set_context(Context p_context) { context = p_context; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - _update_context(E->get()); + for (KeyValue<WindowID, WindowData> &E : windows) { + _update_context(E.value); } } @@ -4268,14 +4286,14 @@ DisplayServerX11::~DisplayServerX11() { events_thread.wait_to_finish(); //destroy all windows - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { + for (KeyValue<WindowID, WindowData> &E : windows) { #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { - context_vulkan->window_destroy(E->key()); + context_vulkan->window_destroy(E.key); } #endif - WindowData &wd = E->get(); + WindowData &wd = E.value; if (wd.xic) { XDestroyIC(wd.xic); wd.xic = nullptr; diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index 052c6d6b7b..1887c7105b 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -372,6 +372,7 @@ public: virtual void keyboard_set_current_layout(int p_index) override; virtual String keyboard_get_layout_language(int p_index) const override; virtual String keyboard_get_layout_name(int p_index) const override; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override; virtual void process_events() override; diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp index a1ef28234d..829feda40a 100644 --- a/platform/linuxbsd/key_mapping_x11.cpp +++ b/platform/linuxbsd/key_mapping_x11.cpp @@ -309,6 +309,18 @@ unsigned int KeyMappingX11::get_scancode(unsigned int p_code) { return keycode; } +unsigned int KeyMappingX11::get_xlibcode(unsigned int p_keysym) { + unsigned int code = 0; + for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + if (_scancode_to_keycode[i].keysym == p_keysym) { + code = _scancode_to_keycode[i].keycode; + break; + } + } + + return code; +} + Key KeyMappingX11::get_keycode(KeySym p_keysym) { // kinda bruteforce.. could optimize. diff --git a/platform/linuxbsd/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h index 598db1c45a..d4f1554671 100644 --- a/platform/linuxbsd/key_mapping_x11.h +++ b/platform/linuxbsd/key_mapping_x11.h @@ -45,6 +45,7 @@ class KeyMappingX11 { public: static Key get_keycode(KeySym p_keysym); + static unsigned int get_xlibcode(unsigned int p_keysym); static unsigned int get_scancode(unsigned int p_code); static KeySym get_keysym(Key p_code); static unsigned int get_unicode_from_keysym(KeySym p_keysym); diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index 06b14f1c14..e8f2858489 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -305,6 +305,7 @@ public: virtual void keyboard_set_current_layout(int p_index) override; virtual String keyboard_get_layout_language(int p_index) const override; virtual String keyboard_get_layout_name(int p_index) const override; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override; virtual void process_events() override; virtual void force_process_and_drop_events() override; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index f037d75fbd..da6c45793a 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -930,146 +930,155 @@ static bool isNumpadKey(unsigned int key) { return false; } +// Keyboard symbol translation table +static const Key _osx_to_godot_table[128] = { + /* 00 */ KEY_A, + /* 01 */ KEY_S, + /* 02 */ KEY_D, + /* 03 */ KEY_F, + /* 04 */ KEY_H, + /* 05 */ KEY_G, + /* 06 */ KEY_Z, + /* 07 */ KEY_X, + /* 08 */ KEY_C, + /* 09 */ KEY_V, + /* 0a */ KEY_SECTION, /* ISO Section */ + /* 0b */ KEY_B, + /* 0c */ KEY_Q, + /* 0d */ KEY_W, + /* 0e */ KEY_E, + /* 0f */ KEY_R, + /* 10 */ KEY_Y, + /* 11 */ KEY_T, + /* 12 */ KEY_1, + /* 13 */ KEY_2, + /* 14 */ KEY_3, + /* 15 */ KEY_4, + /* 16 */ KEY_6, + /* 17 */ KEY_5, + /* 18 */ KEY_EQUAL, + /* 19 */ KEY_9, + /* 1a */ KEY_7, + /* 1b */ KEY_MINUS, + /* 1c */ KEY_8, + /* 1d */ KEY_0, + /* 1e */ KEY_BRACERIGHT, + /* 1f */ KEY_O, + /* 20 */ KEY_U, + /* 21 */ KEY_BRACELEFT, + /* 22 */ KEY_I, + /* 23 */ KEY_P, + /* 24 */ KEY_ENTER, + /* 25 */ KEY_L, + /* 26 */ KEY_J, + /* 27 */ KEY_APOSTROPHE, + /* 28 */ KEY_K, + /* 29 */ KEY_SEMICOLON, + /* 2a */ KEY_BACKSLASH, + /* 2b */ KEY_COMMA, + /* 2c */ KEY_SLASH, + /* 2d */ KEY_N, + /* 2e */ KEY_M, + /* 2f */ KEY_PERIOD, + /* 30 */ KEY_TAB, + /* 31 */ KEY_SPACE, + /* 32 */ KEY_QUOTELEFT, + /* 33 */ KEY_BACKSPACE, + /* 34 */ KEY_UNKNOWN, + /* 35 */ KEY_ESCAPE, + /* 36 */ KEY_META, + /* 37 */ KEY_META, + /* 38 */ KEY_SHIFT, + /* 39 */ KEY_CAPSLOCK, + /* 3a */ KEY_ALT, + /* 3b */ KEY_CTRL, + /* 3c */ KEY_SHIFT, + /* 3d */ KEY_ALT, + /* 3e */ KEY_CTRL, + /* 3f */ KEY_UNKNOWN, /* Function */ + /* 40 */ KEY_UNKNOWN, /* F17 */ + /* 41 */ KEY_KP_PERIOD, + /* 42 */ KEY_UNKNOWN, + /* 43 */ KEY_KP_MULTIPLY, + /* 44 */ KEY_UNKNOWN, + /* 45 */ KEY_KP_ADD, + /* 46 */ KEY_UNKNOWN, + /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */ + /* 48 */ KEY_VOLUMEUP, /* VolumeUp */ + /* 49 */ KEY_VOLUMEDOWN, /* VolumeDown */ + /* 4a */ KEY_VOLUMEMUTE, /* Mute */ + /* 4b */ KEY_KP_DIVIDE, + /* 4c */ KEY_KP_ENTER, + /* 4d */ KEY_UNKNOWN, + /* 4e */ KEY_KP_SUBTRACT, + /* 4f */ KEY_UNKNOWN, /* F18 */ + /* 50 */ KEY_UNKNOWN, /* F19 */ + /* 51 */ KEY_EQUAL, /* KeypadEqual */ + /* 52 */ KEY_KP_0, + /* 53 */ KEY_KP_1, + /* 54 */ KEY_KP_2, + /* 55 */ KEY_KP_3, + /* 56 */ KEY_KP_4, + /* 57 */ KEY_KP_5, + /* 58 */ KEY_KP_6, + /* 59 */ KEY_KP_7, + /* 5a */ KEY_UNKNOWN, /* F20 */ + /* 5b */ KEY_KP_8, + /* 5c */ KEY_KP_9, + /* 5d */ KEY_YEN, /* JIS Yen */ + /* 5e */ KEY_UNDERSCORE, /* JIS Underscore */ + /* 5f */ KEY_COMMA, /* JIS KeypadComma */ + /* 60 */ KEY_F5, + /* 61 */ KEY_F6, + /* 62 */ KEY_F7, + /* 63 */ KEY_F3, + /* 64 */ KEY_F8, + /* 65 */ KEY_F9, + /* 66 */ KEY_UNKNOWN, /* JIS Eisu */ + /* 67 */ KEY_F11, + /* 68 */ KEY_UNKNOWN, /* JIS Kana */ + /* 69 */ KEY_F13, + /* 6a */ KEY_F16, + /* 6b */ KEY_F14, + /* 6c */ KEY_UNKNOWN, + /* 6d */ KEY_F10, + /* 6e */ KEY_MENU, + /* 6f */ KEY_F12, + /* 70 */ KEY_UNKNOWN, + /* 71 */ KEY_F15, + /* 72 */ KEY_INSERT, /* Really Help... */ + /* 73 */ KEY_HOME, + /* 74 */ KEY_PAGEUP, + /* 75 */ KEY_DELETE, + /* 76 */ KEY_F4, + /* 77 */ KEY_END, + /* 78 */ KEY_F2, + /* 79 */ KEY_PAGEDOWN, + /* 7a */ KEY_F1, + /* 7b */ KEY_LEFT, + /* 7c */ KEY_RIGHT, + /* 7d */ KEY_DOWN, + /* 7e */ KEY_UP, + /* 7f */ KEY_UNKNOWN, +}; + // Translates a OS X keycode to a Godot keycode -// static Key translateKey(unsigned int key) { - // Keyboard symbol translation table - static const Key table[128] = { - /* 00 */ KEY_A, - /* 01 */ KEY_S, - /* 02 */ KEY_D, - /* 03 */ KEY_F, - /* 04 */ KEY_H, - /* 05 */ KEY_G, - /* 06 */ KEY_Z, - /* 07 */ KEY_X, - /* 08 */ KEY_C, - /* 09 */ KEY_V, - /* 0a */ KEY_SECTION, /* ISO Section */ - /* 0b */ KEY_B, - /* 0c */ KEY_Q, - /* 0d */ KEY_W, - /* 0e */ KEY_E, - /* 0f */ KEY_R, - /* 10 */ KEY_Y, - /* 11 */ KEY_T, - /* 12 */ KEY_1, - /* 13 */ KEY_2, - /* 14 */ KEY_3, - /* 15 */ KEY_4, - /* 16 */ KEY_6, - /* 17 */ KEY_5, - /* 18 */ KEY_EQUAL, - /* 19 */ KEY_9, - /* 1a */ KEY_7, - /* 1b */ KEY_MINUS, - /* 1c */ KEY_8, - /* 1d */ KEY_0, - /* 1e */ KEY_BRACERIGHT, - /* 1f */ KEY_O, - /* 20 */ KEY_U, - /* 21 */ KEY_BRACELEFT, - /* 22 */ KEY_I, - /* 23 */ KEY_P, - /* 24 */ KEY_ENTER, - /* 25 */ KEY_L, - /* 26 */ KEY_J, - /* 27 */ KEY_APOSTROPHE, - /* 28 */ KEY_K, - /* 29 */ KEY_SEMICOLON, - /* 2a */ KEY_BACKSLASH, - /* 2b */ KEY_COMMA, - /* 2c */ KEY_SLASH, - /* 2d */ KEY_N, - /* 2e */ KEY_M, - /* 2f */ KEY_PERIOD, - /* 30 */ KEY_TAB, - /* 31 */ KEY_SPACE, - /* 32 */ KEY_QUOTELEFT, - /* 33 */ KEY_BACKSPACE, - /* 34 */ KEY_UNKNOWN, - /* 35 */ KEY_ESCAPE, - /* 36 */ KEY_META, - /* 37 */ KEY_META, - /* 38 */ KEY_SHIFT, - /* 39 */ KEY_CAPSLOCK, - /* 3a */ KEY_ALT, - /* 3b */ KEY_CTRL, - /* 3c */ KEY_SHIFT, - /* 3d */ KEY_ALT, - /* 3e */ KEY_CTRL, - /* 3f */ KEY_UNKNOWN, /* Function */ - /* 40 */ KEY_UNKNOWN, /* F17 */ - /* 41 */ KEY_KP_PERIOD, - /* 42 */ KEY_UNKNOWN, - /* 43 */ KEY_KP_MULTIPLY, - /* 44 */ KEY_UNKNOWN, - /* 45 */ KEY_KP_ADD, - /* 46 */ KEY_UNKNOWN, - /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */ - /* 48 */ KEY_VOLUMEUP, /* VolumeUp */ - /* 49 */ KEY_VOLUMEDOWN, /* VolumeDown */ - /* 4a */ KEY_VOLUMEMUTE, /* Mute */ - /* 4b */ KEY_KP_DIVIDE, - /* 4c */ KEY_KP_ENTER, - /* 4d */ KEY_UNKNOWN, - /* 4e */ KEY_KP_SUBTRACT, - /* 4f */ KEY_UNKNOWN, /* F18 */ - /* 50 */ KEY_UNKNOWN, /* F19 */ - /* 51 */ KEY_EQUAL, /* KeypadEqual */ - /* 52 */ KEY_KP_0, - /* 53 */ KEY_KP_1, - /* 54 */ KEY_KP_2, - /* 55 */ KEY_KP_3, - /* 56 */ KEY_KP_4, - /* 57 */ KEY_KP_5, - /* 58 */ KEY_KP_6, - /* 59 */ KEY_KP_7, - /* 5a */ KEY_UNKNOWN, /* F20 */ - /* 5b */ KEY_KP_8, - /* 5c */ KEY_KP_9, - /* 5d */ KEY_YEN, /* JIS Yen */ - /* 5e */ KEY_UNDERSCORE, /* JIS Underscore */ - /* 5f */ KEY_COMMA, /* JIS KeypadComma */ - /* 60 */ KEY_F5, - /* 61 */ KEY_F6, - /* 62 */ KEY_F7, - /* 63 */ KEY_F3, - /* 64 */ KEY_F8, - /* 65 */ KEY_F9, - /* 66 */ KEY_UNKNOWN, /* JIS Eisu */ - /* 67 */ KEY_F11, - /* 68 */ KEY_UNKNOWN, /* JIS Kana */ - /* 69 */ KEY_F13, - /* 6a */ KEY_F16, - /* 6b */ KEY_F14, - /* 6c */ KEY_UNKNOWN, - /* 6d */ KEY_F10, - /* 6e */ KEY_MENU, - /* 6f */ KEY_F12, - /* 70 */ KEY_UNKNOWN, - /* 71 */ KEY_F15, - /* 72 */ KEY_INSERT, /* Really Help... */ - /* 73 */ KEY_HOME, - /* 74 */ KEY_PAGEUP, - /* 75 */ KEY_DELETE, - /* 76 */ KEY_F4, - /* 77 */ KEY_END, - /* 78 */ KEY_F2, - /* 79 */ KEY_PAGEDOWN, - /* 7a */ KEY_F1, - /* 7b */ KEY_LEFT, - /* 7c */ KEY_RIGHT, - /* 7d */ KEY_DOWN, - /* 7e */ KEY_UP, - /* 7f */ KEY_UNKNOWN, - }; - if (key >= 128) { return KEY_UNKNOWN; } - return table[key]; + return _osx_to_godot_table[key]; +} + +// Translates a Godot keycode back to a OSX keycode +static unsigned int unmapKey(Key key) { + for (int i = 0; i <= 126; i++) { + if (_osx_to_godot_table[i] == key) { + return i; + } + } + return 127; } struct _KeyCodeMap { @@ -3200,6 +3209,17 @@ String DisplayServerOSX::keyboard_get_layout_name(int p_index) const { return kbd_layouts[p_index].name; } +Key DisplayServerOSX::keyboard_get_keycode_from_physical(Key p_keycode) const { + if (p_keycode == KEY_PAUSE) { + return p_keycode; + } + + unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK; + unsigned int keycode_no_mod = p_keycode & KEY_CODE_MASK; + unsigned int osx_keycode = unmapKey((Key)keycode_no_mod); + return (Key)(remapKey(osx_keycode, 0) | modifiers); +} + void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; Input::get_singleton()->parse_input_event(ev); diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index df41ccd892..a52436a70a 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -82,6 +82,7 @@ public: virtual String get_data_path() const override; virtual String get_cache_path() const override; virtual String get_bundle_resource_dir() const override; + virtual String get_bundle_icon_path() const override; virtual String get_godot_dir_name() const override; virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index c6e35fee83..e9cb46ed21 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -314,17 +314,27 @@ String OS_OSX::get_name() const { return "macOS"; } +_FORCE_INLINE_ String _get_framework_executable(const String p_path) { + // Append framework executable name, or return as is if p_path is not a framework. + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) { + return p_path.plus_file(p_path.get_file().get_basename()); + } else { + return p_path; + } +} + Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { - String path = p_path; + String path = _get_framework_executable(p_path); if (!FileAccess::exists(path)) { - //this code exists so gdnative can load .dylib files from within the executable path - path = get_executable_path().get_base_dir().plus_file(p_path.get_file()); + // This code exists so gdnative can load .dylib files from within the executable path. + path = _get_framework_executable(get_executable_path().get_base_dir().plus_file(p_path.get_file())); } if (!FileAccess::exists(path)) { - //this code exists so gdnative can load .dylib files from a standard macOS location - path = get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file()); + // This code exists so gdnative can load .dylib files from a standard macOS location. + path = _get_framework_executable(get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file())); } p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); @@ -379,14 +389,26 @@ String OS_OSX::get_cache_path() const { } String OS_OSX::get_bundle_resource_dir() const { + String ret; + NSBundle *main = [NSBundle mainBundle]; - NSString *resourcePath = [main resourcePath]; + if (main) { + NSString *resourcePath = [main resourcePath]; + ret.parse_utf8([resourcePath UTF8String]); + } + return ret; +} - char *utfs = strdup([resourcePath UTF8String]); +String OS_OSX::get_bundle_icon_path() const { String ret; - ret.parse_utf8(utfs); - free(utfs); + NSBundle *main = [NSBundle mainBundle]; + if (main) { + NSString *iconPath = [[main infoDictionary] objectForKey:@"CFBundleIconFile"]; + if (iconPath) { + ret.parse_utf8([iconPath UTF8String]); + } + } return ret; } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 6402702415..3100c0bd27 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -454,8 +454,8 @@ Vector<DisplayServer::WindowID> DisplayServerWindows::get_window_list() const { _THREAD_SAFE_METHOD_ Vector<DisplayServer::WindowID> ret; - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<WindowID, WindowData> &E : windows) { + ret.push_back(E.key); } return ret; } @@ -465,9 +465,9 @@ DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(cons p.x = p_position.x; p.y = p_position.y; HWND hwnd = WindowFromPoint(p); - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (E->get().hWnd == hwnd) { - return E->key(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (E.value.hWnd == hwnd) { + return E.key; } } @@ -1131,8 +1131,8 @@ bool DisplayServerWindows::window_can_draw(WindowID p_window) const { bool DisplayServerWindows::can_any_window_draw() const { _THREAD_SAFE_METHOD_ - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (!E->get().minimized) { + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (!E.value.minimized) { return true; } } @@ -1476,6 +1476,42 @@ String DisplayServerWindows::keyboard_get_layout_language(int p_index) const { return String::utf16((const char16_t *)buf).substr(0, 2); } +Key DisplayServerWindows::keyboard_get_keycode_from_physical(Key p_keycode) const { + unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK; + Key keycode_no_mod = (Key)(p_keycode & KEY_CODE_MASK); + + if (keycode_no_mod == KEY_PRINT || + keycode_no_mod == KEY_KP_ADD || + keycode_no_mod == KEY_KP_5 || + (keycode_no_mod >= KEY_0 && keycode_no_mod <= KEY_9)) { + return p_keycode; + } + + unsigned int scancode = KeyMappingWindows::get_scancode(keycode_no_mod); + if (scancode == 0) { + return p_keycode; + } + + HKL current_layout = GetKeyboardLayout(0); + UINT vk = MapVirtualKeyEx(scancode, MAPVK_VSC_TO_VK, current_layout); + if (vk == 0) { + return p_keycode; + } + + UINT char_code = MapVirtualKeyEx(vk, MAPVK_VK_TO_CHAR, current_layout) & 0x7FFF; + // Unlike a similar Linux/BSD check which matches full Latin-1 range, + // we limit these to ASCII to fix some layouts, including Arabic ones + if (char_code >= 32 && char_code <= 127) { + // Godot uses 'braces' instead of 'brackets' + if (char_code == KEY_BRACKETLEFT || char_code == KEY_BRACKETRIGHT) { + char_code += 32; + } + return (Key)(char_code | modifiers); + } + + return (Key)(KeyMappingWindows::get_keysym(vk) | modifiers); +} + String _get_full_layout_name_from_registry(HKL p_layout) { String id = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + String::num_int64((int64_t)p_layout, 16, false).lpad(8, "0"); String ret; @@ -1816,8 +1852,8 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) callable.call((const Variant **)&evp, 1, ret, ce); } else { // Send to all windows. - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - Callable callable = E->get().input_event_callback; + for (const KeyValue<WindowID, WindowData> &E : windows) { + const Callable callable = E.value.input_event_callback; if (callable.is_null()) { continue; } @@ -1844,9 +1880,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA bool window_created = false; // Check whether window exists. - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - if (E->get().hWnd == hWnd) { - window_id = E->key(); + for (const KeyValue<WindowID, WindowData> &E : windows) { + if (E.value.hWnd == hWnd) { + window_id = E.key; window_created = true; break; } @@ -1882,8 +1918,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA ReleaseCapture(); // Release every touch to avoid sticky points. - for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) { - _touch_event(window_id, false, E->get().x, E->get().y, E->key()); + for (const KeyValue<int, Vector2> &E : touch_state) { + _touch_event(window_id, false, E.value.x, E.value.y, E.key); } touch_state.clear(); @@ -2943,8 +2979,8 @@ void DisplayServerWindows::_process_key_events() { } void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const String &p_new_driver) { - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - WindowData &wd = E->get(); + for (KeyValue<WindowID, WindowData> &E : windows) { + WindowData &wd = E.value; wd.block_mm = false; if ((p_old_driver == "wintab") && wintab_available && wd.wtctx) { wintab_WTEnable(wd.wtctx, false); diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index c02a90c543..8b82288a40 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -543,6 +543,7 @@ public: virtual void keyboard_set_current_layout(int p_index) override; virtual String keyboard_get_layout_language(int p_index) const override; virtual String keyboard_get_layout_name(int p_index) const override; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override; virtual int tablet_get_driver_count() const override; virtual String tablet_get_driver_name(int p_driver) const override; diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp index db99d6c122..8016d20470 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -345,6 +345,16 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) { return KEY_UNKNOWN; } +unsigned int KeyMappingWindows::get_scancode(Key p_keycode) { + for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + if (_scancode_to_keycode[i].keysym == p_keycode) { + return _scancode_to_keycode[i].keycode; + } + } + + return 0; +} + unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) { unsigned int keycode = KEY_UNKNOWN; for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) { diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h index fb07227014..f260666a3e 100644 --- a/platform/windows/key_mapping_windows.h +++ b/platform/windows/key_mapping_windows.h @@ -42,6 +42,7 @@ class KeyMappingWindows { public: static unsigned int get_keysym(unsigned int p_code); + static unsigned int get_scancode(Key p_keycode); static unsigned int get_scansym(unsigned int p_code, bool p_extended); static bool is_extended_key(unsigned int p_code); }; diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index d78b9847e6..33b1c7bcce 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -300,8 +300,8 @@ void Area2D::_clear_monitoring() { body_map.clear(); //disconnect all monitored stuff - for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, BodyState> &E : bmcopy) { + Object *obj = ObjectDB::get_instance(E.key); Node *node = Object::cast_to<Node>(obj); if (!node) { //node may have been deleted in previous frame or at other legitimate point @@ -311,12 +311,12 @@ void Area2D::_clear_monitoring() { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); - if (!E->get().in_tree) { + if (!E.value.in_tree) { continue; } - for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + for (int i = 0; i < E.value.shapes.size(); i++) { + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); } emit_signal(SceneStringNames::get_singleton()->body_exited, obj); @@ -328,8 +328,8 @@ void Area2D::_clear_monitoring() { area_map.clear(); //disconnect all monitored stuff - for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, AreaState> &E : bmcopy) { + Object *obj = ObjectDB::get_instance(E.key); Node *node = Object::cast_to<Node>(obj); if (!node) { //node may have been deleted in previous frame or at other legitimate point @@ -339,12 +339,12 @@ void Area2D::_clear_monitoring() { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); - if (!E->get().in_tree) { + if (!E.value.in_tree) { continue; } - for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + for (int i = 0; i < E.value.shapes.size(); i++) { + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); } emit_signal(SceneStringNames::get_singleton()->area_exited, obj); @@ -404,8 +404,8 @@ TypedArray<Node2D> Area2D::get_overlapping_bodies() const { TypedArray<Node2D> ret; ret.resize(body_map.size()); int idx = 0; - for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, BodyState> &E : body_map) { + Object *obj = ObjectDB::get_instance(E.key); if (!obj) { ret.resize(ret.size() - 1); //ops } else { @@ -421,8 +421,8 @@ TypedArray<Area2D> Area2D::get_overlapping_areas() const { TypedArray<Area2D> ret; ret.resize(area_map.size()); int idx = 0; - for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, AreaState> &E : area_map) { + Object *obj = ObjectDB::get_instance(E.key); if (!obj) { ret.resize(ret.size() - 1); //ops } else { diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 5d3a538f60..6916f832d0 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -342,15 +342,15 @@ real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_ow } void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) { - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - r_owners->push_back(E->key()); + for (const KeyValue<uint32_t, ShapeData> &E : shapes) { + r_owners->push_back(E.key); } } Array CollisionObject2D::_get_shape_owners() { Array ret; - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<uint32_t, ShapeData> &E : shapes) { + ret.push_back(E.key); } return ret; @@ -434,10 +434,10 @@ void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) shapes[p_owner].shapes.remove(p_shape); - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (E->get().shapes[i].index > index_to_remove) { - E->get().shapes.write[i].index -= 1; + for (KeyValue<uint32_t, ShapeData> &E : shapes) { + for (int i = 0; i < E.value.shapes.size(); i++) { + if (E.value.shapes[i].index > index_to_remove) { + E.value.shapes.write[i].index -= 1; } } } @@ -456,10 +456,10 @@ void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) { uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const { ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0); - for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (E->get().shapes[i].index == p_shape_index) { - return E->key(); + for (const KeyValue<uint32_t, ShapeData> &E : shapes) { + for (int i = 0; i < E.value.shapes.size(); i++) { + if (E.value.shapes[i].index == p_shape_index) { + return E.key; } } } diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joint_2d.cpp index 4a6606256e..3b371d4a07 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joint_2d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joints_2d.cpp */ +/* joint_2d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "joints_2d.h" +#include "joint_2d.h" #include "physics_body_2d.h" #include "scene/scene_string_names.h" diff --git a/scene/2d/joints_2d.h b/scene/2d/joint_2d.h index dc5a08f815..0c3956e463 100644 --- a/scene/2d/joints_2d.h +++ b/scene/2d/joint_2d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joints_2d.h */ +/* joint_2d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef JOINTS_2D_H -#define JOINTS_2D_H +#ifndef JOINT_2D_H +#define JOINT_2D_H #include "node_2d.h" @@ -148,4 +148,4 @@ public: DampedSpringJoint2D(); }; -#endif // JOINTS_2D_H +#endif // JOINT_2D_H diff --git a/scene/2d/physical_bone_2d.cpp b/scene/2d/physical_bone_2d.cpp index 48817679bc..c1b0bc35dd 100644 --- a/scene/2d/physical_bone_2d.cpp +++ b/scene/2d/physical_bone_2d.cpp @@ -30,6 +30,8 @@ #include "physical_bone_2d.h" +#include "scene/2d/joint_2d.h" + void PhysicalBone2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { diff --git a/scene/2d/physical_bone_2d.h b/scene/2d/physical_bone_2d.h index a250d0aadd..8b41f75c3e 100644 --- a/scene/2d/physical_bone_2d.h +++ b/scene/2d/physical_bone_2d.h @@ -31,11 +31,11 @@ #ifndef PHYSICAL_BONE_2D_H #define PHYSICAL_BONE_2D_H -#include "scene/2d/joints_2d.h" #include "scene/2d/physics_body_2d.h" - #include "scene/2d/skeleton_2d.h" +class Joint2D; + class PhysicalBone2D : public RigidDynamicBody2D { GDCLASS(PhysicalBone2D, RigidDynamicBody2D); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index c07a999588..5f56f86029 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -288,6 +288,12 @@ void AnimatableBody2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { last_valid_transform = get_global_transform(); + _update_kinematic_motion(); + } break; + + case NOTIFICATION_EXIT_TREE: { + set_only_update_transform_changes(false); + set_notify_local_transform(false); } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { @@ -313,7 +319,6 @@ void AnimatableBody2D::_bind_methods() { AnimatableBody2D::AnimatableBody2D() : StaticBody2D(PhysicsServer2D::BODY_MODE_KINEMATIC) { - _update_kinematic_motion(); } void RigidDynamicBody2D::_body_enter_tree(ObjectID p_id) { @@ -457,9 +462,9 @@ void RigidDynamicBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) //untag all int rc = 0; - for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - E->get().shapes[i].tagged = false; + for (KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { + for (int i = 0; i < E.value.shapes.size(); i++) { + E.value.shapes[i].tagged = false; rc++; } } @@ -503,12 +508,12 @@ void RigidDynamicBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) //put the ones to remove - for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (!E->get().shapes[i].tagged) { - toremove[toremove_count].rid = E->get().rid; - toremove[toremove_count].body_id = E->key(); - toremove[toremove_count].pair = E->get().shapes[i]; + for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { + for (int i = 0; i < E.value.shapes.size(); i++) { + if (!E.value.shapes[i].tagged) { + toremove[toremove_count].rid = E.value.rid; + toremove[toremove_count].body_id = E.key; + toremove[toremove_count].pair = E.value.shapes[i]; toremove_count++; } } @@ -815,8 +820,8 @@ TypedArray<Node2D> RigidDynamicBody2D::get_colliding_bodies() const { TypedArray<Node2D> ret; ret.resize(contact_monitor->body_map.size()); int idx = 0; - for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { + Object *obj = ObjectDB::get_instance(E.key); if (!obj) { ret.resize(ret.size() - 1); //ops } else { @@ -835,9 +840,9 @@ void RigidDynamicBody2D::set_contact_monitor(bool p_enabled) { if (!p_enabled) { ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead."); - for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { + for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { //clean up mess - Object *obj = ObjectDB::get_instance(E->key()); + Object *obj = ObjectDB::get_instance(E.key); Node *node = Object::cast_to<Node>(obj); if (node) { @@ -1047,6 +1052,8 @@ bool CharacterBody2D::move_and_slide() { double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); Vector2 current_platform_velocity = platform_velocity; + Transform2D gt = get_global_transform(); + previous_position = gt.elements[2]; if ((on_floor || on_wall) && platform_rid.is_valid()) { bool excluded = false; @@ -1059,7 +1066,6 @@ bool CharacterBody2D::move_and_slide() { //this approach makes sure there is less delay between the actual body velocity and the one we saved PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(platform_rid); if (bs) { - Transform2D gt = get_global_transform(); Vector2 local_position = gt.elements[2] - bs->get_transform().elements[2]; current_platform_velocity = bs->get_velocity_at_local_position(local_position); } @@ -1069,6 +1075,7 @@ bool CharacterBody2D::move_and_slide() { } motion_results.clear(); + last_motion = Vector2(); bool was_on_floor = on_floor; on_floor = false; @@ -1091,16 +1098,24 @@ bool CharacterBody2D::move_and_slide() { _move_and_slide_free(delta); } - if (!on_floor && !on_wall) { + // Compute real velocity. + real_velocity = get_position_delta() / delta; + + if (moving_platform_apply_velocity_on_leave != PLATFORM_VEL_ON_LEAVE_NEVER) { // Add last platform velocity when just left a moving platform. - linear_velocity += current_platform_velocity; + if (!on_floor && !on_wall) { + if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) { + current_platform_velocity = current_platform_velocity.slide(up_direction); + } + motion_velocity += current_platform_velocity; + } } return motion_results.size() > 0; } void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor, const Vector2 &p_prev_platform_velocity) { - Vector2 motion = linear_velocity * p_delta; + Vector2 motion = motion_velocity * p_delta; Vector2 motion_slide_up = motion.slide(up_direction); Vector2 prev_floor_normal = floor_normal; @@ -1116,8 +1131,10 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo bool sliding_enabled = !floor_stop_on_slope; // Constant speed can be applied only the first time sliding is enabled. bool can_apply_constant_speed = sliding_enabled; + // If the platform's ceiling push down the body. + bool apply_ceiling_velocity = false; bool first_slide = true; - bool vel_dir_facing_up = linear_velocity.dot(up_direction) > 0; + bool vel_dir_facing_up = motion_velocity.dot(up_direction) > 0; Vector2 last_travel; for (int iteration = 0; iteration < max_slides; ++iteration) { @@ -1126,18 +1143,33 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo Vector2 prev_position = get_global_transform().elements[2]; bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled); + last_motion = result.travel; if (collided) { motion_results.push_back(result); _set_collision_direction(result); - if (on_floor && floor_stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) { + // If we hit a ceiling platform, we set the vertical motion_velocity to at least the platform one. + if (on_ceiling && result.collider_velocity != Vector2() && result.collider_velocity.dot(up_direction) < 0) { + // If ceiling sliding is on, only apply when the ceiling is flat or when the motion is upward. + if (!slide_on_ceiling || motion.dot(up_direction) < 0 || (result.collision_normal + up_direction).length() < 0.01) { + apply_ceiling_velocity = true; + Vector2 ceiling_vertical_velocity = up_direction * up_direction.dot(result.collider_velocity); + Vector2 motion_vertical_velocity = up_direction * up_direction.dot(motion_velocity); + if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) { + motion_velocity = ceiling_vertical_velocity + motion_velocity.slide(up_direction); + } + } + } + + if (on_floor && floor_stop_on_slope && (motion_velocity.normalized() + up_direction).length() < 0.01) { Transform2D gt = get_global_transform(); if (result.travel.length() <= margin + CMP_EPSILON) { gt.elements[2] -= result.travel; } set_global_transform(gt); - linear_velocity = Vector2(); + motion_velocity = Vector2(); + last_motion = Vector2(); motion = Vector2(); break; } @@ -1163,7 +1195,8 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo platform_layer = prev_platform_layer; platform_velocity = p_prev_platform_velocity; floor_normal = prev_floor_normal; - linear_velocity = Vector2(); + motion_velocity = Vector2(); + last_motion = Vector2(); motion = Vector2(); break; } @@ -1182,9 +1215,9 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo motion = motion_slide_norm * (motion_slide_up.length() - result.travel.slide(up_direction).length() - last_travel.slide(up_direction).length()); } // Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling. - else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up)) { + else if ((sliding_enabled || !on_floor) && (!on_ceiling || slide_on_ceiling || !vel_dir_facing_up) && !apply_ceiling_velocity) { Vector2 slide_motion = result.remainder.slide(result.collision_normal); - if (slide_motion.dot(linear_velocity) > 0.0) { + if (slide_motion.dot(motion_velocity) > 0.0) { motion = slide_motion; } else { motion = Vector2(); @@ -1192,10 +1225,10 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo if (slide_on_ceiling && on_ceiling) { // Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall. if (vel_dir_facing_up) { - linear_velocity = linear_velocity.slide(result.collision_normal); + motion_velocity = motion_velocity.slide(result.collision_normal); } else { // Avoid acceleration in slope when falling. - linear_velocity = up_direction * up_direction.dot(linear_velocity); + motion_velocity = up_direction * up_direction.dot(motion_velocity); } } } @@ -1203,7 +1236,7 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo else { motion = result.remainder; if (on_ceiling && !slide_on_ceiling && vel_dir_facing_up) { - linear_velocity = linear_velocity.slide(up_direction); + motion_velocity = motion_velocity.slide(up_direction); motion = motion.slide(up_direction); } } @@ -1237,12 +1270,12 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo // Reset the gravity accumulation when touching the ground. if (on_floor && !vel_dir_facing_up) { - linear_velocity = linear_velocity.slide(up_direction); + motion_velocity = motion_velocity.slide(up_direction); } } void CharacterBody2D::_move_and_slide_free(double p_delta) { - Vector2 motion = linear_velocity * p_delta; + Vector2 motion = motion_velocity * p_delta; platform_rid = RID(); floor_normal = Vector2(); @@ -1253,12 +1286,18 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) { PhysicsServer2D::MotionResult result; bool collided = move_and_collide(motion, result, margin, false, false); + last_motion = result.travel; if (collided) { motion_results.push_back(result); _set_collision_direction(result); - if (free_mode_min_slide_angle != 0 && result.get_angle(-linear_velocity.normalized()) < free_mode_min_slide_angle + FLOOR_ANGLE_THRESHOLD) { + if (result.remainder.is_equal_approx(Vector2())) { + motion = Vector2(); + break; + } + + if (free_mode_min_slide_angle != 0 && result.get_angle(-motion_velocity.normalized()) < free_mode_min_slide_angle + FLOOR_ANGLE_THRESHOLD) { motion = Vector2(); } else if (first_slide) { Vector2 motion_slide_norm = result.remainder.slide(result.collision_normal).normalized(); @@ -1267,16 +1306,16 @@ void CharacterBody2D::_move_and_slide_free(double p_delta) { motion = result.remainder.slide(result.collision_normal); } - if (motion.dot(linear_velocity) <= 0.0) { + if (motion.dot(motion_velocity) <= 0.0) { motion = Vector2(); } } - first_slide = false; - if (!collided || motion.is_equal_approx(Vector2())) { break; } + + first_slide = false; } } @@ -1344,6 +1383,7 @@ void CharacterBody2D::_set_collision_direction(const PhysicsServer2D::MotionResu on_ceiling = true; } else { on_wall = true; + wall_normal = p_result.collision_normal; // Don't apply wall velocity when the collider is a CharacterBody2D. if (Object::cast_to<CharacterBody2D>(ObjectDB::get_instance(p_result.collider_id)) == nullptr) { _set_platform_data(p_result); @@ -1357,12 +1397,12 @@ void CharacterBody2D::_set_platform_data(const PhysicsServer2D::MotionResult &p_ platform_layer = PhysicsServer2D::get_singleton()->body_get_collision_layer(platform_rid); } -const Vector2 &CharacterBody2D::get_linear_velocity() const { - return linear_velocity; +const Vector2 &CharacterBody2D::get_motion_velocity() const { + return motion_velocity; } -void CharacterBody2D::set_linear_velocity(const Vector2 &p_velocity) { - linear_velocity = p_velocity; +void CharacterBody2D::set_motion_velocity(const Vector2 &p_velocity) { + motion_velocity = p_velocity; } bool CharacterBody2D::is_on_floor() const { @@ -1389,16 +1429,32 @@ bool CharacterBody2D::is_on_ceiling_only() const { return on_ceiling && !on_floor && !on_wall; } -Vector2 CharacterBody2D::get_floor_normal() const { +const Vector2 &CharacterBody2D::get_floor_normal() const { return floor_normal; } +const Vector2 &CharacterBody2D::get_wall_normal() const { + return wall_normal; +} + +const Vector2 &CharacterBody2D::get_last_motion() const { + return last_motion; +} + +Vector2 CharacterBody2D::get_position_delta() const { + return get_global_transform().elements[2] - previous_position; +} + +const Vector2 &CharacterBody2D::get_real_velocity() const { + return real_velocity; +} + real_t CharacterBody2D::get_floor_angle(const Vector2 &p_up_direction) const { ERR_FAIL_COND_V(p_up_direction == Vector2(), 0); return Math::acos(floor_normal.dot(p_up_direction)); } -Vector2 CharacterBody2D::get_platform_velocity() const { +const Vector2 &CharacterBody2D::get_platform_velocity() const { return platform_velocity; } @@ -1498,6 +1554,14 @@ CharacterBody2D::MotionMode CharacterBody2D::get_motion_mode() const { return motion_mode; } +void CharacterBody2D::set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_apply_velocity) { + moving_platform_apply_velocity_on_leave = p_on_leave_apply_velocity; +} + +CharacterBody2D::MovingPlatformApplyVelocityOnLeave CharacterBody2D::get_moving_platform_apply_velocity_on_leave() const { + return moving_platform_apply_velocity_on_leave; +} + int CharacterBody2D::get_max_slides() const { return max_slides; } @@ -1558,8 +1622,8 @@ void CharacterBody2D::_notification(int p_what) { void CharacterBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody2D::move_and_slide); - ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody2D::set_linear_velocity); - ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody2D::get_linear_velocity); + ClassDB::bind_method(D_METHOD("set_motion_velocity", "motion_velocity"), &CharacterBody2D::set_motion_velocity); + ClassDB::bind_method(D_METHOD("get_motion_velocity"), &CharacterBody2D::get_motion_velocity); ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody2D::set_safe_margin); ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody2D::get_safe_margin); @@ -1589,6 +1653,8 @@ void CharacterBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody2D::set_up_direction); ClassDB::bind_method(D_METHOD("set_motion_mode", "mode"), &CharacterBody2D::set_motion_mode); ClassDB::bind_method(D_METHOD("get_motion_mode"), &CharacterBody2D::get_motion_mode); + ClassDB::bind_method(D_METHOD("set_moving_platform_apply_velocity_on_leave", "on_leave_apply_velocity"), &CharacterBody2D::set_moving_platform_apply_velocity_on_leave); + ClassDB::bind_method(D_METHOD("get_moving_platform_apply_velocity_on_leave"), &CharacterBody2D::get_moving_platform_apply_velocity_on_leave); ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody2D::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_floor_only"), &CharacterBody2D::is_on_floor_only); @@ -1597,6 +1663,10 @@ void CharacterBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_on_wall"), &CharacterBody2D::is_on_wall); ClassDB::bind_method(D_METHOD("is_on_wall_only"), &CharacterBody2D::is_on_wall_only); ClassDB::bind_method(D_METHOD("get_floor_normal"), &CharacterBody2D::get_floor_normal); + ClassDB::bind_method(D_METHOD("get_wall_normal"), &CharacterBody2D::get_wall_normal); + ClassDB::bind_method(D_METHOD("get_last_motion"), &CharacterBody2D::get_last_motion); + ClassDB::bind_method(D_METHOD("get_position_delta"), &CharacterBody2D::get_position_delta); + ClassDB::bind_method(D_METHOD("get_real_velocity"), &CharacterBody2D::get_real_velocity); ClassDB::bind_method(D_METHOD("get_floor_angle", "up_direction"), &CharacterBody2D::get_floor_angle, DEFVAL(Vector2(0.0, -1.0))); ClassDB::bind_method(D_METHOD("get_platform_velocity"), &CharacterBody2D::get_platform_velocity); ClassDB::bind_method(D_METHOD("get_slide_collision_count"), &CharacterBody2D::get_slide_collision_count); @@ -1604,10 +1674,11 @@ void CharacterBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &CharacterBody2D::_get_last_slide_collision); ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_motion_velocity", "get_motion_velocity"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_slides", "get_max_slides"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction"); + ADD_GROUP("Free Mode", "free_mode_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "free_mode_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_free_mode_min_slide_angle", "get_free_mode_min_slide_angle"); ADD_GROUP("Floor", "floor_"); @@ -1617,12 +1688,17 @@ void CharacterBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_floor_snap_length", "get_floor_snap_length"); ADD_GROUP("Moving platform", "moving_platform"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_apply_velocity_on_leave", PROPERTY_HINT_ENUM, "Always,Upward Only,Never", PROPERTY_USAGE_DEFAULT), "set_moving_platform_apply_velocity_on_leave", "get_moving_platform_apply_velocity_on_leave"); ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_floor_layers", "get_moving_platform_floor_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_wall_layers", "get_moving_platform_wall_layers"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED); BIND_ENUM_CONSTANT(MOTION_MODE_FREE); + + BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS); + BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY); + BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_NEVER); } void CharacterBody2D::_validate_property(PropertyInfo &property) const { @@ -1717,10 +1793,6 @@ Vector2 KinematicCollision2D::get_collider_velocity() const { return result.collider_velocity; } -Variant KinematicCollision2D::get_collider_metadata() const { - return Variant(); -} - void KinematicCollision2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision2D::get_position); ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision2D::get_normal); @@ -1734,7 +1806,6 @@ void KinematicCollision2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision2D::get_collider_shape); ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision2D::get_collider_shape_index); ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision2D::get_collider_velocity); - ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision2D::get_collider_metadata); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "", "get_normal"); @@ -1747,5 +1818,4 @@ void KinematicCollision2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "collider_velocity"), "", "get_collider_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index e789ac4cb7..70cc5cd9bf 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -310,10 +310,15 @@ public: MOTION_MODE_GROUNDED, MOTION_MODE_FREE, }; + enum MovingPlatformApplyVelocityOnLeave { + PLATFORM_VEL_ON_LEAVE_ALWAYS, + PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY, + PLATFORM_VEL_ON_LEAVE_NEVER, + }; bool move_and_slide(); - const Vector2 &get_linear_velocity() const; - void set_linear_velocity(const Vector2 &p_velocity); + const Vector2 &get_motion_velocity() const; + void set_motion_velocity(const Vector2 &p_velocity); bool is_on_floor() const; bool is_on_floor_only() const; @@ -321,9 +326,14 @@ public: bool is_on_wall_only() const; bool is_on_ceiling() const; bool is_on_ceiling_only() const; - Vector2 get_floor_normal() const; + const Vector2 &get_last_motion() const; + Vector2 get_position_delta() const; + const Vector2 &get_floor_normal() const; + const Vector2 &get_wall_normal() const; + const Vector2 &get_real_velocity() const; + real_t get_floor_angle(const Vector2 &p_up_direction = Vector2(0.0, -1.0)) const; - Vector2 get_platform_velocity() const; + const Vector2 &get_platform_velocity() const; int get_slide_collision_count() const; PhysicsServer2D::MotionResult get_slide_collision(int p_bounce) const; @@ -334,23 +344,29 @@ public: private: real_t margin = 0.08; MotionMode motion_mode = MOTION_MODE_GROUNDED; + MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS; bool floor_constant_speed = false; bool floor_stop_on_slope = true; bool floor_block_on_wall = true; bool slide_on_ceiling = true; int max_slides = 4; - int platform_layer; + int platform_layer = 0; real_t floor_max_angle = Math::deg2rad((real_t)45.0); real_t floor_snap_length = 1; real_t free_mode_min_slide_angle = Math::deg2rad((real_t)15.0); Vector2 up_direction = Vector2(0.0, -1.0); uint32_t moving_platform_floor_layers = UINT32_MAX; uint32_t moving_platform_wall_layers = 0; - Vector2 linear_velocity; + Vector2 motion_velocity; Vector2 floor_normal; Vector2 platform_velocity; + Vector2 wall_normal; + Vector2 last_motion; + Vector2 previous_position; + Vector2 real_velocity; + RID platform_rid; bool on_floor = false; bool on_ceiling = false; @@ -395,6 +411,9 @@ private: void set_motion_mode(MotionMode p_mode); MotionMode get_motion_mode() const; + void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity); + MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const; + void _move_and_slide_free(double p_delta); void _move_and_slide_grounded(double p_delta, bool p_was_on_floor, const Vector2 &p_prev_platform_velocity); @@ -414,6 +433,7 @@ protected: }; VARIANT_ENUM_CAST(CharacterBody2D::MotionMode); +VARIANT_ENUM_CAST(CharacterBody2D::MovingPlatformApplyVelocityOnLeave); class KinematicCollision2D : public RefCounted { GDCLASS(KinematicCollision2D, RefCounted); @@ -439,7 +459,6 @@ public: Object *get_collider_shape() const; int get_collider_shape_index() const; Vector2 get_collider_velocity() const; - Variant get_collider_metadata() const; }; #endif // PHYSICS_BODY_2D_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 929233e4e0..222ec986b0 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -51,8 +51,8 @@ void TileMapPattern::remove_cell(const Vector2i &p_coords, bool p_update_size) { pattern.erase(p_coords); if (p_update_size) { size = Vector2i(); - for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) { - size = size.max(E->key() + Vector2i(1, 1)); + for (const KeyValue<Vector2i, TileMapCell> &E : pattern) { + size = size.max(E.key + Vector2i(1, 1)); } } } @@ -80,8 +80,8 @@ TypedArray<Vector2i> TileMapPattern::get_used_cells() const { TypedArray<Vector2i> a; a.resize(pattern.size()); int i = 0; - for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) { - Vector2i p(E->key().x, E->key().y); + for (const KeyValue<Vector2i, TileMapCell> &E : pattern) { + Vector2i p(E.key.x, E.key.y); a[i++] = p; } @@ -93,8 +93,8 @@ Vector2i TileMapPattern::get_size() const { } void TileMapPattern::set_size(const Vector2i &p_size) { - for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) { - Vector2i coords = E->key(); + for (const KeyValue<Vector2i, TileMapCell> &E : pattern) { + Vector2i coords = E.key; if (p_size.x <= coords.x || p_size.y <= coords.y) { ERR_FAIL_MSG(vformat("Cannot set pattern size to %s, it contains a tile at %s. Size can only be increased.", p_size, coords)); }; @@ -452,6 +452,19 @@ int TileMap::get_layer_z_index(int p_layer) const { return layers[p_layer].z_index; } +void TileMap::set_collision_animatable(bool p_enabled) { + collision_animatable = p_enabled; + _clear_internals(); + set_notify_local_transform(p_enabled); + set_physics_process_internal(p_enabled); + _recreate_internals(); + emit_signal(SNAME("changed")); +} + +bool TileMap::is_collision_animatable() const { + return collision_animatable; +} + void TileMap::set_collision_visibility_mode(TileMap::VisibilityMode p_show_collision) { collision_visibility_mode = p_show_collision; _clear_internals(); @@ -508,7 +521,6 @@ Map<Vector2i, TileMapQuadrant>::Element *TileMap::_create_quadrant(int p_layer, // Call the create_quadrant method on plugins if (tile_set.is_valid()) { _rendering_create_quadrant(&q); - _physics_create_quadrant(&q); } return layers[p_layer].quadrant_map.insert(p_qk, q); @@ -526,9 +538,9 @@ void TileMap::_make_quadrant_dirty(Map<Vector2i, TileMapQuadrant>::Element *Q) { void TileMap::_make_all_quadrants_dirty() { // Make all quandrants dirty, then trigger an update later. for (unsigned int layer = 0; layer < layers.size(); layer++) { - for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { - if (!E->value().dirty_list_element.in_list()) { - layers[layer].dirty_quadrant_list.add(&E->value().dirty_list_element); + for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { + if (!E.value.dirty_list_element.in_list()) { + layers[layer].dirty_quadrant_list.add(&E.value.dirty_list_element); } } } @@ -610,8 +622,8 @@ void TileMap::_recreate_internals() { // Recreate the quadrants. const Map<Vector2i, TileMapCell> &tile_map = layers[layer].tile_map; - for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) { - Vector2i qk = _coords_to_quadrant_coords(layer, Vector2i(E->key().x, E->key().y)); + for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) { + Vector2i qk = _coords_to_quadrant_coords(layer, Vector2i(E.key.x, E.key.y)); Map<Vector2i, TileMapQuadrant>::Element *Q = layers[layer].quadrant_map.find(qk); if (!Q) { @@ -619,7 +631,7 @@ void TileMap::_recreate_internals() { layers[layer].dirty_quadrant_list.add(&Q->get().dirty_list_element); } - Vector2i pk = E->key(); + Vector2i pk = E.key; Q->get().cells.insert(pk); _make_quadrant_dirty(Q); @@ -688,7 +700,7 @@ void TileMap::_recompute_rect_cache() { Rect2 r_total; for (unsigned int layer = 0; layer < layers.size(); layer++) { - for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { + for (const Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { Rect2 r; r.position = map_to_world(E->key() * get_effective_quadrant_size(layer)); r.expand_to(map_to_world((E->key() + Vector2i(1, 0)) * get_effective_quadrant_size(layer))); @@ -717,13 +729,13 @@ void TileMap::_rendering_notification(int p_what) { case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: { bool visible = is_visible_in_tree(); for (int layer = 0; layer < (int)layers.size(); layer++) { - for (Map<Vector2i, TileMapQuadrant>::Element *E_quadrant = layers[layer].quadrant_map.front(); E_quadrant; E_quadrant = E_quadrant->next()) { - TileMapQuadrant &q = E_quadrant->get(); + for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) { + TileMapQuadrant &q = E_quadrant.value; // Update occluders transform. - for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E_cell = q.world_to_map.front(); E_cell; E_cell = E_cell->next()) { + for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { Transform2D xform; - xform.set_origin(E_cell->key()); + xform.set_origin(E_cell.key); for (const RID &occluder : q.occluders) { RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, visible); } @@ -736,13 +748,13 @@ void TileMap::_rendering_notification(int p_what) { return; } for (int layer = 0; layer < (int)layers.size(); layer++) { - for (Map<Vector2i, TileMapQuadrant>::Element *E_quadrant = layers[layer].quadrant_map.front(); E_quadrant; E_quadrant = E_quadrant->next()) { - TileMapQuadrant &q = E_quadrant->get(); + for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) { + TileMapQuadrant &q = E_quadrant.value; // Update occluders transform. - for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E_cell = q.world_to_map.front(); E_cell; E_cell = E_cell->next()) { + for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { Transform2D xform; - xform.set_origin(E_cell->key()); + xform.set_origin(E_cell.key); for (const RID &occluder : q.occluders) { RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform() * xform); } @@ -821,8 +833,8 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List RID prev_canvas_item; // Iterate over the cells of the quadrant. - for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E_cell = q.world_to_map.front(); E_cell; E_cell = E_cell->next()) { - TileMapCell c = get_cell(q.layer, E_cell->value(), true); + for (const KeyValue<Vector2i, Vector2i> &E_cell : q.world_to_map) { + TileMapCell c = get_cell(q.layer, E_cell.value, true); TileSetSource *source; if (tile_set->has_source(c.source_id)) { @@ -891,12 +903,12 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List modulate.a *= 0.3; } } - draw_tile(canvas_item, E_cell->key() - position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, modulate); + draw_tile(canvas_item, E_cell.key - position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, modulate); // --- Occluders --- for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) { Transform2D xform; - xform.set_origin(E_cell->key()); + xform.set_origin(E_cell.key); if (tile_data->get_occluder(i).is_valid()) { RID occluder_id = rs->canvas_light_occluder_create(); rs->canvas_light_occluder_set_enabled(occluder_id, visible); @@ -922,13 +934,13 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List for (int layer = 0; layer < (int)layers.size(); layer++) { // Sort the quadrants coords per world coordinates Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator> world_to_map; - for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { - world_to_map[map_to_world(E->key())] = E->key(); + for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { + world_to_map[map_to_world(E.key)] = E.key; } // Sort the quadrants - for (Map<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator>::Element *E = world_to_map.front(); E; E = E->next()) { - TileMapQuadrant &q = layers[layer].quadrant_map[E->value()]; + for (const KeyValue<Vector2i, Vector2i> &E : world_to_map) { + TileMapQuadrant &q = layers[layer].quadrant_map[E.value]; for (const RID &ci : q.canvas_items) { RS::get_singleton()->canvas_item_set_draw_index(ci, index++); } @@ -1092,24 +1104,67 @@ void TileMap::draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSe void TileMap::_physics_notification(int p_what) { switch (p_what) { + case CanvasItem::NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + bool in_editor = false; +#ifdef TOOLS_ENABLED + in_editor = Engine::get_singleton()->is_editor_hint(); +#endif + if (is_inside_tree() && collision_animatable && !in_editor) { + // Update tranform on the physics tick when in animatable mode. + last_valid_transform = new_transform; + set_notify_local_transform(false); + set_global_transform(new_transform); + set_notify_local_transform(true); + } + } break; case CanvasItem::NOTIFICATION_TRANSFORM_CHANGED: { - // Update the bodies transforms. - if (is_inside_tree()) { + bool in_editor = false; +#ifdef TOOLS_ENABLED + in_editor = Engine::get_singleton()->is_editor_hint(); +#endif + if (is_inside_tree() && (!collision_animatable || in_editor)) { + // Update the new transform directly if we are not in animatable mode. + Transform2D global_transform = get_global_transform(); for (int layer = 0; layer < (int)layers.size(); layer++) { - Transform2D global_transform = get_global_transform(); + for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { + TileMapQuadrant &q = E.value; - for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { - TileMapQuadrant &q = E->get(); + for (RID body : q.bodies) { + Transform2D xform; + xform.set_origin(map_to_world(bodies_coords[body])); + xform = global_transform * xform; + PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); + } + } + } + } + } break; + case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { + bool in_editor = false; +#ifdef TOOLS_ENABLED + in_editor = Engine::get_singleton()->is_editor_hint(); +#endif + if (is_inside_tree() && !in_editor && collision_animatable) { + // Only active when animatable. Send the new transform to the physics... + new_transform = get_global_transform(); + for (int layer = 0; layer < (int)layers.size(); layer++) { + for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { + TileMapQuadrant &q = E.value; - Transform2D xform; - xform.set_origin(map_to_world(E->key() * get_effective_quadrant_size(layer))); - xform = global_transform * xform; + for (RID body : q.bodies) { + Transform2D xform; + xform.set_origin(map_to_world(bodies_coords[body])); + xform = new_transform * xform; - for (int body_index = 0; body_index < q.bodies.size(); body_index++) { - PhysicsServer2D::get_singleton()->body_set_state(q.bodies[body_index], PhysicsServer2D::BODY_STATE_TRANSFORM, xform); + PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); } } } + + // ... but then revert changes. + set_notify_local_transform(false); + set_global_transform(last_valid_transform); + set_notify_local_transform(true); } } break; } @@ -1120,29 +1175,23 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r ERR_FAIL_COND(!tile_set.is_valid()); Transform2D global_transform = get_global_transform(); + last_valid_transform = global_transform; + new_transform = global_transform; PhysicsServer2D *ps = PhysicsServer2D::get_singleton(); + RID space = get_world_2d()->get_space(); SelfList<TileMapQuadrant> *q_list_element = r_dirty_quadrant_list.first(); while (q_list_element) { TileMapQuadrant &q = *q_list_element->self(); - Vector2 quadrant_pos = map_to_world(q.coords * get_effective_quadrant_size(q.layer)); - - LocalVector<int> body_shape_count; - body_shape_count.resize(q.bodies.size()); - - // Clear shapes. - for (int body_index = 0; body_index < q.bodies.size(); body_index++) { - ps->body_clear_shapes(q.bodies[body_index]); - body_shape_count[body_index] = 0; - - // Position the bodies. - Transform2D xform; - xform.set_origin(quadrant_pos); - xform = global_transform * xform; - ps->body_set_state(q.bodies[body_index], PhysicsServer2D::BODY_STATE_TRANSFORM, xform); + // Clear bodies. + for (RID body : q.bodies) { + bodies_coords.erase(body); + ps->free(body); } + q.bodies.clear(); + // Recreate bodies and shapes. for (Set<Vector2i>::Element *E_cell = q.cells.front(); E_cell; E_cell = E_cell->next()) { TileMapCell c = get_cell(q.layer, E_cell->get(), true); @@ -1158,26 +1207,53 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r if (atlas_source) { TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile)); - for (int body_index = 0; body_index < q.bodies.size(); body_index++) { - int &body_shape_index = body_shape_count[body_index]; + for (int tile_set_physics_layer = 0; tile_set_physics_layer < tile_set->get_physics_layers_count(); tile_set_physics_layer++) { + Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer); + uint32_t physics_layer = tile_set->get_physics_layer_collision_layer(tile_set_physics_layer); + uint32_t physics_mask = tile_set->get_physics_layer_collision_mask(tile_set_physics_layer); - // Add the shapes again. - for (int polygon_index = 0; polygon_index < tile_data->get_collision_polygons_count(body_index); polygon_index++) { - bool one_way_collision = tile_data->is_collision_polygon_one_way(body_index, polygon_index); - float one_way_collision_margin = tile_data->get_collision_polygon_one_way_margin(body_index, polygon_index); + // Create the body. + RID body = ps->body_create(); + bodies_coords[body] = E_cell->get(); + ps->body_set_mode(body, collision_animatable ? PhysicsServer2D::BODY_MODE_KINEMATIC : PhysicsServer2D::BODY_MODE_STATIC); + ps->body_set_space(body, space); - int shapes_count = tile_data->get_collision_polygon_shapes_count(body_index, polygon_index); - for (int shape_index = 0; shape_index < shapes_count; shape_index++) { - Transform2D xform = Transform2D(); - xform.set_origin(map_to_world(E_cell->get()) - quadrant_pos); + Transform2D xform; + xform.set_origin(map_to_world(E_cell->get())); + xform = global_transform * xform; + ps->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); + + ps->body_attach_object_instance_id(body, get_instance_id()); + ps->body_set_collision_layer(body, physics_layer); + ps->body_set_collision_mask(body, physics_mask); + ps->body_set_pickable(body, false); + ps->body_set_state(body, PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, tile_data->get_constant_linear_velocity(tile_set_physics_layer)); + ps->body_set_state(body, PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, tile_data->get_constant_angular_velocity(tile_set_physics_layer)); + + if (!physics_material.is_valid()) { + ps->body_set_param(body, PhysicsServer2D::BODY_PARAM_BOUNCE, 0); + ps->body_set_param(body, PhysicsServer2D::BODY_PARAM_FRICTION, 1); + } else { + ps->body_set_param(body, PhysicsServer2D::BODY_PARAM_BOUNCE, physics_material->computed_bounce()); + ps->body_set_param(body, PhysicsServer2D::BODY_PARAM_FRICTION, physics_material->computed_friction()); + } + + q.bodies.push_back(body); + // Add the shapes to the body. + int body_shape_index = 0; + for (int polygon_index = 0; polygon_index < tile_data->get_collision_polygons_count(tile_set_physics_layer); polygon_index++) { + // Iterate over the polygons. + bool one_way_collision = tile_data->is_collision_polygon_one_way(tile_set_physics_layer, polygon_index); + float one_way_collision_margin = tile_data->get_collision_polygon_one_way_margin(tile_set_physics_layer, polygon_index); + int shapes_count = tile_data->get_collision_polygon_shapes_count(tile_set_physics_layer, polygon_index); + for (int shape_index = 0; shape_index < shapes_count; shape_index++) { // Add decomposed convex shapes. - Ref<ConvexPolygonShape2D> shape = tile_data->get_collision_polygon_shape(body_index, polygon_index, shape_index); - ps->body_add_shape(q.bodies[body_index], shape->get_rid(), xform); - ps->body_set_shape_metadata(q.bodies[body_index], body_shape_index, E_cell->get()); - ps->body_set_shape_as_one_way_collision(q.bodies[body_index], body_shape_index, one_way_collision, one_way_collision_margin); + Ref<ConvexPolygonShape2D> shape = tile_data->get_collision_polygon_shape(tile_set_physics_layer, polygon_index, shape_index); + ps->body_add_shape(body, shape->get_rid()); + ps->body_set_shape_as_one_way_collision(body, body_shape_index, one_way_collision, one_way_collision_margin); - ++body_shape_index; + body_shape_index++; } } } @@ -1189,54 +1265,11 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r } } -void TileMap::_physics_create_quadrant(TileMapQuadrant *p_quadrant) { - ERR_FAIL_COND(!tile_set.is_valid()); - - //Get the TileMap's gobla transform. - Transform2D global_transform; - if (is_inside_tree()) { - global_transform = get_global_transform(); - } - - // Clear all bodies. - p_quadrant->bodies.clear(); - - // Create the body and set its parameters. - for (int layer = 0; layer < tile_set->get_physics_layers_count(); layer++) { - RID body = PhysicsServer2D::get_singleton()->body_create(); - PhysicsServer2D::get_singleton()->body_set_mode(body, PhysicsServer2D::BODY_MODE_STATIC); - - PhysicsServer2D::get_singleton()->body_attach_object_instance_id(body, get_instance_id()); - PhysicsServer2D::get_singleton()->body_set_collision_layer(body, tile_set->get_physics_layer_collision_layer(layer)); - PhysicsServer2D::get_singleton()->body_set_collision_mask(body, tile_set->get_physics_layer_collision_mask(layer)); - - Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(layer); - if (!physics_material.is_valid()) { - PhysicsServer2D::get_singleton()->body_set_param(body, PhysicsServer2D::BODY_PARAM_BOUNCE, 0); - PhysicsServer2D::get_singleton()->body_set_param(body, PhysicsServer2D::BODY_PARAM_FRICTION, 1); - } else { - PhysicsServer2D::get_singleton()->body_set_param(body, PhysicsServer2D::BODY_PARAM_BOUNCE, physics_material->computed_bounce()); - PhysicsServer2D::get_singleton()->body_set_param(body, PhysicsServer2D::BODY_PARAM_FRICTION, physics_material->computed_friction()); - } - - if (is_inside_tree()) { - RID space = get_world_2d()->get_space(); - PhysicsServer2D::get_singleton()->body_set_space(body, space); - - Transform2D xform; - xform.set_origin(map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer))); - xform = global_transform * xform; - PhysicsServer2D::get_singleton()->body_set_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform); - } - - p_quadrant->bodies.push_back(body); - } -} - void TileMap::_physics_cleanup_quadrant(TileMapQuadrant *p_quadrant) { // Remove a quadrant. - for (int body_index = 0; body_index < p_quadrant->bodies.size(); body_index++) { - PhysicsServer2D::get_singleton()->free(p_quadrant->bodies[body_index]); + for (RID body : p_quadrant->bodies) { + bodies_coords.erase(body); + PhysicsServer2D::get_singleton()->free(body); } p_quadrant->bodies.clear(); } @@ -1252,7 +1285,7 @@ void TileMap::_physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { bool show_collision = false; switch (collision_visibility_mode) { case TileMap::VISIBILITY_MODE_DEFAULT: - show_collision = !Engine::get_singleton()->is_editor_hint() && (get_tree() && get_tree()->is_debugging_navigation_hint()); + show_collision = !Engine::get_singleton()->is_editor_hint() && (get_tree() && get_tree()->is_debugging_collisions_hint()); break; case TileMap::VISIBILITY_MODE_FORCE_HIDE: show_collision = false; @@ -1266,39 +1299,28 @@ void TileMap::_physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant) { } RenderingServer *rs = RenderingServer::get_singleton(); - - Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); + PhysicsServer2D *ps = PhysicsServer2D::get_singleton(); Color debug_collision_color = get_tree()->get_debug_collisions_color(); - for (Set<Vector2i>::Element *E_cell = p_quadrant->cells.front(); E_cell; E_cell = E_cell->next()) { - TileMapCell c = get_cell(p_quadrant->layer, E_cell->get(), true); - - Transform2D xform; - xform.set_origin(map_to_world(E_cell->get()) - quadrant_pos); - rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); + Vector<Color> color; + color.push_back(debug_collision_color); - if (tile_set->has_source(c.source_id)) { - TileSetSource *source = *tile_set->get_source(c.source_id); - - if (!source->has_tile(c.get_atlas_coords()) || !source->has_alternative_tile(c.get_atlas_coords(), c.alternative_tile)) { - continue; - } - - TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source); - if (atlas_source) { - TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile)); + Vector2 quadrant_pos = map_to_world(p_quadrant->coords * get_effective_quadrant_size(p_quadrant->layer)); + Transform2D qudrant_xform; + qudrant_xform.set_origin(quadrant_pos); + Transform2D global_transform_inv = (get_global_transform() * qudrant_xform).affine_inverse(); - for (int body_index = 0; body_index < p_quadrant->bodies.size(); body_index++) { - for (int polygon_index = 0; polygon_index < tile_data->get_collision_polygons_count(body_index); polygon_index++) { - // Draw the debug polygon. - Vector<Vector2> polygon = tile_data->get_collision_polygon_points(body_index, polygon_index); - if (polygon.size() >= 3) { - Vector<Color> color; - color.push_back(debug_collision_color); - rs->canvas_item_add_polygon(p_quadrant->debug_canvas_item, polygon, color); - } - } - } + for (RID body : p_quadrant->bodies) { + Transform2D xform = Transform2D(ps->body_get_state(body, PhysicsServer2D::BODY_STATE_TRANSFORM)) * global_transform_inv; + rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, xform); + for (int shape_index = 0; shape_index < ps->body_get_shape_count(body); shape_index++) { + const RID &shape = ps->body_get_shape(body, shape_index); + PhysicsServer2D::ShapeType type = ps->shape_get_type(shape); + if (type == PhysicsServer2D::SHAPE_CONVEX_POLYGON) { + Vector<Vector2> polygon = ps->shape_get_data(shape); + rs->canvas_item_add_polygon(p_quadrant->debug_canvas_item, polygon, color); + } else { + WARN_PRINT("Wrong shape type for a tile, should be SHAPE_CONVEX_POLYGON."); } } rs->canvas_item_add_set_transform(p_quadrant->debug_canvas_item, Transform2D()); @@ -1313,16 +1335,16 @@ void TileMap::_navigation_notification(int p_what) { if (is_inside_tree()) { for (int layer = 0; layer < (int)layers.size(); layer++) { Transform2D tilemap_xform = get_global_transform(); - for (Map<Vector2i, TileMapQuadrant>::Element *E_quadrant = layers[layer].quadrant_map.front(); E_quadrant; E_quadrant = E_quadrant->next()) { - TileMapQuadrant &q = E_quadrant->get(); - for (Map<Vector2i, Vector<RID>>::Element *E_region = q.navigation_regions.front(); E_region; E_region = E_region->next()) { - for (int layer_index = 0; layer_index < E_region->get().size(); layer_index++) { - RID region = E_region->get()[layer_index]; + for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) { + TileMapQuadrant &q = E_quadrant.value; + for (const KeyValue<Vector2i, Vector<RID>> &E_region : q.navigation_regions) { + for (int layer_index = 0; layer_index < E_region.value.size(); layer_index++) { + RID region = E_region.value[layer_index]; if (!region.is_valid()) { continue; } Transform2D tile_transform; - tile_transform.set_origin(map_to_world(E_region->key())); + tile_transform.set_origin(map_to_world(E_region.key)); NavigationServer2D::get_singleton()->region_set_transform(region, tilemap_xform * tile_transform); } } @@ -1351,9 +1373,9 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List TileMapQuadrant &q = *q_list_element->self(); // Clear navigation shapes in the quadrant. - for (Map<Vector2i, Vector<RID>>::Element *E = q.navigation_regions.front(); E; E = E->next()) { - for (int i = 0; i < E->get().size(); i++) { - RID region = E->get()[i]; + for (const KeyValue<Vector2i, Vector<RID>> &E : q.navigation_regions) { + for (int i = 0; i < E.value.size(); i++) { + RID region = E.value[i]; if (!region.is_valid()) { continue; } @@ -1404,9 +1426,9 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List void TileMap::_navigation_cleanup_quadrant(TileMapQuadrant *p_quadrant) { // Clear navigation shapes in the quadrant. - for (Map<Vector2i, Vector<RID>>::Element *E = p_quadrant->navigation_regions.front(); E; E = E->next()) { - for (int i = 0; i < E->get().size(); i++) { - RID region = E->get()[i]; + for (const KeyValue<Vector2i, Vector<RID>> &E : p_quadrant->navigation_regions) { + for (int i = 0; i < E.value.size(); i++) { + RID region = E.value[i]; if (!region.is_valid()) { continue; } @@ -1507,8 +1529,8 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_ TileMapQuadrant &q = *q_list_element->self(); // Clear the scenes. - for (Map<Vector2i, String>::Element *E = q.scenes.front(); E; E = E->next()) { - Node *node = get_node(E->get()); + for (const KeyValue<Vector2i, String> &E : q.scenes) { + Node *node = get_node(E.value); if (node) { node->queue_delete(); } @@ -1555,8 +1577,8 @@ void TileMap::_scenes_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_ void TileMap::_scenes_cleanup_quadrant(TileMapQuadrant *p_quadrant) { // Clear the scenes. - for (Map<Vector2i, String>::Element *E = p_quadrant->scenes.front(); E; E = E->next()) { - Node *node = get_node(E->get()); + for (const KeyValue<Vector2i, String> &E : p_quadrant->scenes) { + Node *node = get_node(E.value); if (node) { node->queue_delete(); } @@ -1858,16 +1880,21 @@ Map<Vector2i, TileMapQuadrant> *TileMap::get_quadrant_map(int p_layer) { return &layers[p_layer].quadrant_map; } +Vector2i TileMap::get_coords_for_body_rid(RID p_physics_body) { + ERR_FAIL_COND_V_MSG(!bodies_coords.has(p_physics_body), Vector2i(), vformat("No tiles for the given body RID %d.", p_physics_body)); + return bodies_coords[p_physics_body]; +} + void TileMap::fix_invalid_tiles() { ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open."); for (unsigned int i = 0; i < layers.size(); i++) { const Map<Vector2i, TileMapCell> &tile_map = layers[i].tile_map; Set<Vector2i> coords; - for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) { - TileSetSource *source = *tile_set->get_source(E->get().source_id); - if (!source || !source->has_tile(E->get().get_atlas_coords()) || !source->has_alternative_tile(E->get().get_atlas_coords(), E->get().alternative_tile)) { - coords.insert(E->key()); + for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) { + TileSetSource *source = *tile_set->get_source(E.value.source_id); + if (!source || !source->has_tile(E.value.get_atlas_coords()) || !source->has_alternative_tile(E.value.get_atlas_coords(), E.value.alternative_tile)) { + coords.insert(E.key); } } for (Set<Vector2i>::Element *E = coords.front(); E; E = E->next()) { @@ -1990,14 +2017,14 @@ Vector<int> TileMap::_get_tile_data(int p_layer) const { // Save in highest format int idx = 0; - for (const Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) { + for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) { uint8_t *ptr = (uint8_t *)&w[idx]; - encode_uint16((int16_t)(E->key().x), &ptr[0]); - encode_uint16((int16_t)(E->key().y), &ptr[2]); - encode_uint16(E->get().source_id, &ptr[4]); - encode_uint16(E->get().coord_x, &ptr[6]); - encode_uint16(E->get().coord_y, &ptr[8]); - encode_uint16(E->get().alternative_tile, &ptr[10]); + encode_uint16((int16_t)(E.key.x), &ptr[0]); + encode_uint16((int16_t)(E.key.y), &ptr[2]); + encode_uint16(E.value.source_id, &ptr[4]); + encode_uint16(E.value.coord_x, &ptr[6]); + encode_uint16(E.value.coord_y, &ptr[8]); + encode_uint16(E.value.alternative_tile, &ptr[10]); idx += 3; } @@ -2751,8 +2778,8 @@ TypedArray<Vector2i> TileMap::get_used_cells(int p_layer) const { TypedArray<Vector2i> a; a.resize(layers[p_layer].tile_map.size()); int i = 0; - for (Map<Vector2i, TileMapCell>::Element *E = layers[p_layer].tile_map.front(); E; E = E->next()) { - Vector2i p(E->key().x, E->key().y); + for (const KeyValue<Vector2i, TileMapCell> &E : layers[p_layer].tile_map) { + Vector2i p(E.key.x, E.key.y); a[i++] = p; } @@ -2773,8 +2800,8 @@ Rect2 TileMap::get_used_rect() { // Not const because of cache first = false; } - for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) { - used_rect_cache.expand_to(Vector2i(E->key().x, E->key().y)); + for (const KeyValue<Vector2i, TileMapCell> &E : tile_map) { + used_rect_cache.expand_to(Vector2i(E.key.x, E.key.y)); } } } @@ -2794,8 +2821,8 @@ void TileMap::set_light_mask(int p_light_mask) { // Occlusion: set light mask. CanvasItem::set_light_mask(p_light_mask); for (unsigned int layer = 0; layer < layers.size(); layer++) { - for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { - for (const RID &ci : E->get().canvas_items) { + for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { + for (const RID &ci : E.value.canvas_items) { RenderingServer::get_singleton()->canvas_item_set_light_mask(ci, get_light_mask()); } } @@ -2809,8 +2836,8 @@ void TileMap::set_material(const Ref<Material> &p_material) { // Update material for the whole tilemap. for (unsigned int layer = 0; layer < layers.size(); layer++) { - for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { - TileMapQuadrant &q = E->get(); + for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { + TileMapQuadrant &q = E.value; for (const RID &ci : q.canvas_items) { RS::get_singleton()->canvas_item_set_use_parent_material(ci, get_use_parent_material() || get_material().is_valid()); } @@ -2825,8 +2852,8 @@ void TileMap::set_use_parent_material(bool p_use_parent_material) { // Update use_parent_material for the whole tilemap. for (unsigned int layer = 0; layer < layers.size(); layer++) { - for (Map<Vector2i, TileMapQuadrant>::Element *E = layers[layer].quadrant_map.front(); E; E = E->next()) { - TileMapQuadrant &q = E->get(); + for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) { + TileMapQuadrant &q = E.value; for (const RID &ci : q.canvas_items) { RS::get_singleton()->canvas_item_set_use_parent_material(ci, get_use_parent_material() || get_material().is_valid()); } @@ -3007,6 +3034,8 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_layer_z_index", "layer", "z_index"), &TileMap::set_layer_z_index); ClassDB::bind_method(D_METHOD("get_layer_z_index", "layer"), &TileMap::get_layer_z_index); + ClassDB::bind_method(D_METHOD("set_collision_animatable", "enabled"), &TileMap::set_collision_animatable); + ClassDB::bind_method(D_METHOD("is_collision_animatable"), &TileMap::is_collision_animatable); ClassDB::bind_method(D_METHOD("set_collision_visibility_mode", "collision_visibility_mode"), &TileMap::set_collision_visibility_mode); ClassDB::bind_method(D_METHOD("get_collision_visibility_mode"), &TileMap::get_collision_visibility_mode); @@ -3018,10 +3047,14 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "layer", "coords", "use_proxies"), &TileMap::get_cell_atlas_coords); ClassDB::bind_method(D_METHOD("get_cell_alternative_tile", "layer", "coords", "use_proxies"), &TileMap::get_cell_alternative_tile); + ClassDB::bind_method(D_METHOD("get_coords_for_body_rid", "body"), &TileMap::get_coords_for_body_rid); + ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles); - ClassDB::bind_method(D_METHOD("get_surrounding_tiles", "coords"), &TileMap::get_surrounding_tiles); + ClassDB::bind_method(D_METHOD("clear_layer", "layer"), &TileMap::clear_layer); ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear); + ClassDB::bind_method(D_METHOD("get_surrounding_tiles", "coords"), &TileMap::get_surrounding_tiles); + ClassDB::bind_method(D_METHOD("get_used_cells", "layer"), &TileMap::get_used_cells); ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect); @@ -3037,6 +3070,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tile_set", PROPERTY_HINT_RESOURCE_TYPE, "TileSet"), "set_tileset", "get_tileset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_quadrant_size", "get_quadrant_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_animatable"), "set_collision_animatable", "is_collision_animatable"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_visibility_mode", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode"); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index ca38baa550..2faede2445 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -202,6 +202,7 @@ private: // Properties. Ref<TileSet> tile_set; int quadrant_size = 16; + bool collision_animatable = false; VisibilityMode collision_visibility_mode = VISIBILITY_MODE_DEFAULT; VisibilityMode navigation_visibility_mode = VISIBILITY_MODE_DEFAULT; @@ -229,6 +230,9 @@ private: LocalVector<TileMapLayer> layers; int selected_layer = -1; + // Mapping for RID to coords. + Map<RID, Vector2i> bodies_coords; + // Quadrants and internals management. Vector2i _coords_to_quadrant_coords(int p_layer, const Vector2i &p_coords) const; @@ -259,9 +263,10 @@ private: void _rendering_cleanup_quadrant(TileMapQuadrant *p_quadrant); void _rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant); + Transform2D last_valid_transform; + Transform2D new_transform; void _physics_notification(int p_what); void _physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list); - void _physics_create_quadrant(TileMapQuadrant *p_quadrant); void _physics_cleanup_quadrant(TileMapQuadrant *p_quadrant); void _physics_draw_quadrant_debug(TileMapQuadrant *p_quadrant); @@ -325,6 +330,9 @@ public: void set_selected_layer(int p_layer_id); // For editor use. int get_selected_layer() const; + void set_collision_animatable(bool p_enabled); + bool is_collision_animatable() const; + void set_collision_visibility_mode(VisibilityMode p_show_collision); VisibilityMode get_collision_visibility_mode(); @@ -364,6 +372,9 @@ public: virtual void set_texture_filter(CanvasItem::TextureFilter p_texture_filter) override; virtual void set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) override; + // For finding tiles from collision. + Vector2i get_coords_for_body_rid(RID p_physics_body); + // Fixing a nclearing methods. void fix_invalid_tiles(); diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 943586f43c..7e4c40ca0e 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -262,8 +262,8 @@ void Area3D::_clear_monitoring() { body_map.clear(); //disconnect all monitored stuff - for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, BodyState> &E : bmcopy) { + Object *obj = ObjectDB::get_instance(E.key); Node *node = Object::cast_to<Node>(obj); if (!node) { //node may have been deleted in previous frame or at other legitimate point @@ -274,12 +274,12 @@ void Area3D::_clear_monitoring() { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree)); - if (!E->get().in_tree) { + if (!E.value.in_tree) { continue; } - for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->get().rid, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape); + for (int i = 0; i < E.value.shapes.size(); i++) { + emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E.value.rid, node, E.value.shapes[i].body_shape, E.value.shapes[i].area_shape); } emit_signal(SceneStringNames::get_singleton()->body_exited, node); @@ -291,8 +291,8 @@ void Area3D::_clear_monitoring() { area_map.clear(); //disconnect all monitored stuff - for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, AreaState> &E : bmcopy) { + Object *obj = ObjectDB::get_instance(E.key); Node *node = Object::cast_to<Node>(obj); if (!node) { //node may have been deleted in previous frame or at other legitimate point @@ -303,12 +303,12 @@ void Area3D::_clear_monitoring() { node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree)); node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree)); - if (!E->get().in_tree) { + if (!E.value.in_tree) { continue; } - for (int i = 0; i < E->get().shapes.size(); i++) { - emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->get().rid, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape); + for (int i = 0; i < E.value.shapes.size(); i++) { + emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E.value.rid, node, E.value.shapes[i].area_shape, E.value.shapes[i].self_shape); } emit_signal(SceneStringNames::get_singleton()->area_exited, obj); @@ -446,8 +446,8 @@ TypedArray<Node3D> Area3D::get_overlapping_bodies() const { Array ret; ret.resize(body_map.size()); int idx = 0; - for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, BodyState> &E : body_map) { + Object *obj = ObjectDB::get_instance(E.key); if (!obj) { ret.resize(ret.size() - 1); //ops } else { @@ -479,8 +479,8 @@ TypedArray<Area3D> Area3D::get_overlapping_areas() const { Array ret; ret.resize(area_map.size()); int idx = 0; - for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, AreaState> &E : area_map) { + Object *obj = ObjectDB::get_instance(E.key); if (!obj) { ret.resize(ret.size() - 1); //ops } else { diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index e2f953974a..814ed5c2a7 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -37,8 +37,8 @@ void CollisionObject3D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (_are_collision_shapes_visible()) { debug_shape_old_transform = get_global_transform(); - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - debug_shapes_to_update.insert(E->key()); + for (const KeyValue<uint32_t, ShapeData> &E : shapes) { + debug_shapes_to_update.insert(E.key); } _update_debug_shapes(); } @@ -324,8 +324,8 @@ void CollisionObject3D::_update_shape_data(uint32_t p_owner) { } void CollisionObject3D::_shape_changed(const Ref<Shape3D> &p_shape) { - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - ShapeData &shapedata = E->get(); + for (KeyValue<uint32_t, ShapeData> &E : shapes) { + ShapeData &shapedata = E.value; ShapeData::ShapeBase *shapes = shapedata.shapes.ptrw(); for (int i = 0; i < shapedata.shapes.size(); i++) { ShapeData::ShapeBase &s = shapes[i]; @@ -380,8 +380,8 @@ void CollisionObject3D::_update_debug_shapes() { } void CollisionObject3D::_clear_debug_shapes() { - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - ShapeData &shapedata = E->get(); + for (KeyValue<uint32_t, ShapeData> &E : shapes) { + ShapeData &shapedata = E.value; ShapeData::ShapeBase *shapes = shapedata.shapes.ptrw(); for (int i = 0; i < shapedata.shapes.size(); i++) { ShapeData::ShapeBase &s = shapes[i]; @@ -400,8 +400,8 @@ void CollisionObject3D::_clear_debug_shapes() { void CollisionObject3D::_on_transform_changed() { if (debug_shapes_count > 0 && !debug_shape_old_transform.is_equal_approx(get_global_transform())) { debug_shape_old_transform = get_global_transform(); - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - ShapeData &shapedata = E->get(); + for (KeyValue<uint32_t, ShapeData> &E : shapes) { + ShapeData &shapedata = E.value; const ShapeData::ShapeBase *shapes = shapedata.shapes.ptr(); for (int i = 0; i < shapedata.shapes.size(); i++) { RS::get_singleton()->instance_set_transform(shapes[i].debug_shape, debug_shape_old_transform * shapedata.xform); @@ -523,15 +523,15 @@ bool CollisionObject3D::is_shape_owner_disabled(uint32_t p_owner) const { } void CollisionObject3D::get_shape_owners(List<uint32_t> *r_owners) { - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - r_owners->push_back(E->key()); + for (const KeyValue<uint32_t, ShapeData> &E : shapes) { + r_owners->push_back(E.key); } } Array CollisionObject3D::_get_shape_owners() { Array ret; - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<uint32_t, ShapeData> &E : shapes) { + ret.push_back(E.key); } return ret; @@ -628,10 +628,10 @@ void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) shapes[p_owner].shapes.remove(p_shape); - for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (E->get().shapes[i].index > index_to_remove) { - E->get().shapes.write[i].index -= 1; + for (KeyValue<uint32_t, ShapeData> &E : shapes) { + for (int i = 0; i < E.value.shapes.size(); i++) { + if (E.value.shapes[i].index > index_to_remove) { + E.value.shapes.write[i].index -= 1; } } } @@ -650,10 +650,10 @@ void CollisionObject3D::shape_owner_clear_shapes(uint32_t p_owner) { uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0); - for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (E->get().shapes[i].index == p_shape_index) { - return E->key(); + for (const KeyValue<uint32_t, ShapeData> &E : shapes) { + for (int i = 0; i < E.value.shapes.size(); i++) { + if (E.value.shapes[i].index == p_shape_index) { + return E.key; } } } diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/joint_3d.cpp index 12938946a0..aa5ca85bdf 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/joint_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* physics_joint_3d.cpp */ +/* joint_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "physics_joint_3d.h" +#include "joint_3d.h" #include "scene/scene_string_names.h" diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/joint_3d.h index 3e0ea38a5c..211cf8e071 100644 --- a/scene/3d/physics_joint_3d.h +++ b/scene/3d/joint_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* physics_joint_3d.h */ +/* joint_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICS_JOINT_H -#define PHYSICS_JOINT_H +#ifndef JOINT_3D_H +#define JOINT_3D_H #include "scene/3d/node_3d.h" #include "scene/3d/physics_body_3d.h" @@ -334,4 +334,4 @@ public: VARIANT_ENUM_CAST(Generic6DOFJoint3D::Param); VARIANT_ENUM_CAST(Generic6DOFJoint3D::Flag); -#endif // PHYSICS_JOINT_H +#endif // JOINT_3D_H diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 7e7db57af3..67f4a88228 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -86,8 +86,8 @@ bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const { void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { List<String> ls; - for (const Map<StringName, BlendShapeTrack>::Element *E = blend_shape_tracks.front(); E; E = E->next()) { - ls.push_back(E->key()); + for (const KeyValue<StringName, BlendShapeTrack> &E : blend_shape_tracks) { + ls.push_back(E.key); } ls.sort(); @@ -369,6 +369,8 @@ void MeshInstance3D::create_debug_tangents() { for (int i = 0; i < mesh->get_surface_count(); i++) { Array arrays = mesh->surface_get_arrays(i); + ERR_CONTINUE(arrays.size() != Mesh::ARRAY_MAX); + Vector<Vector3> verts = arrays[Mesh::ARRAY_VERTEX]; Vector<Vector3> norms = arrays[Mesh::ARRAY_NORMAL]; if (norms.size() == 0) { diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index bbf2c81a92..fc0df3650f 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -33,10 +33,6 @@ #include "core/core_string_names.h" #include "scene/scene_string_names.h" -#ifdef TOOLS_ENABLED -#include "editor/plugins/node_3d_editor_plugin.h" -#endif - void PhysicsBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "linear_velocity", "test_only", "safe_margin", "max_collisions"), &PhysicsBody3D::_move, DEFVAL(false), DEFVAL(0.001), DEFVAL(1)); ClassDB::bind_method(D_METHOD("test_move", "from", "linear_velocity", "collision", "safe_margin", "max_collisions"), &PhysicsBody3D::test_move, DEFVAL(Variant()), DEFVAL(0.001), DEFVAL(1)); @@ -340,6 +336,12 @@ void AnimatableBody3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { last_valid_transform = get_global_transform(); + _update_kinematic_motion(); + } break; + + case NOTIFICATION_EXIT_TREE: { + set_only_update_transform_changes(false); + set_notify_local_transform(false); } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { @@ -367,8 +369,6 @@ void AnimatableBody3D::_bind_methods() { AnimatableBody3D::AnimatableBody3D() : StaticBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) { PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback); - - _update_kinematic_motion(); } void RigidDynamicBody3D::_body_enter_tree(ObjectID p_id) { @@ -512,9 +512,9 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) //untag all int rc = 0; - for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - E->get().shapes[i].tagged = false; + for (KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { + for (int i = 0; i < E.value.shapes.size(); i++) { + E.value.shapes[i].tagged = false; rc++; } } @@ -560,12 +560,12 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) //put the ones to remove - for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - for (int i = 0; i < E->get().shapes.size(); i++) { - if (!E->get().shapes[i].tagged) { - toremove[toremove_count].rid = E->get().rid; - toremove[toremove_count].body_id = E->key(); - toremove[toremove_count].pair = E->get().shapes[i]; + for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { + for (int i = 0; i < E.value.shapes.size(); i++) { + if (!E.value.shapes[i].tagged) { + toremove[toremove_count].rid = E.value.rid; + toremove[toremove_count].body_id = E.key; + toremove[toremove_count].pair = E.value.shapes[i]; toremove_count++; } } @@ -885,9 +885,9 @@ void RigidDynamicBody3D::set_contact_monitor(bool p_enabled) { if (!p_enabled) { ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead."); - for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { + for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { //clean up mess - Object *obj = ObjectDB::get_instance(E->key()); + Object *obj = ObjectDB::get_instance(E.key); Node *node = Object::cast_to<Node>(obj); if (node) { @@ -914,8 +914,8 @@ Array RigidDynamicBody3D::get_colliding_bodies() const { Array ret; ret.resize(contact_monitor->body_map.size()); int idx = 0; - for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); + for (const KeyValue<ObjectID, BodyState> &E : contact_monitor->body_map) { + Object *obj = ObjectDB::get_instance(E.key); if (!obj) { ret.resize(ret.size() - 1); //ops } else { @@ -1085,13 +1085,16 @@ void RigidDynamicBody3D::_reload_physics_characteristics() { bool CharacterBody3D::move_and_slide() { // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); - previous_position = get_global_transform().origin; + for (int i = 0; i < 3; i++) { if (locked_axis & (1 << i)) { - linear_velocity[i] = 0.0; + motion_velocity[i] = 0.0; } } + Transform3D gt = get_global_transform(); + previous_position = gt.origin; + Vector3 current_platform_velocity = platform_velocity; if ((collision_state.floor || collision_state.wall) && platform_rid.is_valid()) { @@ -1105,7 +1108,6 @@ bool CharacterBody3D::move_and_slide() { //this approach makes sure there is less delay between the actual body velocity and the one we saved PhysicsDirectBodyState3D *bs = PhysicsServer3D::get_singleton()->body_get_direct_state(platform_rid); if (bs) { - Transform3D gt = get_global_transform(); Vector3 local_position = gt.origin - bs->get_transform().origin; current_platform_velocity = bs->get_velocity_at_local_position(local_position); } @@ -1119,6 +1121,8 @@ bool CharacterBody3D::move_and_slide() { bool was_on_floor = collision_state.floor; collision_state.state = 0; + last_motion = Vector3(); + if (!current_platform_velocity.is_equal_approx(Vector3())) { PhysicsServer3D::MotionResult floor_result; Set<RID> exclude; @@ -1146,40 +1150,40 @@ bool CharacterBody3D::move_and_slide() { if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) { current_platform_velocity = current_platform_velocity.slide(up_direction); } - linear_velocity += current_platform_velocity; + motion_velocity += current_platform_velocity; } } - // Reset the gravity accumulation when touching the ground. - if (collision_state.floor && linear_velocity.dot(up_direction) <= 0) { - linear_velocity = linear_velocity.slide(up_direction); - } - return motion_results.size() > 0; } void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor) { - Vector3 motion = linear_velocity * p_delta; + Vector3 motion = motion_velocity * p_delta; Vector3 motion_slide_up = motion.slide(up_direction); Vector3 prev_floor_normal = floor_normal; platform_rid = RID(); platform_velocity = Vector3(); + platform_ceiling_velocity = Vector3(); floor_normal = Vector3(); wall_normal = Vector3(); + ceiling_normal = Vector3(); // No sliding on first attempt to keep floor motion stable when possible, // When stop on slope is enabled or when there is no up direction. bool sliding_enabled = !floor_stop_on_slope; // Constant speed can be applied only the first time sliding is enabled. bool can_apply_constant_speed = sliding_enabled; + // If the platform's ceiling push down the body. + bool apply_ceiling_velocity = false; bool first_slide = true; - bool vel_dir_facing_up = linear_velocity.dot(up_direction) > 0; + bool vel_dir_facing_up = motion_velocity.dot(up_direction) > 0; Vector3 total_travel; for (int iteration = 0; iteration < max_slides; ++iteration) { PhysicsServer3D::MotionResult result; bool collided = move_and_collide(motion, result, margin, false, 4, !sliding_enabled); + last_motion = result.travel; if (collided) { motion_results.push_back(result); @@ -1189,20 +1193,33 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo CollisionState result_state; _set_collision_direction(result, result_state); - if (collision_state.floor && floor_stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) { + // If we hit a ceiling platform, we set the vertical motion_velocity to at least the platform one. + if (collision_state.ceiling && platform_ceiling_velocity != Vector3() && platform_ceiling_velocity.dot(up_direction) < 0) { + // If ceiling sliding is on, only apply when the ceiling is flat or when the motion is upward. + if (!slide_on_ceiling || motion.dot(up_direction) < 0 || (ceiling_normal + up_direction).length() < 0.01) { + apply_ceiling_velocity = true; + Vector3 ceiling_vertical_velocity = up_direction * up_direction.dot(platform_ceiling_velocity); + Vector3 motion_vertical_velocity = up_direction * up_direction.dot(motion_velocity); + if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) { + motion_velocity = ceiling_vertical_velocity + motion_velocity.slide(up_direction); + } + } + } + + if (collision_state.floor && floor_stop_on_slope && (motion_velocity.normalized() + up_direction).length() < 0.01) { Transform3D gt = get_global_transform(); if (result.travel.length() <= margin + CMP_EPSILON) { gt.origin -= result.travel; } set_global_transform(gt); - linear_velocity = Vector3(); + motion_velocity = Vector3(); motion = Vector3(); + last_motion = Vector3(); break; } if (result.remainder.is_equal_approx(Vector3())) { motion = Vector3(); - last_motion = result.travel; break; } @@ -1251,7 +1268,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo Vector3 forward = wall_normal.slide(up_direction).normalized(); motion = motion.slide(forward); // Avoid accelerating when you jump on the wall and smooth falling. - linear_velocity = linear_velocity.slide(forward); + motion_velocity = motion_velocity.slide(forward); // Allow only lateral motion along previous floor when already on floor. // Fixes slowing down when moving in diagonal against an inclined wall. @@ -1280,7 +1297,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo if (stop_all_motion) { motion = Vector3(); - linear_velocity = Vector3(); + motion_velocity = Vector3(); } } } @@ -1291,7 +1308,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo real_t motion_angle = Math::abs(Math::acos(-horizontal_normal.dot(motion_slide_up.normalized()))); if (motion_angle < wall_min_slide_angle) { motion = up_direction * motion.dot(up_direction); - linear_velocity = up_direction * linear_velocity.dot(up_direction); + motion_velocity = up_direction * motion_velocity.dot(up_direction); apply_default_sliding = false; } @@ -1300,21 +1317,35 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo if (apply_default_sliding) { // Regular sliding, the last part of the test handle the case when you don't want to slide on the ceiling. - if ((sliding_enabled || !collision_state.floor) && (!collision_state.ceiling || slide_on_ceiling || !vel_dir_facing_up)) { + if ((sliding_enabled || !collision_state.floor) && (!collision_state.ceiling || slide_on_ceiling || !vel_dir_facing_up) && !apply_ceiling_velocity) { const PhysicsServer3D::MotionCollision &collision = result.collisions[0]; + Vector3 slide_motion = result.remainder.slide(collision.normal); - if (slide_motion.dot(linear_velocity) > 0.0) { + if (collision_state.floor && !collision_state.wall) { + // Slide using the intersection between the motion plane and the floor plane, + // in order to keep the direction intact. + real_t motion_length = slide_motion.length(); + slide_motion = up_direction.cross(result.remainder).cross(floor_normal); + + // Keep the length from default slide to change speed in slopes by default, + // when constant speed is not enabled. + slide_motion.normalize(); + slide_motion *= motion_length; + } + + if (slide_motion.dot(motion_velocity) > 0.0) { motion = slide_motion; } else { motion = Vector3(); } + if (slide_on_ceiling && result_state.ceiling) { // Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall. if (vel_dir_facing_up) { - linear_velocity = linear_velocity.slide(collision.normal); + motion_velocity = motion_velocity.slide(collision.normal); } else { // Avoid acceleration in slope when falling. - linear_velocity = up_direction * up_direction.dot(linear_velocity); + motion_velocity = up_direction * up_direction.dot(motion_velocity); } } } @@ -1322,18 +1353,19 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo else { motion = result.remainder; if (result_state.ceiling && !slide_on_ceiling && vel_dir_facing_up) { - linear_velocity = linear_velocity.slide(up_direction); + motion_velocity = motion_velocity.slide(up_direction); motion = motion.slide(up_direction); } } } + total_travel += result.travel; + // Apply Constant Speed. - if (p_was_on_floor && floor_constant_speed && collision_state.floor && !motion.is_equal_approx(Vector3())) { - motion = motion.normalized() * MAX(0, (motion_slide_up.length() - result.travel.slide(up_direction).length() - total_travel.slide(up_direction).length())); + if (p_was_on_floor && floor_constant_speed && can_apply_constant_speed && collision_state.floor && !motion.is_equal_approx(Vector3())) { + Vector3 travel_slide_up = total_travel.slide(up_direction); + motion = motion.normalized() * MAX(0, (motion_slide_up.length() - travel_slide_up.length())); } - - total_travel += result.travel; } // When you move forward in a downward slope you don’t collide because you will be in the air. // This test ensures that constant speed is applied, only if the player is still on the ground after the snap is applied. @@ -1344,34 +1376,34 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo gt.origin = gt.origin - result.travel; set_global_transform(gt); - Vector3 motion_slide_norm = motion.slide(prev_floor_normal).normalized(); + // Slide using the intersection between the motion plane and the floor plane, + // in order to keep the direction intact. + Vector3 motion_slide_norm = up_direction.cross(motion).cross(prev_floor_normal); + motion_slide_norm.normalize(); + motion = motion_slide_norm * (motion_slide_up.length()); collided = true; } - can_apply_constant_speed = !can_apply_constant_speed && !sliding_enabled; - sliding_enabled = true; - first_slide = false; - - if (!motion.is_equal_approx(Vector3())) { - last_motion = motion; - } - if (!collided || motion.is_equal_approx(Vector3())) { break; } + + can_apply_constant_speed = !can_apply_constant_speed && !sliding_enabled; + sliding_enabled = true; + first_slide = false; } _snap_on_floor(p_was_on_floor, vel_dir_facing_up); // Reset the gravity accumulation when touching the ground. if (collision_state.floor && !vel_dir_facing_up) { - linear_velocity = linear_velocity.slide(up_direction); + motion_velocity = motion_velocity.slide(up_direction); } } void CharacterBody3D::_move_and_slide_free(double p_delta) { - Vector3 motion = linear_velocity * p_delta; + Vector3 motion = motion_velocity * p_delta; platform_rid = RID(); floor_normal = Vector3(); @@ -1382,6 +1414,7 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) { PhysicsServer3D::MotionResult result; bool collided = move_and_collide(motion, result, margin, false, 1, false); + last_motion = result.travel; if (collided) { motion_results.push_back(result); @@ -1389,7 +1422,12 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) { CollisionState result_state; _set_collision_direction(result, result_state); - if (wall_min_slide_angle != 0 && Math::acos(wall_normal.dot(-linear_velocity.normalized())) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) { + if (result.remainder.is_equal_approx(Vector3())) { + motion = Vector3(); + break; + } + + if (wall_min_slide_angle != 0 && Math::acos(wall_normal.dot(-motion_velocity.normalized())) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) { motion = Vector3(); if (result.travel.length() < margin + CMP_EPSILON) { Transform3D gt = get_global_transform(); @@ -1403,16 +1441,16 @@ void CharacterBody3D::_move_and_slide_free(double p_delta) { motion = result.remainder.slide(wall_normal); } - if (motion.dot(linear_velocity) <= 0.0) { + if (motion.dot(motion_velocity) <= 0.0) { motion = Vector3(); } } - first_slide = false; - if (!collided || motion.is_equal_approx(Vector3())) { break; } + + first_slide = false; } } @@ -1501,6 +1539,8 @@ void CharacterBody3D::_set_collision_direction(const PhysicsServer3D::MotionResu if (ceiling_angle <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { r_state.ceiling = true; if (p_apply_state.ceiling) { + platform_ceiling_velocity = collision.collider_velocity; + ceiling_normal = collision.normal; collision_state.ceiling = true; } continue; @@ -1564,12 +1604,12 @@ real_t CharacterBody3D::get_safe_margin() const { return margin; } -Vector3 CharacterBody3D::get_linear_velocity() const { - return linear_velocity; +const Vector3 &CharacterBody3D::get_motion_velocity() const { + return motion_velocity; } -void CharacterBody3D::set_linear_velocity(const Vector3 &p_velocity) { - linear_velocity = p_velocity; +void CharacterBody3D::set_motion_velocity(const Vector3 &p_velocity) { + motion_velocity = p_velocity; } bool CharacterBody3D::is_on_floor() const { @@ -1596,15 +1636,15 @@ bool CharacterBody3D::is_on_ceiling_only() const { return collision_state.ceiling && !collision_state.floor && !collision_state.wall; } -Vector3 CharacterBody3D::get_floor_normal() const { +const Vector3 &CharacterBody3D::get_floor_normal() const { return floor_normal; } -Vector3 CharacterBody3D::get_wall_normal() const { +const Vector3 &CharacterBody3D::get_wall_normal() const { return wall_normal; } -Vector3 CharacterBody3D::get_last_motion() const { +const Vector3 &CharacterBody3D::get_last_motion() const { return last_motion; } @@ -1612,19 +1652,23 @@ Vector3 CharacterBody3D::get_position_delta() const { return get_transform().origin - previous_position; } -Vector3 CharacterBody3D::get_real_velocity() const { +const Vector3 &CharacterBody3D::get_real_velocity() const { return real_velocity; -}; +} real_t CharacterBody3D::get_floor_angle(const Vector3 &p_up_direction) const { ERR_FAIL_COND_V(p_up_direction == Vector3(), 0); return Math::acos(floor_normal.dot(p_up_direction)); } -Vector3 CharacterBody3D::get_platform_velocity() const { +const Vector3 &CharacterBody3D::get_platform_velocity() const { return platform_velocity; } +Vector3 CharacterBody3D::get_linear_velocity() const { + return get_real_velocity(); +} + int CharacterBody3D::get_slide_collision_count() const { return motion_results.size(); } @@ -1779,8 +1823,8 @@ void CharacterBody3D::_notification(int p_what) { void CharacterBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody3D::move_and_slide); - ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody3D::set_linear_velocity); - ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody3D::get_linear_velocity); + ClassDB::bind_method(D_METHOD("set_motion_velocity", "motion_velocity"), &CharacterBody3D::set_motion_velocity); + ClassDB::bind_method(D_METHOD("get_motion_velocity"), &CharacterBody3D::get_motion_velocity); ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody3D::set_safe_margin); ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody3D::get_safe_margin); @@ -1833,7 +1877,7 @@ void CharacterBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_motion_velocity", "get_motion_velocity"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_slides", "get_max_slides"); ADD_GROUP("Free Mode", "free_mode_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wall_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_wall_min_slide_angle", "get_wall_min_slide_angle"); @@ -1958,11 +2002,6 @@ Vector3 KinematicCollision3D::get_collider_velocity(int p_collision_index) const return result.collisions[p_collision_index].collider_velocity; } -Variant KinematicCollision3D::get_collider_metadata(int p_collision_index) const { - ERR_FAIL_INDEX_V(p_collision_index, result.collision_count, Variant()); - return Variant(); -} - Vector3 KinematicCollision3D::get_best_position() const { return result.collision_count ? get_position() : Vector3(); } @@ -1999,10 +2038,6 @@ Vector3 KinematicCollision3D::get_best_collider_velocity() const { return result.collision_count ? get_collider_velocity() : Vector3(); } -Variant KinematicCollision3D::get_best_collider_metadata() const { - return result.collision_count ? get_collider_metadata() : Variant(); -} - void KinematicCollision3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision3D::get_travel); ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision3D::get_remainder); @@ -2017,7 +2052,6 @@ void KinematicCollision3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_collider_shape", "collision_index"), &KinematicCollision3D::get_collider_shape, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_collider_shape_index", "collision_index"), &KinematicCollision3D::get_collider_shape_index, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_collider_velocity", "collision_index"), &KinematicCollision3D::get_collider_velocity, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_collider_metadata", "collision_index"), &KinematicCollision3D::get_collider_metadata, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_best_position"), &KinematicCollision3D::get_best_position); ClassDB::bind_method(D_METHOD("get_best_normal"), &KinematicCollision3D::get_best_normal); @@ -2028,7 +2062,6 @@ void KinematicCollision3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_best_collider_shape"), &KinematicCollision3D::get_best_collider_shape); ClassDB::bind_method(D_METHOD("get_best_collider_shape_index"), &KinematicCollision3D::get_best_collider_shape_index); ClassDB::bind_method(D_METHOD("get_best_collider_velocity"), &KinematicCollision3D::get_best_collider_velocity); - ClassDB::bind_method(D_METHOD("get_best_collider_metadata"), &KinematicCollision3D::get_best_collider_metadata); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder"); @@ -2042,7 +2075,6 @@ void KinematicCollision3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_best_collider_shape"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_best_collider_shape_index"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_best_collider_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_best_collider_metadata"); } /////////////////////////////////////// @@ -2981,14 +3013,11 @@ void PhysicalBone3D::_on_bone_parent_changed() { _reload_joint(); } -void PhysicalBone3D::_set_gizmo_move_joint(bool p_move_joint) { #ifdef TOOLS_ENABLED +void PhysicalBone3D::_set_gizmo_move_joint(bool p_move_joint) { gizmo_move_joint = p_move_joint; - Node3DEditor::get_singleton()->update_transform_gizmo(); -#endif } -#ifdef TOOLS_ENABLED Transform3D PhysicalBone3D::get_global_gizmo_transform() const { return gizmo_move_joint ? get_global_transform() * joint_offset : get_global_transform(); } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index a53147cb8f..fdda681350 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -328,8 +328,8 @@ public: }; bool move_and_slide(); - virtual Vector3 get_linear_velocity() const override; - void set_linear_velocity(const Vector3 &p_velocity); + const Vector3 &get_motion_velocity() const; + void set_motion_velocity(const Vector3 &p_velocity); bool is_on_floor() const; bool is_on_floor_only() const; @@ -337,13 +337,15 @@ public: bool is_on_wall_only() const; bool is_on_ceiling() const; bool is_on_ceiling_only() const; - Vector3 get_last_motion() const; + const Vector3 &get_last_motion() const; Vector3 get_position_delta() const; - Vector3 get_floor_normal() const; - Vector3 get_wall_normal() const; - Vector3 get_real_velocity() const; + const Vector3 &get_floor_normal() const; + const Vector3 &get_wall_normal() const; + const Vector3 &get_real_velocity() const; real_t get_floor_angle(const Vector3 &p_up_direction = Vector3(0.0, 1.0, 0.0)) const; - Vector3 get_platform_velocity() const; + const Vector3 &get_platform_velocity() const; + + virtual Vector3 get_linear_velocity() const override; int get_slide_collision_count() const; PhysicsServer3D::MotionResult get_slide_collision(int p_bounce) const; @@ -379,7 +381,7 @@ private: bool floor_block_on_wall = true; bool slide_on_ceiling = true; int max_slides = 6; - int platform_layer; + int platform_layer = 0; RID platform_rid; uint32_t moving_platform_floor_layers = UINT32_MAX; uint32_t moving_platform_wall_layers = 0; @@ -387,11 +389,13 @@ private: real_t floor_max_angle = Math::deg2rad((real_t)45.0); real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0); Vector3 up_direction = Vector3(0.0, 1.0, 0.0); - Vector3 linear_velocity; + Vector3 motion_velocity; Vector3 floor_normal; Vector3 wall_normal; + Vector3 ceiling_normal; Vector3 last_motion; Vector3 platform_velocity; + Vector3 platform_ceiling_velocity; Vector3 previous_position; Vector3 real_velocity; @@ -483,7 +487,6 @@ public: Object *get_collider_shape(int p_collision_index = 0) const; int get_collider_shape_index(int p_collision_index = 0) const; Vector3 get_collider_velocity(int p_collision_index = 0) const; - Variant get_collider_metadata(int p_collision_index = 0) const; Vector3 get_best_position() const; Vector3 get_best_normal() const; @@ -494,7 +497,6 @@ public: Object *get_best_collider_shape() const; int get_best_collider_shape_index() const; Vector3 get_best_collider_velocity() const; - Variant get_best_collider_metadata() const; }; class PhysicalBone3D : public PhysicsBody3D { @@ -662,10 +664,9 @@ private: public: void _on_bone_parent_changed(); - void _set_gizmo_move_joint(bool p_move_joint); -public: #ifdef TOOLS_ENABLED + void _set_gizmo_move_joint(bool p_move_joint); virtual Transform3D get_global_gizmo_transform() const override; virtual Transform3D get_local_gizmo_transform() const override; #endif diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index a886c61263..21f9b0a35d 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -433,9 +433,9 @@ void SoftDynamicBody3D::prepare_physics_server() { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { if (get_mesh().is_valid()) { - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()->get_rid()); } else { - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, RID()); } return; @@ -444,10 +444,10 @@ void SoftDynamicBody3D::prepare_physics_server() { if (get_mesh().is_valid() && (is_enabled() || (disable_mode != DISABLE_MODE_REMOVE))) { become_mesh_owner(); - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()->get_rid()); RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh)); } else { - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, RID()); if (RS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh))) { RS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh)); } diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index af186072ac..10a66386eb 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -828,9 +828,9 @@ Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) co } StringName AnimationNodeBlendTree::get_node_name(const Ref<AnimationNode> &p_node) const { - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - if (E->get().node == p_node) { - return E->key(); + for (const KeyValue<StringName, Node> &E : nodes) { + if (E.value.node == p_node) { + return E.key; } } @@ -850,8 +850,8 @@ Vector2 AnimationNodeBlendTree::get_node_position(const StringName &p_node) cons void AnimationNodeBlendTree::get_child_nodes(List<ChildNode> *r_child_nodes) { Vector<StringName> ns; - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - ns.push_back(E->key()); + for (const KeyValue<StringName, Node> &E : nodes) { + ns.push_back(E.key); } ns.sort_custom<StringName::AlphCompare>(); @@ -886,10 +886,10 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) { nodes.erase(p_name); //erase connections to name - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().connections.size(); i++) { - if (E->get().connections[i] == p_name) { - E->get().connections.write[i] = StringName(); + for (KeyValue<StringName, Node> &E : nodes) { + for (int i = 0; i < E.value.connections.size(); i++) { + if (E.value.connections[i] == p_name) { + E.value.connections.write[i] = StringName(); } } } @@ -910,10 +910,10 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN nodes.erase(p_name); //rename connections - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().connections.size(); i++) { - if (E->get().connections[i] == p_name) { - E->get().connections.write[i] = p_new_name; + for (KeyValue<StringName, Node> &E : nodes) { + for (int i = 0; i < E.value.connections.size(); i++) { + if (E.value.connections[i] == p_name) { + E.value.connections.write[i] = p_new_name; } } } @@ -932,9 +932,9 @@ void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_ Ref<AnimationNode> input = nodes[p_input_node].node; ERR_FAIL_INDEX(p_input_index, nodes[p_input_node].connections.size()); - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().connections.size(); i++) { - StringName output = E->get().connections[i]; + for (KeyValue<StringName, Node> &E : nodes) { + for (int i = 0; i < E.value.connections.size(); i++) { + StringName output = E.value.connections[i]; ERR_FAIL_COND(output == p_output_node); } } @@ -976,9 +976,9 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node return CONNECTION_ERROR_CONNECTION_EXISTS; } - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().connections.size(); i++) { - StringName output = E->get().connections[i]; + for (const KeyValue<StringName, Node> &E : nodes) { + for (int i = 0; i < E.value.connections.size(); i++) { + const StringName output = E.value.connections[i]; if (output == p_output_node) { return CONNECTION_ERROR_CONNECTION_EXISTS; } @@ -988,12 +988,12 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node } void AnimationNodeBlendTree::get_node_connections(List<NodeConnection> *r_connections) const { - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - for (int i = 0; i < E->get().connections.size(); i++) { - StringName output = E->get().connections[i]; + for (const KeyValue<StringName, Node> &E : nodes) { + for (int i = 0; i < E.value.connections.size(); i++) { + const StringName output = E.value.connections[i]; if (output != StringName()) { NodeConnection nc; - nc.input_node = E->key(); + nc.input_node = E.key; nc.input_index = i; nc.output_node = output; r_connections->push_back(nc); @@ -1012,8 +1012,8 @@ double AnimationNodeBlendTree::process(double p_time, bool p_seek) { } void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) { - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - r_list->push_back(E->key()); + for (const KeyValue<StringName, Node> &E : nodes) { + r_list->push_back(E.key); } } @@ -1104,8 +1104,8 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) const { List<StringName> names; - for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) { - names.push_back(E->key()); + for (const KeyValue<StringName, Node> &E : nodes) { + names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 9fc1dbd0c6..984be04285 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -571,9 +571,9 @@ Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) } StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_node) const { - for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) { - if (E->get().node == p_node) { - return E->key(); + for (const KeyValue<StringName, State> &E : states) { + if (E.value.node == p_node) { + return E.key; } } @@ -583,8 +583,8 @@ StringName AnimationNodeStateMachine::get_node_name(const Ref<AnimationNode> &p_ void AnimationNodeStateMachine::get_child_nodes(List<ChildNode> *r_child_nodes) { Vector<StringName> nodes; - for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) { - nodes.push_back(E->key()); + for (const KeyValue<StringName, State> &E : states) { + nodes.push_back(E.key); } nodes.sort_custom<StringName::AlphCompare>(); @@ -674,8 +674,8 @@ void AnimationNodeStateMachine::rename_node(const StringName &p_name, const Stri void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const { List<StringName> nodes; - for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) { - nodes.push_back(E->key()); + for (const KeyValue<StringName, State> &E : states) { + nodes.push_back(E.key); } nodes.sort_custom<StringName::AlphCompare>(); @@ -897,8 +897,8 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const { List<StringName> names; - for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) { - names.push_back(E->key()); + for (const KeyValue<StringName, State> &E : states) { + names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 5825a35030..a8d46eac6e 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -124,8 +124,8 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const { } else if (name == "blend_times") { Vector<BlendKey> keys; - for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) { - keys.ordered_insert(E->key()); + for (const KeyValue<BlendKey, float> &E : blend_times) { + keys.ordered_insert(E.key); } Array array; @@ -147,8 +147,8 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const { if (property.name == "current_animation") { List<String> names; - for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) { - names.push_back(E->key()); + for (const KeyValue<StringName, AnimationData> &E : animation_set) { + names.push_back(E.key); } names.sort(); names.push_front("[stop]"); @@ -167,10 +167,10 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const { void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> anim_names; - for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) { - anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); - if (E->get().next != StringName()) { - anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + for (const KeyValue<StringName, AnimationData> &E : animation_set) { + anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E.key), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); + if (E.value.next != StringName()) { + anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); } } @@ -1019,8 +1019,8 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam List<BlendKey> to_erase; Map<BlendKey, float> to_insert; - for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) { - BlendKey bk = E->key(); + for (const KeyValue<BlendKey, float> &E : blend_times) { + BlendKey bk = E.key; BlendKey new_bk = bk; bool erase = false; if (bk.from == p_name) { @@ -1034,7 +1034,7 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam if (erase) { to_erase.push_back(bk); - to_insert[new_bk] = E->get(); + to_insert[new_bk] = E.value; } } @@ -1071,8 +1071,8 @@ Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const { void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const { List<String> anims; - for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) { - anims.push_back(E->key()); + for (const KeyValue<StringName, AnimationData> &E : animation_set) { + anims.push_back(E.key); } anims.sort(); @@ -1365,8 +1365,8 @@ void AnimationPlayer::clear_caches() { node_cache_map.clear(); - for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) { - E->get().node_cache.clear(); + for (KeyValue<StringName, AnimationData> &E : animation_set) { + E.value.node_cache.clear(); } cache_update_size = 0; @@ -1388,9 +1388,9 @@ bool AnimationPlayer::is_active() const { } StringName AnimationPlayer::find_animation(const Ref<Animation> &p_animation) const { - for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) { - if (E->get().animation == p_animation) { - return E->key(); + for (const KeyValue<StringName, AnimationData> &E : animation_set) { + if (E.value.animation == p_animation) { + return E.key; } } @@ -1545,12 +1545,12 @@ Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_o entry.bone_idx = -1; backup->entries.push_back(entry); } else { - for (Map<StringName, TrackNodeCache::PropertyAnim>::Element *E = nc->property_anim.front(); E; E = E->next()) { + for (const KeyValue<StringName, TrackNodeCache::PropertyAnim> &E : nc->property_anim) { AnimatedValuesBackup::Entry entry; - entry.object = E->value().object; - entry.subpath = E->value().subpath; + entry.object = E.value.object; + entry.subpath = E.value.subpath; bool valid; - entry.value = E->value().object->get_indexed(E->value().subpath, &valid); + entry.value = E.value.object->get_indexed(E.value.subpath, &valid); entry.bone_idx = -1; if (valid) { backup->entries.push_back(entry); diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index f4e477b613..3c8949ddfb 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -249,8 +249,8 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) { Map<Node *, Map<ObjectID, Node *>> &remove_list = debugger->live_edit_remove_list; Map<Node *, Map<ObjectID, Node *>>::Element *F = remove_list.find(p_node); if (F) { - for (Map<ObjectID, Node *>::Element *G = F->get().front(); G; G = G->next()) { - memdelete(G->get()); + for (const KeyValue<ObjectID, Node *> &G : F->get()) { + memdelete(G.value); } remove_list.erase(F); } @@ -339,15 +339,15 @@ void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInsta } // Constants for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) { - for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) { + for (const KeyValue<StringName, Variant> &E : sc->get()) { String script_path = sc->key() == p_script ? "" : sc->key()->get_path().get_file() + "/"; - if (E->value().get_type() == Variant::OBJECT) { - Variant id = ((Object *)E->value())->get_instance_id(); - PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object"); + if (E.value.get_type() == Variant::OBJECT) { + Variant id = ((Object *)E.value)->get_instance_id(); + PropertyInfo pi(id.get_type(), "Constants/" + E.key, PROPERTY_HINT_OBJECT_ID, "Object"); properties.push_back(SceneDebuggerProperty(pi, id)); } else { - PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key()); - properties.push_back(SceneDebuggerProperty(pi, E->value())); + PropertyInfo pi(E.value.get_type(), "Constants/" + script_path + E.key); + properties.push_back(SceneDebuggerProperty(pi, E.value)); } } } diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index c7d1d7ef82..b816f12bc3 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -614,6 +614,11 @@ void CodeEdit::_backspace_internal() { return; } + if (has_selection()) { + delete_selection(); + return; + } + int cc = get_caret_column(); int cl = get_caret_line(); @@ -621,11 +626,6 @@ void CodeEdit::_backspace_internal() { return; } - if (has_selection()) { - delete_selection(); - return; - } - if (cl > 0 && _is_line_hidden(cl - 1)) { unfold_line(get_caret_line() - 1); } @@ -1146,13 +1146,20 @@ bool CodeEdit::is_drawing_executing_lines_gutter() const { } void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) { - if (draw_breakpoints && is_line_breakpointed(p_line)) { - int padding = p_region.size.x / 6; + if (draw_breakpoints) { + bool hovering = p_region.has_point(get_local_mouse_pos()); + bool breakpointed = is_line_breakpointed(p_line); + + if (breakpointed || (hovering && !is_dragging_cursor())) { + int padding = p_region.size.x / 6; + Rect2 icon_region = p_region; + icon_region.position += Point2(padding, padding); + icon_region.size -= Point2(padding, padding) * 2; - Rect2 breakpoint_region = p_region; - breakpoint_region.position += Point2(padding, padding); - breakpoint_region.size -= Point2(padding, padding) * 2; - breakpoint_icon->draw_rect(get_canvas_item(), breakpoint_region, false, breakpoint_color); + // Darken icon when hovering & not yet breakpointed. + Color use_color = hovering && !breakpointed ? breakpoint_color.darkened(0.4) : breakpoint_color; + breakpoint_icon->draw_rect(get_canvas_item(), icon_region, false, use_color); + } } if (draw_bookmarks && is_line_bookmarked(p_line)) { @@ -1613,12 +1620,12 @@ Point2 CodeEdit::get_delimiter_start_position(int p_line, int p_column) const { bool in_region = ((p_line <= 0 || delimiter_cache[p_line - 1].size() < 1) ? -1 : delimiter_cache[p_line - 1].back()->value()) != -1; /* Check the keys for this line. */ - for (Map<int, int>::Element *E = delimiter_cache[p_line].front(); E; E = E->next()) { - if (E->key() > p_column) { + for (const KeyValue<int, int> &E : delimiter_cache[p_line]) { + if (E.key > p_column) { break; } - in_region = E->value() != -1; - start_position.x = in_region ? E->key() : -1; + in_region = E.value != -1; + start_position.x = in_region ? E.key : -1; } /* Region was found on this line and is not a multiline continuation. */ @@ -1664,12 +1671,12 @@ Point2 CodeEdit::get_delimiter_end_position(int p_line, int p_column) const { int region = (p_line <= 0 || delimiter_cache[p_line - 1].size() < 1) ? -1 : delimiter_cache[p_line - 1].back()->value(); /* Check the keys for this line. */ - for (Map<int, int>::Element *E = delimiter_cache[p_line].front(); E; E = E->next()) { - end_position.x = (E->value() == -1) ? E->key() : -1; - if (E->key() > p_column) { + for (const KeyValue<int, int> &E : delimiter_cache[p_line]) { + end_position.x = (E.value == -1) ? E.key : -1; + if (E.key > p_column) { break; } - region = E->value(); + region = E.value; } /* Region was found on this line and is not a multiline continuation. */ diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 81411d5844..1b8b5e17ed 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -742,7 +742,7 @@ bool Control::has_point(const Point2 &p_point) const { return Rect2(Point2(), get_size()).has_point(p_point); } -void Control::set_drag_forwarding(Control *p_target) { +void Control::set_drag_forwarding(Node *p_target) { if (p_target) { data.drag_owner = p_target->get_instance_id(); } else { @@ -754,8 +754,7 @@ Variant Control::get_drag_data(const Point2 &p_point) { if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { - Control *c = Object::cast_to<Control>(obj); - return c->call("_get_drag_data_fw", p_point, this); + return obj->call("_get_drag_data_fw", p_point, this); } } @@ -771,8 +770,7 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { - Control *c = Object::cast_to<Control>(obj); - return c->call("_can_drop_data_fw", p_point, p_data, this); + return obj->call("_can_drop_data_fw", p_point, p_data, this); } } @@ -787,8 +785,7 @@ void Control::drop_data(const Point2 &p_point, const Variant &p_data) { if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { - Control *c = Object::cast_to<Control>(obj); - c->call("_drop_data_fw", p_point, p_data, this); + obj->call("_drop_data_fw", p_point, p_data, this); return; } } @@ -2452,8 +2449,8 @@ bool Control::is_text_field() const { return false; } -Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const { - Vector<Vector2i> ret; +Array Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const { + Array ret; switch (p_theme_type) { case STRUCTURED_TEXT_URI: { int prev = 0; diff --git a/scene/gui/control.h b/scene/gui/control.h index 9cec5d6e8d..87ff3918cb 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -283,7 +283,7 @@ protected: //virtual void _window_gui_input(InputEvent p_event); - virtual Vector<Vector2i> structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const; + virtual Array structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const; bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -355,7 +355,7 @@ public: virtual Size2 get_minimum_size() const; virtual Size2 get_combined_minimum_size() const; virtual bool has_point(const Point2 &p_point) const; - virtual void set_drag_forwarding(Control *p_target); + virtual void set_drag_forwarding(Node *p_target); virtual Variant get_drag_data(const Point2 &p_point); virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const; virtual void drop_data(const Point2 &p_point, const Variant &p_data); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index ecf735d7f5..8462fd259e 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -403,28 +403,28 @@ void GraphNode::_notification(int p_what) { close_rect = Rect2(); } - for (Map<int, Slot>::Element *E = slot_info.front(); E; E = E->next()) { - if (E->key() < 0 || E->key() >= cache_y.size()) { + for (const KeyValue<int, Slot> &E : slot_info) { + if (E.key < 0 || E.key >= cache_y.size()) { continue; } - if (!slot_info.has(E->key())) { + if (!slot_info.has(E.key)) { continue; } - const Slot &s = slot_info[E->key()]; + const Slot &s = slot_info[E.key]; //left if (s.enable_left) { Ref<Texture2D> p = port; if (s.custom_slot_left.is_valid()) { p = s.custom_slot_left; } - p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left); + p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E.key]), s.color_left); } if (s.enable_right) { Ref<Texture2D> p = port; if (s.custom_slot_right.is_valid()) { p = s.custom_slot_right; } - p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E->key()]), s.color_right); + p->draw(get_canvas_item(), icofs + Point2(get_size().x - edgeofs, cache_y[E.key]), s.color_right); } } diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index 1107e3a4af..2beb2624d2 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -82,15 +82,15 @@ void GridContainer::_notification(int p_what) { // Evaluate the remaining space for expanded columns/rows. Size2 remaining_space = get_size(); - for (Map<int, int>::Element *E = col_minw.front(); E; E = E->next()) { - if (!col_expanded.has(E->key())) { - remaining_space.width -= E->get(); + for (const KeyValue<int, int> &E : col_minw) { + if (!col_expanded.has(E.key)) { + remaining_space.width -= E.value; } } - for (Map<int, int>::Element *E = row_minh.front(); E; E = E->next()) { - if (!row_expanded.has(E->key())) { - remaining_space.height -= E->get(); + for (const KeyValue<int, int> &E : row_minh) { + if (!row_expanded.has(E.key)) { + remaining_space.height -= E.value; } } remaining_space.height -= vsep * MAX(max_row - 1, 0); @@ -247,12 +247,12 @@ Size2 GridContainer::get_minimum_size() const { Size2 ms; - for (Map<int, int>::Element *E = col_minw.front(); E; E = E->next()) { - ms.width += E->get(); + for (const KeyValue<int, int> &E : col_minw) { + ms.width += E.value; } - for (Map<int, int>::Element *E = row_minh.front(); E; E = E->next()) { - ms.height += E->get(); + for (const KeyValue<int, int> &E : row_minh) { + ms.height += E.value; } ms.height += vsep * max_row; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 18cde25e55..b8cb618171 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -108,7 +108,7 @@ void Label::_shape() { } lines_rid.clear(); - uint8_t autowrap_flags = TextServer::BREAK_MANDATORY; + uint16_t autowrap_flags = TextServer::BREAK_MANDATORY; switch (autowrap_mode) { case AUTOWRAP_WORD_SMART: autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY; @@ -122,10 +122,10 @@ void Label::_shape() { case AUTOWRAP_OFF: break; } - Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); - for (int i = 0; i < line_breaks.size(); i++) { - RID line = TS->shaped_text_substr(text_rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x); + for (int i = 0; i < line_breaks.size(); i = i + 2) { + RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); lines_rid.push_back(line); } } @@ -145,7 +145,7 @@ void Label::_shape() { } if (lines_dirty) { - uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; + uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; switch (overrun_behavior) { case OVERRUN_TRIM_WORD_ELLIPSIS: overrun_flags |= TextServer::OVERRUN_TRIM; @@ -231,7 +231,7 @@ void Label::_update_visible() { } } -inline void draw_glyph(const TextServer::Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) { +inline void draw_glyph(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) { if (p_gl.font_rid != RID()) { TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off), p_gl.index, p_font_color); } else { @@ -239,7 +239,7 @@ inline void draw_glyph(const TextServer::Glyph &p_gl, const RID &p_canvas, const } } -inline void draw_glyph_outline(const TextServer::Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Color &p_font_shadow_color, const Color &p_font_outline_color, const int &p_shadow_outline_size, const int &p_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) { +inline void draw_glyph_outline(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Color &p_font_shadow_color, const Color &p_font_outline_color, const int &p_shadow_outline_size, const int &p_outline_size, const Vector2 &p_ofs, const Vector2 &shadow_ofs) { if (p_gl.font_rid != RID()) { if (p_font_shadow_color.a > 0) { TS->font_draw_glyph(p_gl.font_rid, p_canvas, p_gl.font_size, p_ofs + Vector2(p_gl.x_off, p_gl.y_off) + shadow_ofs, p_gl.index, p_font_shadow_color); @@ -387,21 +387,25 @@ void Label::_notification(int p_what) { } break; } - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(lines_rid[i]); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); - TextServer::TrimData trim_data = TS->shaped_text_get_trim_data(lines_rid[i]); + const Glyph *glyphs = TS->shaped_text_get_glyphs(lines_rid[i]); + int gl_size = TS->shaped_text_get_glyph_count(lines_rid[i]); + + int ellipsis_pos = TS->shaped_text_get_ellipsis_pos(lines_rid[i]); + int trim_pos = TS->shaped_text_get_trim_pos(lines_rid[i]); + + const Glyph *ellipsis_glyphs = TS->shaped_text_get_ellipsis_glyphs(lines_rid[i]); + int ellipsis_gl_size = TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]); // Draw outline. Note: Do not merge this into the single loop with the main text, to prevent overlaps. if (font_shadow_color.a > 0 || (font_outline_color.a != 0.0 && outline_size > 0)) { Vector2 offset = ofs; // Draw RTL ellipsis string when necessary. - if (rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = trim_data.ellipsis_glyph_buf.size() - 1; gl_idx >= 0; gl_idx--) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (rtl && ellipsis_pos >= 0) { + for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph_outline(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); - offset.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + offset.x += ellipsis_glyphs[gl_idx].advance; } } } @@ -410,13 +414,13 @@ void Label::_notification(int p_what) { for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { // Trim when necessary. - if (trim_data.trim_pos >= 0) { + if (trim_pos >= 0) { if (rtl) { - if (j < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { continue; } } else { - if (j >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { break; } } @@ -428,12 +432,12 @@ void Label::_notification(int p_what) { } } // Draw LTR ellipsis string when necessary. - if (!rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = 0; gl_idx < trim_data.ellipsis_glyph_buf.size(); gl_idx++) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (!rtl && ellipsis_pos >= 0) { + for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph_outline(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); - offset.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph_outline(ellipsis_glyphs[gl_idx], ci, font_color, font_shadow_color, font_outline_color, shadow_outline_size, outline_size, offset, shadow_ofs); + offset.x += ellipsis_glyphs[gl_idx].advance; } } } @@ -442,12 +446,12 @@ void Label::_notification(int p_what) { // Draw main text. Note: Do not merge this into the single loop with the outline, to prevent overlaps. // Draw RTL ellipsis string when necessary. - if (rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = trim_data.ellipsis_glyph_buf.size() - 1; gl_idx >= 0; gl_idx--) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (rtl && ellipsis_pos >= 0) { + for (int gl_idx = ellipsis_gl_size - 1; gl_idx >= 0; gl_idx--) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, ofs); - ofs.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + ofs.x += ellipsis_glyphs[gl_idx].advance; } } } @@ -456,13 +460,13 @@ void Label::_notification(int p_what) { for (int j = 0; j < gl_size; j++) { for (int k = 0; k < glyphs[j].repeat; k++) { // Trim when necessary. - if (trim_data.trim_pos >= 0) { + if (trim_pos >= 0) { if (rtl) { - if (j < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { continue; } } else { - if (j >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (j >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { break; } } @@ -474,12 +478,12 @@ void Label::_notification(int p_what) { } } // Draw LTR ellipsis string when necessary. - if (!rtl && trim_data.ellipsis_pos >= 0) { - for (int gl_idx = 0; gl_idx < trim_data.ellipsis_glyph_buf.size(); gl_idx++) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[gl_idx].repeat; j++) { + if (!rtl && ellipsis_pos >= 0) { + for (int gl_idx = 0; gl_idx < ellipsis_gl_size; gl_idx++) { + for (int j = 0; j < ellipsis_glyphs[gl_idx].repeat; j++) { //Draw glyph outlines and shadow. - draw_glyph(trim_data.ellipsis_glyph_buf[gl_idx], ci, font_color, ofs); - ofs.x += trim_data.ellipsis_glyph_buf[gl_idx].advance; + draw_glyph(ellipsis_glyphs[gl_idx], ci, font_color, ofs); + ofs.x += ellipsis_glyphs[gl_idx].advance; } } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 89fd9bfc88..2c1092d8f9 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -67,10 +67,10 @@ void LineEdit::_move_caret_left(bool p_select, bool p_move_by_word) { if (p_move_by_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < cc) { + cc = words[i]; break; } } @@ -99,10 +99,10 @@ void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) { if (p_move_by_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > cc) { + cc = words[i]; break; } } @@ -151,10 +151,10 @@ void LineEdit::_backspace(bool p_word, bool p_all_to_left) { if (p_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < cc) { + cc = words[i]; break; } } @@ -194,10 +194,10 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) { if (p_word) { int cc = caret_column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > cc) { + cc = words[i]; break; } } @@ -276,12 +276,12 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { // Double-click select word. last_dblclk = OS::get_singleton()->get_ticks_msec(); last_dblclk_pos = b->get_position(); - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid); - for (int i = 0; i < words.size(); i++) { - if ((words[i].x < caret_column && words[i].y > caret_column) || (i == words.size() - 1 && caret_column == words[i].y)) { + PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); + for (int i = 0; i < words.size(); i = i + 2) { + if ((words[i] < caret_column && words[i + 1] > caret_column) || (i == words.size() - 2 && caret_column == words[i + 1])) { selection.enabled = true; - selection.begin = words[i].x; - selection.end = words[i].y; + selection.begin = words[i]; + selection.end = words[i + 1]; selection.double_click = true; caret_column = selection.end; break; @@ -737,9 +737,8 @@ void LineEdit::_notification(int p_what) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, selection_color); } } - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(text_rid); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); + const Glyph *glyphs = TS->shaped_text_get_glyphs(text_rid); + int gl_size = TS->shaped_text_get_glyph_count(text_rid); // Draw text. ofs.y += TS->shaped_text_get_ascent(text_rid); @@ -783,38 +782,36 @@ void LineEdit::_notification(int p_what) { if (draw_caret) { if (ime_text.length() == 0) { // Normal caret. - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; - TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir); + CaretInfo caret = TS->shaped_text_get_carets(text_rid, caret_column); - if (l_caret == Rect2() && t_caret == Rect2()) { + if (caret.l_caret == Rect2() && caret.t_caret == Rect2()) { // No carets, add one at the start. int h = get_theme_font(SNAME("font"))->get_height(get_theme_font_size(SNAME("font_size"))); int y = style->get_offset().y + (y_area - h) / 2; if (rtl) { - l_dir = TextServer::DIRECTION_RTL; - l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h)); + caret.l_dir = TextServer::DIRECTION_RTL; + caret.l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h)); } else { - l_dir = TextServer::DIRECTION_LTR; - l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h)); + caret.l_dir = TextServer::DIRECTION_LTR; + caret.l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h)); } - RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color); } else { - if (l_caret != Rect2() && l_dir == TextServer::DIRECTION_AUTO) { + if (caret.l_caret != Rect2() && caret.l_dir == TextServer::DIRECTION_AUTO) { // Draw extra marker on top of mid caret. - Rect2 trect = Rect2(l_caret.position.x - 3 * caret_width, l_caret.position.y, 6 * caret_width, caret_width); + Rect2 trect = Rect2(caret.l_caret.position.x - 3 * caret_width, caret.l_caret.position.y, 6 * caret_width, caret_width); trect.position += ofs; RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color); } - l_caret.position += ofs; - l_caret.size.x = caret_width; - RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color); + caret.l_caret.position += ofs; + caret.l_caret.size.x = caret_width; + RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color); - t_caret.position += ofs; - t_caret.size.x = caret_width; + caret.t_caret.position += ofs; + caret.t_caret.size.x = caret_width; - RenderingServer::get_singleton()->canvas_item_add_rect(ci, t_caret, caret_color); + RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.t_caret, caret_color); } } else { { @@ -1114,32 +1111,31 @@ Vector2i LineEdit::get_caret_pixel_pos() { } Vector2i ret; - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; + CaretInfo caret; // Get position of the start of caret. if (ime_text.length() != 0 && ime_selection.x != 0) { - TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x, l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x); } else { - TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column); } - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - ret.x = x_ofs + l_caret.position.x + scroll_offset; + if ((caret.l_caret != Rect2() && (caret.l_dir == TextServer::DIRECTION_AUTO || caret.l_dir == (TextServer::Direction)input_direction)) || (caret.t_caret == Rect2())) { + ret.x = x_ofs + caret.l_caret.position.x + scroll_offset; } else { - ret.x = x_ofs + t_caret.position.x + scroll_offset; + ret.x = x_ofs + caret.t_caret.position.x + scroll_offset; } // Get position of the end of caret. if (ime_text.length() != 0) { if (ime_selection.y != 0) { - TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x + ime_selection.y, l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x + ime_selection.y); } else { - TS->shaped_text_get_carets(text_rid, caret_column + ime_text.size(), l_caret, l_dir, t_caret, t_dir); + caret = TS->shaped_text_get_carets(text_rid, caret_column + ime_text.size()); } - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - ret.y = x_ofs + l_caret.position.x + scroll_offset; + if ((caret.l_caret != Rect2() && (caret.l_dir == TextServer::DIRECTION_AUTO || caret.l_dir == (TextServer::Direction)input_direction)) || (caret.t_caret == Rect2())) { + ret.y = x_ofs + caret.l_caret.position.x + scroll_offset; } else { - ret.y = x_ofs + t_caret.position.x + scroll_offset; + ret.y = x_ofs + caret.t_caret.position.x + scroll_offset; } } else { ret.y = ret.x; @@ -1502,7 +1498,7 @@ void LineEdit::insert_text_at_caret(String p_text) { String post = text.substr(caret_column, text.length() - caret_column); text = pre + p_text + post; _shape(); - TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length()); + TextServer::Direction dir = TS->shaped_text_get_dominant_direction_in_range(text_rid, caret_column, caret_column + p_text.length()); if (dir != TextServer::DIRECTION_AUTO) { input_direction = (TextDirection)dir; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 277026cc28..bc25177275 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -819,9 +819,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); + const Glyph *glyphs = TS->shaped_text_get_glyphs(rid); + int gl_size = TS->shaped_text_get_glyph_count(rid); Vector2 gloff = off; // Draw oulines and shadow. @@ -1593,18 +1592,18 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) { if (c_frame) { const Line &l = c_frame->lines[c_line]; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(l.text_buf->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (c_index >= words[i].x && c_index < words[i].y) { + PackedInt32Array words = TS->shaped_text_get_word_breaks(l.text_buf->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if (c_index >= words[i] && c_index < words[i + 1]) { selection.from_frame = c_frame; selection.from_line = c_line; selection.from_item = c_item; - selection.from_char = words[i].x; + selection.from_char = words[i]; selection.to_frame = c_frame; selection.to_line = c_line; selection.to_item = c_item; - selection.to_char = words[i].y; + selection.to_char = words[i + 1]; selection.active = true; update(); diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index ef34bec347..ba8dba847c 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -164,7 +164,7 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) { if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { if (rb_hover != -1) { //pressed - emit_signal(SNAME("right_button_pressed"), rb_hover); + emit_signal(SNAME("tab_rmb_clicked"), rb_hover); } rb_pressing = false; @@ -401,7 +401,7 @@ void Tabs::_notification(int p_what) { w += tabs[i].size_text; if (tabs[i].right_button.is_valid()) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("button")); + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); Ref<Texture2D> rb = tabs[i].right_button; w += get_theme_constant(SNAME("hseparation")); @@ -433,7 +433,7 @@ void Tabs::_notification(int p_what) { } if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { - Ref<StyleBox> style = get_theme_stylebox(SNAME("button")); + Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight")); Ref<Texture2D> cb = close; w += get_theme_constant(SNAME("hseparation")); @@ -449,7 +449,7 @@ void Tabs::_notification(int p_what) { if (!tabs[i].disabled && cb_hover == i) { if (cb_pressing) { - get_theme_stylebox(SNAME("button_pressed"))->draw(ci, cb_rect); + get_theme_stylebox(SNAME("close_bg_pressed"))->draw(ci, cb_rect); } else { style->draw(ci, cb_rect); } @@ -886,7 +886,7 @@ void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) { hover_now = get_tab_count() - 1; } move_tab(tab_from_id, hover_now); - emit_signal(SNAME("reposition_active_tab_request"), hover_now); + emit_signal(SNAME("active_tab_rearranged"), hover_now); set_current_tab(hover_now); } else if (get_tabs_rearrange_group() != -1) { // drag and drop between Tabs @@ -1165,10 +1165,10 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("get_select_with_rmb"), &Tabs::get_select_with_rmb); ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); - ADD_SIGNAL(MethodInfo("right_button_pressed", PropertyInfo(Variant::INT, "tab"))); + ADD_SIGNAL(MethodInfo("tab_rmb_clicked", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("tab_closed", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("tab_hovered", PropertyInfo(Variant::INT, "tab"))); - ADD_SIGNAL(MethodInfo("reposition_active_tab_request", PropertyInfo(Variant::INT, "idx_to"))); + ADD_SIGNAL(MethodInfo("active_tab_rearranged", PropertyInfo(Variant::INT, "idx_to"))); ADD_SIGNAL(MethodInfo("tab_clicked", PropertyInfo(Variant::INT, "tab"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 5b13e1da0b..e2ddc761b8 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -186,7 +186,7 @@ void TextEdit::Text::_calculate_max_line_width() { max_width = width; } -void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Vector<Vector2i> &p_bidi_override) { +void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Array &p_bidi_override) { ERR_FAIL_INDEX(p_line, text.size()); if (font.is_null() || font_size <= 0) { @@ -278,14 +278,14 @@ void TextEdit::Text::invalidate_all() { void TextEdit::Text::clear() { text.clear(); - insert(0, "", Vector<Vector2i>()); + insert(0, "", Array()); } int TextEdit::Text::get_max_width() const { return max_width; } -void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override) { +void TextEdit::Text::set(int p_line, const String &p_text, const Array &p_bidi_override) { ERR_FAIL_INDEX(p_line, text.size()); text.write[p_line].data = p_text; @@ -293,7 +293,7 @@ void TextEdit::Text::set(int p_line, const String &p_text, const Vector<Vector2i invalidate_cache(p_line); } -void TextEdit::Text::insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override) { +void TextEdit::Text::insert(int p_at, const String &p_text, const Array &p_bidi_override) { Line line; line.gutters.resize(gutter_count); line.hidden = false; @@ -1076,9 +1076,8 @@ void TextEdit::_notification(int p_what) { ofs_y += (row_height - text_height) / 2; - const Vector<TextServer::Glyph> visual = TS->shaped_text_get_glyphs(rid); - const TextServer::Glyph *glyphs = visual.ptr(); - int gl_size = visual.size(); + const Glyph *glyphs = TS->shaped_text_get_glyphs(rid); + int gl_size = TS->shaped_text_get_glyph_count(rid); ofs_y += ldata->get_line_ascent(line_wrap_index); int char_ofs = 0; @@ -1185,27 +1184,26 @@ void TextEdit::_notification(int p_what) { caret.draw_pos.y = ofs_y + ldata->get_line_descent(line_wrap_index); if (ime_text.length() == 0) { - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; + CaretInfo ts_caret; if (str.length() != 0) { // Get carets. - TS->shaped_text_get_carets(rid, caret.column, l_caret, l_dir, t_caret, t_dir); + ts_caret = TS->shaped_text_get_carets(rid, caret.column); } else { // No carets, add one at the start. int h = font->get_height(font_size); if (rtl) { - l_dir = TextServer::DIRECTION_RTL; - l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h)); + ts_caret.l_dir = TextServer::DIRECTION_RTL; + ts_caret.l_caret = Rect2(Vector2(xmargin_end - char_margin + ofs_x, -h / 2), Size2(caret_width * 4, h)); } else { - l_dir = TextServer::DIRECTION_LTR; - l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h)); + ts_caret.l_dir = TextServer::DIRECTION_LTR; + ts_caret.l_caret = Rect2(Vector2(char_ofs, -h / 2), Size2(caret_width * 4, h)); } } - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - caret.draw_pos.x = char_margin + ofs_x + l_caret.position.x; + if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) { + caret.draw_pos.x = char_margin + ofs_x + ts_caret.l_caret.position.x; } else { - caret.draw_pos.x = char_margin + ofs_x + t_caret.position.x; + caret.draw_pos.x = char_margin + ofs_x + ts_caret.t_caret.position.x; } if (caret.draw_pos.x >= xmargin_beg && caret.draw_pos.x < xmargin_end) { @@ -1215,64 +1213,64 @@ void TextEdit::_notification(int p_what) { //Block or underline caret, draw trailing carets at full height. int h = font->get_height(font_size); - if (t_caret != Rect2()) { + if (ts_caret.t_caret != Rect2()) { if (overtype_mode) { - t_caret.position.y = TS->shaped_text_get_descent(rid); - t_caret.size.y = caret_width; + ts_caret.t_caret.position.y = TS->shaped_text_get_descent(rid); + ts_caret.t_caret.size.y = caret_width; } else { - t_caret.position.y = -TS->shaped_text_get_ascent(rid); - t_caret.size.y = h; + ts_caret.t_caret.position.y = -TS->shaped_text_get_ascent(rid); + ts_caret.t_caret.size.y = h; } - t_caret.position += Vector2(char_margin + ofs_x, ofs_y); - draw_rect(t_caret, caret_color, overtype_mode); + ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y); + draw_rect(ts_caret.t_caret, caret_color, overtype_mode); - if (l_caret != Rect2() && l_dir != t_dir) { - l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - l_caret.size.x = caret_width; - draw_rect(l_caret, caret_color * Color(1, 1, 1, 0.5)); + if (ts_caret.l_caret != Rect2() && ts_caret.l_dir != ts_caret.t_dir) { + ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); + ts_caret.l_caret.size.x = caret_width; + draw_rect(ts_caret.l_caret, caret_color * Color(1, 1, 1, 0.5)); } } else { // End of the line. if (gl_size > 0) { // Adjust for actual line dimensions. if (overtype_mode) { - l_caret.position.y = TS->shaped_text_get_descent(rid); - l_caret.size.y = caret_width; + ts_caret.l_caret.position.y = TS->shaped_text_get_descent(rid); + ts_caret.l_caret.size.y = caret_width; } else { - l_caret.position.y = -TS->shaped_text_get_ascent(rid); - l_caret.size.y = h; + ts_caret.l_caret.position.y = -TS->shaped_text_get_ascent(rid); + ts_caret.l_caret.size.y = h; } } else if (overtype_mode) { - l_caret.position.y += l_caret.size.y; - l_caret.size.y = caret_width; + ts_caret.l_caret.position.y += ts_caret.l_caret.size.y; + ts_caret.l_caret.size.y = caret_width; } - if (l_caret.position.x >= TS->shaped_text_get_size(rid).x) { - l_caret.size.x = font->get_char_size('m', 0, font_size).x; + if (ts_caret.l_caret.position.x >= TS->shaped_text_get_size(rid).x) { + ts_caret.l_caret.size.x = font->get_char_size('m', 0, font_size).x; } else { - l_caret.size.x = 3 * caret_width; + ts_caret.l_caret.size.x = 3 * caret_width; } - l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - if (l_dir == TextServer::DIRECTION_RTL) { - l_caret.position.x -= l_caret.size.x; + ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); + if (ts_caret.l_dir == TextServer::DIRECTION_RTL) { + ts_caret.l_caret.position.x -= ts_caret.l_caret.size.x; } - draw_rect(l_caret, caret_color, overtype_mode); + draw_rect(ts_caret.l_caret, caret_color, overtype_mode); } } else { // Normal caret. - if (l_caret != Rect2() && l_dir == TextServer::DIRECTION_AUTO) { + if (ts_caret.l_caret != Rect2() && ts_caret.l_dir == TextServer::DIRECTION_AUTO) { // Draw extra marker on top of mid caret. - Rect2 trect = Rect2(l_caret.position.x - 3 * caret_width, l_caret.position.y, 6 * caret_width, caret_width); + Rect2 trect = Rect2(ts_caret.l_caret.position.x - 3 * caret_width, ts_caret.l_caret.position.y, 6 * caret_width, caret_width); trect.position += Vector2(char_margin + ofs_x, ofs_y); RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color); } - l_caret.position += Vector2(char_margin + ofs_x, ofs_y); - l_caret.size.x = caret_width; + ts_caret.l_caret.position += Vector2(char_margin + ofs_x, ofs_y); + ts_caret.l_caret.size.x = caret_width; - draw_rect(l_caret, caret_color); + draw_rect(ts_caret.l_caret, caret_color); - t_caret.position += Vector2(char_margin + ofs_x, ofs_y); - t_caret.size.x = caret_width; + ts_caret.t_caret.position += Vector2(char_margin + ofs_x, ofs_y); + ts_caret.t_caret.size.x = caret_width; - draw_rect(t_caret, caret_color); + draw_rect(ts_caret.t_caret, caret_color); } } } @@ -1636,6 +1634,32 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } } } + + // Check if user is hovering a different gutter, and update if yes. + Vector2i current_hovered_gutter = Vector2i(-1, -1); + + int left_margin = style_normal->get_margin(SIDE_LEFT); + if (mpos.x <= left_margin + gutters_width + gutter_padding) { + int hovered_row = get_line_column_at_pos(mpos).y; + for (int i = 0; i < gutters.size(); i++) { + if (!gutters[i].draw || gutters[i].width <= 0) { + continue; + } + + if (mpos.x > left_margin && mpos.x <= (left_margin + gutters[i].width) - 3) { + // We are in this gutter i's horizontal area. + current_hovered_gutter = Vector2i(i, hovered_row); + break; + } + + left_margin += gutters[i].width; + } + } + + if (current_hovered_gutter != hovered_gutter) { + hovered_gutter = current_hovered_gutter; + update(); + } } if (draw_minimap && !dragging_selection) { @@ -1942,10 +1966,10 @@ void TextEdit::_move_caret_left(bool p_select, bool p_move_by_word) { set_caret_line(caret.line - 1); set_caret_column(text[caret.line].length()); } else { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < cc) { - cc = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < cc) { + cc = words[i]; break; } } @@ -1993,10 +2017,10 @@ void TextEdit::_move_caret_right(bool p_select, bool p_move_by_word) { set_caret_line(caret.line + 1); set_caret_column(0); } else { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > cc) { - cc = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > cc) { + cc = words[i]; break; } } @@ -2188,10 +2212,10 @@ void TextEdit::_do_backspace(bool p_word, bool p_all_to_left) { int line = caret.line; int column = caret.column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = words.size() - 1; i >= 0; i--) { - if (words[i].x < column) { - column = words[i].x; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = words.size() - 2; i >= 0; i = i - 2) { + if (words[i] < column) { + column = words[i]; break; } } @@ -2231,10 +2255,10 @@ void TextEdit::_delete(bool p_word, bool p_all_to_right) { int line = caret.line; int column = caret.column; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].y > column) { - column = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = 1; i < words.size(); i = i + 2) { + if (words[i] > column) { + column = words[i]; break; } } @@ -2731,7 +2755,10 @@ void TextEdit::insert_line_at(int p_at, const String &p_text) { } void TextEdit::insert_text_at_caret(const String &p_text) { - begin_complex_operation(); + bool had_selection = has_selection(); + if (had_selection) { + begin_complex_operation(); + } delete_selection(); @@ -2743,7 +2770,9 @@ void TextEdit::insert_text_at_caret(const String &p_text) { set_caret_column(new_column); update(); - end_complex_operation(); + if (had_selection) { + end_complex_operation(); + } } void TextEdit::remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) { @@ -3600,10 +3629,10 @@ int TextEdit::get_caret_wrap_index() const { } String TextEdit::get_word_under_caret() const { - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if (words[i].x <= caret.column && words[i].y > caret.column) { - return text[caret.line].substr(words[i].x, words[i].y - words[i].x); + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if (words[i] <= caret.column && words[i + 1] > caret.column) { + return text[caret.line].substr(words[i], words[i + 1] - words[i]); } } return ""; @@ -3687,11 +3716,11 @@ void TextEdit::select_word_under_caret() { int begin = 0; int end = 0; - const Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if ((words[i].x < caret.column && words[i].y > caret.column) || (i == words.size() - 1 && caret.column == words[i].y)) { - begin = words[i].x; - end = words[i].y; + const PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(caret.line)->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if ((words[i] < caret.column && words[i + 1] > caret.column) || (i == words.size() - 2 && caret.column == words[i + 1])) { + begin = words[i]; + end = words[i + 1]; break; } } @@ -5345,14 +5374,12 @@ int TextEdit::_get_column_x_offset_for_line(int p_char, int p_line) const { } } - Rect2 l_caret, t_caret; - TextServer::Direction l_dir, t_dir; RID text_rid = text.get_line_data(p_line)->get_line_rid(row); - TS->shaped_text_get_carets(text_rid, caret.column, l_caret, l_dir, t_caret, t_dir); - if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) { - return l_caret.position.x; + CaretInfo ts_caret = TS->shaped_text_get_carets(text_rid, caret.column); + if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) { + return ts_caret.l_caret.position.x; } else { - return t_caret.position.x; + return ts_caret.t_caret.position.x; } } @@ -5409,11 +5436,11 @@ void TextEdit::_update_selection_mode_word() { int caret_pos = CLAMP(col, 0, text[line].length()); int beg = caret_pos; int end = beg; - Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); - for (int i = 0; i < words.size(); i++) { - if ((words[i].x < caret_pos && words[i].y > caret_pos) || (i == words.size() - 1 && caret_pos == words[i].y)) { - beg = words[i].x; - end = words[i].y; + PackedInt32Array words = TS->shaped_text_get_word_breaks(text.get_line_data(line)->get_rid()); + for (int i = 0; i < words.size(); i = i + 2) { + if ((words[i] < caret_pos && words[i + 1] > caret_pos) || (i == words.size() - 2 && caret_pos == words[i + 1])) { + beg = words[i]; + end = words[i + 1]; break; } } @@ -6001,7 +6028,7 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i r_end_line = p_line + substrings.size() - 1; r_end_column = text[r_end_line].length() - postinsert_text.length(); - TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text.get_line_data(r_end_line)->get_rid(), (r_end_line == p_line) ? caret.column : 0, r_end_column); + TextServer::Direction dir = TS->shaped_text_get_dominant_direction_in_range(text.get_line_data(r_end_line)->get_rid(), (r_end_line == p_line) ? caret.column : 0, r_end_column); if (dir != TextServer::DIRECTION_AUTO) { input_direction = (TextDirection)dir; } diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index b1226f2aff..07e585847a 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -139,7 +139,7 @@ private: Vector<Gutter> gutters; String data; - Vector<Vector2i> bidi_override; + Array bidi_override; Ref<TextParagraph> data_buf; Color background_color = Color(0, 0, 0, 0); @@ -194,7 +194,7 @@ private: Vector<Vector2i> get_line_wrap_ranges(int p_line) const; const Ref<TextParagraph> get_line_data(int p_line) const; - void set(int p_line, const String &p_text, const Vector<Vector2i> &p_bidi_override); + void set(int p_line, const String &p_text, const Array &p_bidi_override); void set_hidden(int p_line, bool p_hidden) { text.write[p_line].hidden = p_hidden; if (!p_hidden && text[p_line].width > max_width) { @@ -204,12 +204,12 @@ private: } } bool is_hidden(int p_line) const { return text[p_line].hidden; } - void insert(int p_at, const String &p_text, const Vector<Vector2i> &p_bidi_override); + void insert(int p_at, const String &p_text, const Array &p_bidi_override); void remove(int p_at); int size() const { return text.size(); } void clear(); - void invalidate_cache(int p_line, int p_column = -1, const String &p_ime_text = String(), const Vector<Vector2i> &p_bidi_override = Vector<Vector2i>()); + void invalidate_cache(int p_line, int p_column = -1, const String &p_ime_text = String(), const Array &p_bidi_override = Array()); void invalidate_all(); void invalidate_all_lines(); @@ -477,6 +477,7 @@ private: Vector<GutterInfo> gutters; int gutters_width = 0; int gutter_padding = 0; + Vector2i hovered_gutter = Vector2i(-1, -1); // X = gutter index, Y = row. void _update_gutter_width(); diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 64b169b1fb..916833c9a7 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -647,13 +647,13 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid); } -void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const { +void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_font.is_null()); p_font->draw_string(canvas_item, p_pos, p_text, p_align, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); } -void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const { +void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_font.is_null()); p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_align, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 01ed47d4dc..ba9f47119d 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -235,8 +235,8 @@ public: void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1)); void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture); - void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; - void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const; void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0)); diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index f24d880045..14fd14dd18 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -104,9 +104,11 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h CharString charstr = p_request_data.utf8(); size_t len = charstr.length(); - raw_data.resize(len); - uint8_t *w = raw_data.ptrw(); - memcpy(w, charstr.ptr(), len); + if (len > 0) { + raw_data.resize(len); + uint8_t *w = raw_data.ptrw(); + memcpy(w, charstr.ptr(), len); + } return request_raw(p_url, p_custom_headers, p_ssl_validate_domain, p_method, raw_data); } diff --git a/scene/main/node.cpp b/scene/main/node.cpp index f5d2d2f2a2..b1ba9de85c 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -114,8 +114,8 @@ void Node::_notification(int p_notification) { memdelete(data.path_cache); data.path_cache = nullptr; } - if (data.filename.length()) { - get_multiplayer()->scene_enter_exit_notify(data.filename, this, false); + if (data.scene_file_path.length()) { + get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, false); } } break; case NOTIFICATION_PATH_CHANGED: { @@ -146,9 +146,9 @@ void Node::_notification(int p_notification) { GDVIRTUAL_CALL(_ready); - if (data.filename.length()) { + if (data.scene_file_path.length()) { ERR_FAIL_COND(!is_inside_tree()); - get_multiplayer()->scene_enter_exit_notify(data.filename, this, true); + get_multiplayer()->scene_enter_exit_notify(data.scene_file_path, this, true); } } break; @@ -211,8 +211,8 @@ void Node::_propagate_enter_tree() { data.inside_tree = true; - for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) { - E->get().group = data.tree->add_to_group(E->key(), this); + for (KeyValue<StringName, GroupData> &E : data.grouped) { + E.value.group = data.tree->add_to_group(E.key, this); } notification(NOTIFICATION_ENTER_TREE); @@ -235,7 +235,7 @@ void Node::_propagate_enter_tree() { data.blocked--; #ifdef DEBUG_ENABLED - SceneDebugger::add_to_cache(data.filename, this); + SceneDebugger::add_to_cache(data.scene_file_path, this); #endif // enter groups } @@ -253,7 +253,7 @@ void Node::_propagate_exit_tree() { //block while removing children #ifdef DEBUG_ENABLED - SceneDebugger::remove_from_cache(data.filename, this); + SceneDebugger::remove_from_cache(data.scene_file_path, this); #endif data.blocked++; @@ -274,9 +274,9 @@ void Node::_propagate_exit_tree() { // exit groups - for (Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) { - data.tree->remove_from_group(E->key(), this); - E->get().group = nullptr; + for (KeyValue<StringName, GroupData> &E : data.grouped) { + data.tree->remove_from_group(E.key, this); + E.value.group = nullptr; } data.viewport = nullptr; @@ -353,9 +353,9 @@ void Node::_move_child(Node *p_child, int p_pos, bool p_ignore_end) { for (int i = motion_from; i <= motion_to; i++) { data.children[i]->notification(NOTIFICATION_MOVED_IN_PARENT); } - for (const Map<StringName, GroupData>::Element *E = p_child->data.grouped.front(); E; E = E->next()) { - if (E->get().group) { - E->get().group->changed = true; + for (const KeyValue<StringName, GroupData> &E : p_child->data.grouped) { + if (E.value.group) { + E.value.group->changed = true; } } @@ -1678,10 +1678,10 @@ Array Node::_get_groups() const { } void Node::get_groups(List<GroupInfo> *p_groups) const { - for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) { + for (const KeyValue<StringName, GroupData> &E : data.grouped) { GroupInfo gi; - gi.name = E->key(); - gi.persistent = E->get().persistent; + gi.name = E.key; + gi.persistent = E.value.persistent; p_groups->push_back(gi); } } @@ -1689,8 +1689,8 @@ void Node::get_groups(List<GroupInfo> *p_groups) const { int Node::get_persistent_group_count() const { int count = 0; - for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) { - if (E->get().persistent) { + for (const KeyValue<StringName, GroupData> &E : data.grouped) { + if (E.value.persistent) { count += 1; } } @@ -1846,12 +1846,12 @@ void Node::remove_and_skip() { data.parent->remove_child(this); } -void Node::set_filename(const String &p_filename) { - data.filename = p_filename; +void Node::set_scene_file_path(const String &p_scene_file_path) { + data.scene_file_path = p_scene_file_path; } -String Node::get_filename() const { - return data.filename; +String Node::get_scene_file_path() const { + return data.scene_file_path; } void Node::set_editor_description(const String &p_editor_description) { @@ -1948,8 +1948,8 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const nip->set_instance_path(ip->get_instance_path()); node = nip; - } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_filename() != String()) { - Ref<PackedScene> res = ResourceLoader::load(get_filename()); + } else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_scene_file_path() != String()) { + Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path()); ERR_FAIL_COND_V(res.is_null(), nullptr); PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED; #ifdef TOOLS_ENABLED @@ -1972,8 +1972,8 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const ERR_FAIL_COND_V(!node, nullptr); } - if (get_filename() != "") { //an instance - node->set_filename(get_filename()); + if (get_scene_file_path() != "") { //an instance + node->set_scene_file_path(get_scene_file_path()); node->data.editable_instance = data.editable_instance; } @@ -2004,7 +2004,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const node_tree.push_back(descendant); - if (descendant->get_filename() != "" && instance_roots.has(descendant->get_owner())) { + if (descendant->get_scene_file_path() != "" && instance_roots.has(descendant->get_owner())) { instance_roots.push_back(descendant); } } @@ -2313,7 +2313,7 @@ void Node::replace_by(Node *p_node, bool p_keep_groups) { owned_by_owner[i]->set_owner(owner); } - p_node->set_filename(get_filename()); + p_node->set_scene_file_path(get_scene_file_path()); } void Node::_replace_connections_target(Node *p_new_target) { @@ -2693,8 +2693,8 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("get_index", "include_internal"), &Node::get_index, DEFVAL(false)); ClassDB::bind_method(D_METHOD("print_tree"), &Node::print_tree); ClassDB::bind_method(D_METHOD("print_tree_pretty"), &Node::print_tree_pretty); - ClassDB::bind_method(D_METHOD("set_filename", "filename"), &Node::set_filename); - ClassDB::bind_method(D_METHOD("get_filename"), &Node::get_filename); + ClassDB::bind_method(D_METHOD("set_scene_file_path", "scene_file_path"), &Node::set_scene_file_path); + ClassDB::bind_method(D_METHOD("get_scene_file_path"), &Node::get_scene_file_path); ClassDB::bind_method(D_METHOD("propagate_notification", "what"), &Node::propagate_notification); ClassDB::bind_method(D_METHOD("propagate_call", "method", "args", "parent_first"), &Node::propagate_call, DEFVAL(Array()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_physics_process", "enable"), &Node::set_physics_process); @@ -2839,7 +2839,7 @@ void Node::_bind_methods() { ADD_SIGNAL(MethodInfo("tree_exited")); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_name", "get_name"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_filename", "get_filename"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "scene_file_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_scene_file_path", "get_scene_file_path"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_owner", "get_owner"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "", "get_multiplayer"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", PROPERTY_USAGE_NONE), "set_custom_multiplayer", "get_custom_multiplayer"); diff --git a/scene/main/node.h b/scene/main/node.h index 198501eeac..7d4c79cfba 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -96,7 +96,7 @@ private: }; struct Data { - String filename; + String scene_file_path; Ref<SceneState> instance_state; Ref<SceneState> inherited_state; @@ -353,8 +353,8 @@ public: void print_tree(); void print_tree_pretty(); - void set_filename(const String &p_filename); - String get_filename() const; + void set_scene_file_path(const String &p_scene_file_path); + String get_scene_file_path() const; void set_editor_description(const String &p_editor_description); String get_editor_description() const; diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp index cd9560db61..f4c90ee668 100644 --- a/scene/main/resource_preloader.cpp +++ b/scene/main/resource_preloader.cpp @@ -57,8 +57,8 @@ Array ResourcePreloader::_get_resources() const { Set<String> sorted_names; - for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next()) { - sorted_names.insert(E->key()); + for (const KeyValue<StringName, RES> &E : resources) { + sorted_names.insert(E.key); } int i = 0; @@ -131,8 +131,8 @@ Vector<String> ResourcePreloader::_get_resource_list() const { } void ResourcePreloader::get_resource_list(List<StringName> *p_list) { - for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next()) { - p_list->push_back(E->key()); + for (const KeyValue<StringName, RES> &E : resources) { + p_list->push_back(E.key); } } diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 6e78193717..3d07e4473d 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1105,7 +1105,7 @@ Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) { Error SceneTree::reload_current_scene() { ERR_FAIL_COND_V(!current_scene, ERR_UNCONFIGURED); - String fname = current_scene->get_filename(); + String fname = current_scene->get_scene_file_path(); return change_scene(fname); } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 1e89b17044..56dd9c6b06 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -46,7 +46,7 @@ #include "scene/2d/collision_shape_2d.h" #include "scene/2d/cpu_particles_2d.h" #include "scene/2d/gpu_particles_2d.h" -#include "scene/2d/joints_2d.h" +#include "scene/2d/joint_2d.h" #include "scene/2d/light_2d.h" #include "scene/2d/light_occluder_2d.h" #include "scene/2d/line_2d.h" @@ -215,6 +215,7 @@ #include "scene/3d/decal.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/gpu_particles_collision_3d.h" +#include "scene/3d/joint_3d.h" #include "scene/3d/light_3d.h" #include "scene/3d/lightmap_gi.h" #include "scene/3d/lightmap_probe.h" @@ -227,7 +228,6 @@ #include "scene/3d/occluder_instance_3d.h" #include "scene/3d/path_3d.h" #include "scene/3d/physics_body_3d.h" -#include "scene/3d/physics_joint_3d.h" #include "scene/3d/position_3d.h" #include "scene/3d/proximity_group_3d.h" #include "scene/3d/ray_cast_3d.h" diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index a364a27e80..9dc76dcf44 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -966,9 +966,9 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) cons int pidx = 0; for (int i = 0; i < points.size() - 1; i++) { - for (Map<float, Vector2>::Element *E = midpoints[i].front(); E; E = E->next()) { + for (const KeyValue<float, Vector2> &E : midpoints[i]) { pidx++; - bpw[pidx] = E->get(); + bpw[pidx] = E.value; } pidx++; @@ -1652,9 +1652,9 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) cons int pidx = 0; for (int i = 0; i < points.size() - 1; i++) { - for (Map<float, Vector3>::Element *E = midpoints[i].front(); E; E = E->next()) { + for (const KeyValue<float, Vector3> &E : midpoints[i]) { pidx++; - bpw[pidx] = E->get(); + bpw[pidx] = E.value; } pidx++; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 492e0512e4..94cf826477 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -790,8 +790,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("tab_selected", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2)); theme->set_stylebox("tab_unselected", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3)); theme->set_stylebox("tab_disabled", "Tabs", sb_expand(make_stylebox(tab_disabled_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3)); - theme->set_stylebox("button_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4)); - theme->set_stylebox("button", "Tabs", make_stylebox(button_normal_png, 4, 4, 4, 4)); + theme->set_stylebox("close_bg_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4)); + theme->set_stylebox("close_bg_highlight", "Tabs", make_stylebox(button_normal_png, 4, 4, 4, 4)); theme->set_icon("increment", "Tabs", make_icon(scroll_button_right_png)); theme->set_icon("increment_highlight", "Tabs", make_icon(scroll_button_right_hl_png)); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 9b403a18f0..c1d42dff09 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -502,6 +502,11 @@ void FontData::set_data(const PackedByteArray &p_data) { } PackedByteArray FontData::get_data() const { + if (unlikely((size_t)data.size() != data_size)) { + PackedByteArray *data_w = const_cast<PackedByteArray *>(&data); + data_w->resize(data_size); + memcpy(data_w->ptrw(), data_ptr, data_size); + } return data; } @@ -1399,7 +1404,7 @@ real_t Font::get_underline_thickness(int p_size) const { return ret; } -Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, real_t p_width, uint8_t p_flags) const { +Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, real_t p_width, uint16_t p_flags) const { ERR_FAIL_COND_V(data.is_empty(), Size2()); int size = (p_size <= 0) ? base_size : p_size; @@ -1426,7 +1431,7 @@ Size2 Font::get_string_size(const String &p_text, int p_size, HAlign p_align, re return buffer->get_size(); } -Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int p_size, uint8_t p_flags) const { +Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int p_size, uint16_t p_flags) const { ERR_FAIL_COND_V(data.is_empty(), Size2()); int size = (p_size <= 0) ? base_size : p_size; @@ -1465,7 +1470,7 @@ Size2 Font::get_multiline_string_size(const String &p_text, real_t p_width, int return ret; } -void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const { +void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND(data.is_empty()); int size = (p_size <= 0) ? base_size : p_size; @@ -1507,7 +1512,7 @@ void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_t buffer->draw(p_canvas_item, ofs, p_modulate); } -void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint8_t p_flags) const { +void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align, float p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const { ERR_FAIL_COND(data.is_empty()); int size = (p_size <= 0) ? base_size : p_size; diff --git a/scene/resources/font.h b/scene/resources/font.h index 9a34edce64..e65fdb0751 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -266,11 +266,11 @@ public: virtual real_t get_underline_thickness(int p_size = -1) const; // Drawing string. - virtual Size2 get_string_size(const String &p_text, int p_size = -1, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, uint8_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; - virtual Size2 get_multiline_string_size(const String &p_text, real_t p_width = -1, int p_size = -1, uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const; + virtual Size2 get_string_size(const String &p_text, int p_size = -1, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + virtual Size2 get_multiline_string_size(const String &p_text, real_t p_width = -1, int p_size = -1, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const; - virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; - virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint8_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; + virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HAlign p_align = HALIGN_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = -1, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const; // Helper functions. virtual bool has_char(char32_t p_char) const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 67db8c1a10..18e6a51118 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -373,8 +373,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { //normalize - for (Map<Vector3, Vector3>::Element *E = normal_accum.front(); E; E = E->next()) { - E->get().normalize(); + for (KeyValue<Vector3, Vector3> &E : normal_accum) { + E.value.normalize(); } //displace normals diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index cfb7c3e037..309670e0b1 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -97,8 +97,8 @@ bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const { } void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const { - for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) { - String name = "item/" + itos(E->key()) + "/"; + for (const KeyValue<int, Item> &E : item_map) { + String name = "item/" + itos(E.key) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, name + "name")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh")); p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, name + "mesh_transform")); @@ -230,17 +230,17 @@ Vector<int> MeshLibrary::get_item_list() const { Vector<int> ret; ret.resize(item_map.size()); int idx = 0; - for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) { - ret.write[idx++] = E->key(); + for (const KeyValue<int, Item> &E : item_map) { + ret.write[idx++] = E.key; } return ret; } int MeshLibrary::find_item_by_name(const String &p_name) const { - for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) { - if (E->get().name == p_name) { - return E->key(); + for (const KeyValue<int, Item> &E : item_map) { + if (E.value.name == p_name) { + return E.key; } } return -1; diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index 00cee9269b..d87056f55d 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -41,6 +41,8 @@ void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) { continue; } Array arr = p_mesh->surface_get_arrays(i); + ERR_CONTINUE(arr.size() != Mesh::ARRAY_MAX); + Vector<Vector3> varr = arr[Mesh::ARRAY_VERTEX]; Vector<int> iarr = arr[Mesh::ARRAY_INDEX]; if (varr.size() == 0 || iarr.size() == 0) { @@ -367,10 +369,10 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { } List<Vector3> lines; - for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) { - if (E->get()) { - lines.push_back(E->key().from); - lines.push_back(E->key().to); + for (const KeyValue<_EdgeKey, bool> &E : edge_map) { + if (E.value) { + lines.push_back(E.key.from); + lines.push_back(E.key.to); } } diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 59faa50114..c8d3ea5e37 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -299,8 +299,8 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { } } - for (Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.front(); E; E = E->next()) { - E->get()->setup_local_to_scene(); + for (KeyValue<Ref<Resource>, Ref<Resource>> &E : resources_local_to_scene) { + E.value->setup_local_to_scene(); } //do connections @@ -384,7 +384,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map // save the child instantiated scenes that are chosen as editable, so they can be restored // upon load back - if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node)) { + if (p_node != p_owner && p_node->get_scene_file_path() != String() && p_owner->is_editable_instance(p_node)) { editable_instances.push_back(p_owner->get_path_to(p_node)); // Node is the root of an editable instance. is_editable_instance = true; @@ -437,14 +437,14 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map } } - if (p_node->get_filename() != String() && p_node->get_owner() == p_owner && instantiated_by_owner) { + if (p_node->get_scene_file_path() != String() && p_node->get_owner() == p_owner && instantiated_by_owner) { if (p_node->get_scene_instance_load_placeholder()) { //it's a placeholder, use the placeholder path - nd.instance = _vm_get_variant(p_node->get_filename(), variant_map); + nd.instance = _vm_get_variant(p_node->get_scene_file_path(), variant_map); nd.instance |= FLAG_INSTANCE_IS_PLACEHOLDER; } else { //must instance ourselves - Ref<PackedScene> instance = ResourceLoader::load(p_node->get_filename()); + Ref<PackedScene> instance = ResourceLoader::load(p_node->get_scene_file_path()); if (!instance.is_valid()) { return ERR_CANT_OPEN; } @@ -454,7 +454,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map } n = nullptr; } else { - if (n->get_filename() != String()) { + if (n->get_scene_file_path() != String()) { //is an instance Ref<SceneState> state = n->get_scene_instance_state(); if (state.is_valid()) { @@ -714,7 +714,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName ERR_CONTINUE(!common_parent); - if (common_parent != p_owner && common_parent->get_filename() == String()) { + if (common_parent != p_owner && common_parent->get_scene_file_path() == String()) { common_parent = common_parent->get_owner(); } @@ -774,7 +774,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName nl = nullptr; } else { - if (nl->get_filename() != String()) { + if (nl->get_scene_file_path() != String()) { //is an instance Ref<SceneState> state = nl->get_scene_instance_state(); if (state.is_valid()) { @@ -887,8 +887,8 @@ Error SceneState::pack(Node *p_scene) { names.resize(name_map.size()); - for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) { - names.write[E->get()] = E->key(); + for (const KeyValue<StringName, int> &E : name_map) { + names.write[E.value] = E.key; } variants.resize(variant_map.size()); @@ -899,14 +899,14 @@ Error SceneState::pack(Node *p_scene) { } node_paths.resize(nodepath_map.size()); - for (Map<Node *, int>::Element *E = nodepath_map.front(); E; E = E->next()) { - node_paths.write[E->get()] = scene->get_path_to(E->key()); + for (const KeyValue<Node *, int> &E : nodepath_map) { + node_paths.write[E.value] = scene->get_path_to(E.key); } if (Engine::get_singleton()->is_editor_hint()) { // Build node path cache - for (Map<Node *, int>::Element *E = node_map.front(); E; E = E->next()) { - node_path_cache[scene->get_path_to(E->key())] = E->get(); + for (const KeyValue<Node *, int> &E : node_map) { + node_path_cache[scene->get_path_to(E.key)] = E.value; } } @@ -977,9 +977,9 @@ int SceneState::find_node_by_path(const NodePath &p_node) const { } int SceneState::_find_base_scene_node_remap_key(int p_idx) const { - for (Map<int, int>::Element *E = base_scene_node_remap.front(); E; E = E->next()) { - if (E->value() == p_idx) { - return E->key(); + for (const KeyValue<int, int> &E : base_scene_node_remap) { + if (E.value == p_idx) { + return E.key; } } return -1; @@ -1652,7 +1652,7 @@ Node *PackedScene::instantiate(GenEditState p_edit_state) const { } if (get_path() != "" && get_path().find("::") == -1) { - s->set_filename(get_path()); + s->set_scene_file_path(get_path()); } s->notification(Node::NOTIFICATION_INSTANCED); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 341ce22185..77d915aef9 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1653,55 +1653,55 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r #ifdef TOOLS_ENABLED // Keep order from cached ids. Set<String> cached_ids_found; - for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { - String cached_id = E->key()->get_id_for_path(local_path); + for (KeyValue<RES, String> &E : external_resources) { + String cached_id = E.key->get_id_for_path(local_path); if (cached_id == "" || cached_ids_found.has(cached_id)) { - int sep_pos = E->get().find("_"); + int sep_pos = E.value.find("_"); if (sep_pos != -1) { - E->get() = E->get().substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance. + E.value = E.value.substr(0, sep_pos + 1); // Keep the order found, for improved thread loading performance. } else { - E->get() = ""; + E.value = ""; } } else { - E->get() = cached_id; + E.value = cached_id; cached_ids_found.insert(cached_id); } } // Create IDs for non cached resources. - for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { - if (cached_ids_found.has(E->get())) { // Already cached, go on. + for (KeyValue<RES, String> &E : external_resources) { + if (cached_ids_found.has(E.value)) { // Already cached, go on. continue; } String attempt; while (true) { - attempt = E->get() + Resource::generate_scene_unique_id(); + attempt = E.value + Resource::generate_scene_unique_id(); if (!cached_ids_found.has(attempt)) { break; } } cached_ids_found.insert(attempt); - E->get() = attempt; + E.value = attempt; // Update also in resource. - Ref<Resource> res = E->key(); + Ref<Resource> res = E.key; res->set_id_for_path(local_path, attempt); } #else // Make sure to start from one, as it makes format more readable. int counter = 1; - for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { - E->get() = itos(counter++); + for (KeyValue<RES, String> &E : external_resources) { + E.value = itos(counter++); } #endif Vector<ResourceSort> sorted_er; - for (Map<RES, String>::Element *E = external_resources.front(); E; E = E->next()) { + for (const KeyValue<RES, String> &E : external_resources) { ResourceSort rs; - rs.resource = E->key(); - rs.id = E->get(); + rs.resource = E.key; + rs.id = E.value; sorted_er.push_back(rs); } diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 44d524f142..242e20f3b0 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -116,8 +116,8 @@ Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) cons } void Shader::get_default_texture_param_list(List<StringName> *r_textures) const { - for (const Map<StringName, Ref<Texture2D>>::Element *E = default_textures.front(); E; E = E->next()) { - r_textures->push_back(E->key()); + for (const KeyValue<StringName, Ref<Texture2D>> &E : default_textures) { + r_textures->push_back(E.key); } } diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index 140c6f821f..01afb00283 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -108,15 +108,15 @@ Vector<String> SpriteFrames::_get_animation_list() const { } void SpriteFrames::get_animation_list(List<StringName> *r_animations) const { - for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) { - r_animations->push_back(E->key()); + for (const KeyValue<StringName, Anim> &E : animations) { + r_animations->push_back(E.key); } } Vector<String> SpriteFrames::get_animation_names() const { Vector<String> names; - for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) { - names.push_back(E->key()); + for (const KeyValue<StringName, Anim> &E : animations) { + names.push_back(E.key); } names.sort(); return names; @@ -164,14 +164,14 @@ Array SpriteFrames::_get_frames() const { Array SpriteFrames::_get_animations() const { Array anims; - for (Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) { + for (const KeyValue<StringName, Anim> &E : animations) { Dictionary d; - d["name"] = E->key(); - d["speed"] = E->get().speed; - d["loop"] = E->get().loop; + d["name"] = E.key; + d["speed"] = E.value.speed; + d["loop"] = E.value.loop; Array frames; - for (int i = 0; i < E->get().frames.size(); i++) { - frames.push_back(E->get().frames[i]); + for (int i = 0; i < E.value.frames.size(); i++) { + frames.push_back(E.value.frames[i]); } d["frames"] = frames; anims.push_back(d); diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index d2f38ba836..0094518967 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -53,7 +53,7 @@ void TextLine::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "preserve_control"), "set_preserve_control", "get_preserve_control"); - ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::_set_bidi_override); + ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::set_bidi_override); ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL("")); ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1)); @@ -112,7 +112,7 @@ void TextLine::_shape() { TS->shaped_text_tab_align(rid, tab_stops); } - uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; + uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; if (overrun_behavior != OVERRUN_NO_TRIMMING) { switch (overrun_behavior) { case OVERRUN_TRIM_WORD_ELLIPSIS: @@ -195,15 +195,7 @@ TextServer::Orientation TextLine::get_orientation() const { return TS->shaped_text_get_orientation(rid); } -void TextLine::_set_bidi_override(const Array &p_override) { - Vector<Vector2i> overrides; - for (int i = 0; i < p_override.size(); i++) { - overrides.push_back(p_override[i]); - } - set_bidi_override(overrides); -} - -void TextLine::set_bidi_override(const Vector<Vector2i> &p_override) { +void TextLine::set_bidi_override(const Array &p_override) { TS->shaped_text_set_bidi_override(rid, p_override); dirty = true; } @@ -256,14 +248,14 @@ void TextLine::tab_align(const Vector<float> &p_tab_stops) { dirty = true; } -void TextLine::set_flags(uint8_t p_flags) { +void TextLine::set_flags(uint16_t p_flags) { if (flags != p_flags) { flags = p_flags; dirty = true; } } -uint8_t TextLine::get_flags() const { +uint16_t TextLine::get_flags() const { return flags; } diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h index 9ed9c2f177..43739f27ec 100644 --- a/scene/resources/text_line.h +++ b/scene/resources/text_line.h @@ -56,7 +56,7 @@ private: bool dirty = true; float width = -1.0; - uint8_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; + uint16_t flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; HAlign align = HALIGN_LEFT; OverrunBehavior overrun_behavior = OVERRUN_TRIM_ELLIPSIS; @@ -75,7 +75,7 @@ public: void set_direction(TextServer::Direction p_direction); TextServer::Direction get_direction() const; - void set_bidi_override(const Vector<Vector2i> &p_override); + void set_bidi_override(const Array &p_override); void set_orientation(TextServer::Orientation p_orientation); TextServer::Orientation get_orientation() const; @@ -95,8 +95,8 @@ public: void tab_align(const Vector<float> &p_tab_stops); - void set_flags(uint8_t p_flags); - uint8_t get_flags() const; + void set_flags(uint16_t p_flags); + uint16_t get_flags() const; void set_text_overrun_behavior(OverrunBehavior p_behavior); OverrunBehavior get_text_overrun_behavior() const; @@ -120,8 +120,6 @@ public: int hit_test(float p_coords) const; - void _set_bidi_override(const Array &p_override); - TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL); TextLine(); ~TextLine(); diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 62949b9b98..b2e18e2451 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -53,7 +53,7 @@ void TextParagraph::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "preserve_control"), "set_preserve_control", "get_preserve_control"); - ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextParagraph::_set_bidi_override); + ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextParagraph::set_bidi_override); ClassDB::bind_method(D_METHOD("set_dropcap", "text", "fonts", "size", "dropcap_margins", "opentype_features", "language"), &TextParagraph::set_dropcap, DEFVAL(Rect2()), DEFVAL(Dictionary()), DEFVAL("")); ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap); @@ -158,9 +158,9 @@ void TextParagraph::_shape_lines() { if (h_offset > 0) { // Dropcap, flow around. - Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(rid, width - h_offset, 0, flags); - for (int i = 0; i < line_breaks.size(); i++) { - RID line = TS->shaped_text_substr(rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x); + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width - h_offset, 0, flags); + for (int i = 0; i < line_breaks.size(); i = i + 2) { + RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x; if (v_offset < h) { TS->free(line); @@ -171,21 +171,21 @@ void TextParagraph::_shape_lines() { } dropcap_lines++; v_offset -= h; - start = line_breaks[i].y; + start = line_breaks[i + 1]; lines_rid.push_back(line); } } // Use fixed for the rest of lines. - Vector<Vector2i> line_breaks = TS->shaped_text_get_line_breaks(rid, width, start, flags); - for (int i = 0; i < line_breaks.size(); i++) { - RID line = TS->shaped_text_substr(rid, line_breaks[i].x, line_breaks[i].y - line_breaks[i].x); + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(rid, width, start, flags); + for (int i = 0; i < line_breaks.size(); i = i + 2) { + RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); if (!tab_stops.is_empty()) { TS->shaped_text_tab_align(line, tab_stops); } lines_rid.push_back(line); } - uint8_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; + uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIMMING; if (overrun_behavior != OVERRUN_NO_TRIMMING) { switch (overrun_behavior) { case OVERRUN_TRIM_WORD_ELLIPSIS: @@ -347,15 +347,7 @@ int TextParagraph::get_spacing_bottom() const { return spacing_bottom; } -void TextParagraph::_set_bidi_override(const Array &p_override) { - Vector<Vector2i> overrides; - for (int i = 0; i < p_override.size(); i++) { - overrides.push_back(p_override[i]); - } - set_bidi_override(overrides); -} - -void TextParagraph::set_bidi_override(const Vector<Vector2i> &p_override) { +void TextParagraph::set_bidi_override(const Array &p_override) { TS->shaped_text_set_bidi_override(rid, p_override); lines_dirty = true; } @@ -392,14 +384,14 @@ void TextParagraph::tab_align(const Vector<float> &p_tab_stops) { lines_dirty = true; } -void TextParagraph::set_flags(uint8_t p_flags) { +void TextParagraph::set_flags(uint16_t p_flags) { if (flags != p_flags) { flags = p_flags; lines_dirty = true; } } -uint8_t TextParagraph::get_flags() const { +uint16_t TextParagraph::get_flags() const { return flags; } diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index ee7bbab9c5..69c50559df 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -63,7 +63,7 @@ private: float width = -1.0; int max_lines_visible = -1; - uint8_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; + uint16_t flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA; OverrunBehavior overrun_behavior = OVERRUN_NO_TRIMMING; HAlign align = HALIGN_LEFT; @@ -94,7 +94,7 @@ public: void set_preserve_control(bool p_enabled); bool get_preserve_control() const; - void set_bidi_override(const Vector<Vector2i> &p_override); + void set_bidi_override(const Array &p_override); bool set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Dictionary &p_opentype_features = Dictionary(), const String &p_language = ""); void clear_dropcap(); @@ -108,8 +108,8 @@ public: void tab_align(const Vector<float> &p_tab_stops); - void set_flags(uint8_t p_flags); - uint8_t get_flags() const; + void set_flags(uint16_t p_flags); + uint16_t get_flags() const; void set_text_overrun_behavior(OverrunBehavior p_behavior); OverrunBehavior get_text_overrun_behavior() const; @@ -153,8 +153,6 @@ public: int hit_test(const Point2 &p_coords) const; - void _set_bidi_override(const Array &p_override); - TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL); TextParagraph(); ~TextParagraph(); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 80cab99373..1b3a7a5f2a 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1249,7 +1249,7 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const { } Ref<Image> AtlasTexture::get_image() const { - if (!atlas.is_valid()) { + if (!atlas.is_valid() || !atlas->get_image().is_valid()) { return Ref<Image>(); } diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 5a8c5b3782..40eedb63c1 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -66,8 +66,8 @@ const char *TileSet::CELL_NEIGHBOR_ENUM_TO_TEXT[] = { void TileSet::set_tile_shape(TileSet::TileShape p_shape) { tile_shape = p_shape; - for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) { - E_source->get()->notify_tile_data_properties_should_change(); + for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) { + E_source.value->notify_tile_data_properties_should_change(); } terrain_bits_meshes_dirty = true; @@ -89,8 +89,8 @@ TileSet::TileLayout TileSet::get_tile_layout() const { void TileSet::set_tile_offset_axis(TileSet::TileOffsetAxis p_alignment) { tile_offset_axis = p_alignment; - for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) { - E_source->get()->notify_tile_data_properties_should_change(); + for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) { + E_source.value->notify_tile_data_properties_should_change(); } terrain_bits_meshes_dirty = true; @@ -386,8 +386,8 @@ void TileSet::remove_terrain_set(int p_index) { void TileSet::set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode) { ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size()); terrain_sets.write[p_terrain_set].mode = p_terrain_mode; - for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) { - E_source->get()->notify_tile_data_properties_should_change(); + for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) { + E_source.value->notify_tile_data_properties_should_change(); } notify_property_list_changed(); @@ -719,8 +719,8 @@ void TileSet::set_custom_data_type(int p_layer_id, Variant::Type p_value) { ERR_FAIL_INDEX(p_layer_id, custom_data_layers.size()); custom_data_layers.write[p_layer_id].type = p_value; - for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) { - E_source->get()->notify_tile_data_properties_should_change(); + for (KeyValue<int, Ref<TileSetSource>> &E_source : sources) { + E_source.value->notify_tile_data_properties_should_change(); } emit_changed(); @@ -858,10 +858,10 @@ void TileSet::remove_alternative_level_tile_proxy(int p_source_from, Vector2i p_ Array TileSet::get_source_level_tile_proxies() const { Array output; - for (Map<int, int>::Element *E = source_level_proxies.front(); E; E = E->next()) { + for (const KeyValue<int, int> &E : source_level_proxies) { Array proxy; - proxy.push_back(E->key()); - proxy.push_back(E->get()); + proxy.push_back(E.key); + proxy.push_back(E.value); output.push_back(proxy); } return output; @@ -869,10 +869,10 @@ Array TileSet::get_source_level_tile_proxies() const { Array TileSet::get_coords_level_tile_proxies() const { Array output; - for (Map<Array, Array>::Element *E = coords_level_proxies.front(); E; E = E->next()) { + for (const KeyValue<Array, Array> &E : coords_level_proxies) { Array proxy; - proxy.append_array(E->key()); - proxy.append_array(E->get()); + proxy.append_array(E.key); + proxy.append_array(E.value); output.push_back(proxy); } return output; @@ -880,10 +880,10 @@ Array TileSet::get_coords_level_tile_proxies() const { Array TileSet::get_alternative_level_tile_proxies() const { Array output; - for (Map<Array, Array>::Element *E = alternative_level_proxies.front(); E; E = E->next()) { + for (const KeyValue<Array, Array> &E : alternative_level_proxies) { Array proxy; - proxy.append_array(E->key()); - proxy.append_array(E->get()); + proxy.append_array(E.key); + proxy.append_array(E.value); output.push_back(proxy); } return output; @@ -935,9 +935,9 @@ Array TileSet::map_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_a void TileSet::cleanup_invalid_tile_proxies() { // Source level. Vector<int> source_to_remove; - for (Map<int, int>::Element *E = source_level_proxies.front(); E; E = E->next()) { - if (has_source(E->key())) { - source_to_remove.append(E->key()); + for (const KeyValue<int, int> &E : source_level_proxies) { + if (has_source(E.key)) { + source_to_remove.append(E.key); } } for (int i = 0; i < source_to_remove.size(); i++) { @@ -946,8 +946,8 @@ void TileSet::cleanup_invalid_tile_proxies() { // Coords level. Vector<Array> coords_to_remove; - for (Map<Array, Array>::Element *E = coords_level_proxies.front(); E; E = E->next()) { - Array a = E->key(); + for (const KeyValue<Array, Array> &E : coords_level_proxies) { + Array a = E.key; if (has_source(a[0]) && get_source(a[0])->has_tile(a[1])) { coords_to_remove.append(a); } @@ -959,8 +959,8 @@ void TileSet::cleanup_invalid_tile_proxies() { // Alternative level. Vector<Array> alternative_to_remove; - for (Map<Array, Array>::Element *E = alternative_level_proxies.front(); E; E = E->next()) { - Array a = E->key(); + for (const KeyValue<Array, Array> &E : alternative_level_proxies) { + Array a = E.key; if (has_source(a[0]) && get_source(a[0])->has_tile(a[1]) && get_source(a[0])->has_alternative_tile(a[1], a[2])) { alternative_to_remove.append(a); } @@ -1911,8 +1911,8 @@ const int TileSetSource::INVALID_TILE_ALTERNATIVE = -1; #ifndef DISABLE_DEPRECATED void TileSet::_compatibility_conversion() { - for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) { - CompatibilityTileData *ctd = E->value(); + for (KeyValue<int, CompatibilityTileData *> &E : compatibility_data) { + CompatibilityTileData *ctd = E.value; // Add the texture TileSetAtlasSource *atlas_source = memnew(TileSetAtlasSource); @@ -1950,11 +1950,11 @@ void TileSet::_compatibility_conversion() { value_array.push_back(coords); value_array.push_back(alternative_tile); - if (!compatibility_tilemap_mapping.has(E->key())) { - compatibility_tilemap_mapping[E->key()] = Map<Array, Array>(); + if (!compatibility_tilemap_mapping.has(E.key)) { + compatibility_tilemap_mapping[E.key] = Map<Array, Array>(); } - compatibility_tilemap_mapping[E->key()][key_array] = value_array; - compatibility_tilemap_mapping_tile_modes[E->key()] = COMPATIBILITY_TILE_MODE_SINGLE_TILE; + compatibility_tilemap_mapping[E.key][key_array] = value_array; + compatibility_tilemap_mapping_tile_modes[E.key] = COMPATIBILITY_TILE_MODE_SINGLE_TILE; TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile)); @@ -2042,11 +2042,11 @@ void TileSet::_compatibility_conversion() { value_array.push_back(coords); value_array.push_back(alternative_tile); - if (!compatibility_tilemap_mapping.has(E->key())) { - compatibility_tilemap_mapping[E->key()] = Map<Array, Array>(); + if (!compatibility_tilemap_mapping.has(E.key)) { + compatibility_tilemap_mapping[E.key] = Map<Array, Array>(); } - compatibility_tilemap_mapping[E->key()][key_array] = value_array; - compatibility_tilemap_mapping_tile_modes[E->key()] = COMPATIBILITY_TILE_MODE_ATLAS_TILE; + compatibility_tilemap_mapping[E.key][key_array] = value_array; + compatibility_tilemap_mapping_tile_modes[E.key] = COMPATIBILITY_TILE_MODE_ATLAS_TILE; TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile)); @@ -2128,8 +2128,8 @@ void TileSet::_compatibility_conversion() { } // Reset compatibility data - for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<int, CompatibilityTileData *> &E : compatibility_data) { + memdelete(E.value); } compatibility_data = Map<int, CompatibilityTileData *>(); } @@ -2579,25 +2579,25 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { } else if (components.size() == 2 && components[0] == "tile_proxies") { if (components[1] == "source_level") { Array a; - for (Map<int, int>::Element *E = source_level_proxies.front(); E; E = E->next()) { - a.push_back(E->key()); - a.push_back(E->get()); + for (const KeyValue<int, int> &E : source_level_proxies) { + a.push_back(E.key); + a.push_back(E.value); } r_ret = a; return true; } else if (components[1] == "coords_level") { Array a; - for (Map<Array, Array>::Element *E = coords_level_proxies.front(); E; E = E->next()) { - a.push_back(E->key()); - a.push_back(E->get()); + for (const KeyValue<Array, Array> &E : coords_level_proxies) { + a.push_back(E.key); + a.push_back(E.value); } r_ret = a; return true; } else if (components[1] == "alternative_level") { Array a; - for (Map<Array, Array>::Element *E = alternative_level_proxies.front(); E; E = E->next()) { - a.push_back(E->key()); - a.push_back(E->get()); + for (const KeyValue<Array, Array> &E : alternative_level_proxies) { + a.push_back(E.key); + a.push_back(E.value); } r_ret = a; return true; @@ -2673,8 +2673,8 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { // Sources. // Note: sources have to be listed in at the end as some TileData rely on the TileSet properties being initialized first. - for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) { - p_list->push_back(PropertyInfo(Variant::INT, vformat("sources/%d", E_source->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + for (const KeyValue<int, Ref<TileSetSource>> &E_source : sources) { + p_list->push_back(PropertyInfo(Variant::INT, vformat("sources/%d", E_source.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } // Tile Proxies. @@ -2850,8 +2850,8 @@ TileSet::TileSet() { TileSet::~TileSet() { #ifndef DISABLE_DEPRECATED - for (Map<int, CompatibilityTileData *>::Element *E = compatibility_data.front(); E; E = E->next()) { - memdelete(E->get()); + for (const KeyValue<int, CompatibilityTileData *> &E : compatibility_data) { + memdelete(E.value); } #endif // DISABLE_DEPRECATED while (!source_ids.is_empty()) { @@ -2883,18 +2883,18 @@ void TileSetAtlasSource::set_tile_set(const TileSet *p_tile_set) { tile_set = p_tile_set; // Set the TileSet on all TileData. - for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) { - for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) { - E_alternative->get()->set_tile_set(tile_set); + for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) { + for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) { + E_alternative.value->set_tile_set(tile_set); } } } void TileSetAtlasSource::notify_tile_data_properties_should_change() { // Set the TileSet on all TileData. - for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) { - for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) { - E_alternative->get()->notify_tile_data_properties_should_change(); + for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) { + for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) { + E_alternative.value->notify_tile_data_properties_should_change(); } } } @@ -3045,9 +3045,9 @@ void TileSetAtlasSource::remove_custom_data_layer(int p_index) { void TileSetAtlasSource::reset_state() { // Reset all TileData. - for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) { - for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) { - E_alternative->get()->reset_state(); + for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) { + for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) { + E_alternative.value->reset_state(); } } } @@ -3124,7 +3124,7 @@ Vector2i TileSetAtlasSource::get_atlas_grid_size() const { } bool TileSetAtlasSource::_set(const StringName &p_name, const Variant &p_value) { - Vector<String> components = String(p_name).split("/", true, 3); + Vector<String> components = String(p_name).split("/", true, 2); // Compute the vector2i if we have coordinates. Vector<String> coords_split = components[0].split(":"); @@ -3260,40 +3260,40 @@ bool TileSetAtlasSource::_get(const StringName &p_name, Variant &r_ret) const { void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const { // Atlases data. PropertyInfo property_info; - for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) { + for (const KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) { List<PropertyInfo> tile_property_list; // size_in_atlas property_info = PropertyInfo(Variant::VECTOR2I, "size_in_atlas", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); - if (E_tile->get().size_in_atlas == Vector2i(1, 1)) { + if (E_tile.value.size_in_atlas == Vector2i(1, 1)) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } tile_property_list.push_back(property_info); // next_alternative_id property_info = PropertyInfo(Variant::INT, "next_alternative_id", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); - if (E_tile->get().next_alternative_id == 1) { + if (E_tile.value.next_alternative_id == 1) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } tile_property_list.push_back(property_info); // animation_columns. property_info = PropertyInfo(Variant::INT, "animation_columns", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); - if (E_tile->get().animation_columns == 0) { + if (E_tile.value.animation_columns == 0) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } tile_property_list.push_back(property_info); // animation_separation. property_info = PropertyInfo(Variant::INT, "animation_separation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); - if (E_tile->get().animation_separation == Vector2i()) { + if (E_tile.value.animation_separation == Vector2i()) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } tile_property_list.push_back(property_info); // animation_speed. property_info = PropertyInfo(Variant::FLOAT, "animation_speed", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); - if (E_tile->get().animation_speed == 1.0) { + if (E_tile.value.animation_speed == 1.0) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } tile_property_list.push_back(property_info); @@ -3302,8 +3302,8 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const { tile_property_list.push_back(PropertyInfo(Variant::INT, "animation_frames_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NETWORK)); // animation_frame_*. - bool store_durations = tiles[E_tile->key()].animation_frames_durations.size() >= 2; - for (int i = 0; i < (int)tiles[E_tile->key()].animation_frames_durations.size(); i++) { + bool store_durations = tiles[E_tile.key].animation_frames_durations.size() >= 2; + for (int i = 0; i < (int)tiles[E_tile.key].animation_frames_durations.size(); i++) { property_info = PropertyInfo(Variant::FLOAT, vformat("animation_frame_%d/duration", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR); if (!store_durations) { property_info.usage ^= PROPERTY_USAGE_STORAGE; @@ -3311,27 +3311,27 @@ void TileSetAtlasSource::_get_property_list(List<PropertyInfo> *p_list) const { tile_property_list.push_back(property_info); } - for (Map<int, TileData *>::Element *E_alternative = E_tile->get().alternatives.front(); E_alternative; E_alternative = E_alternative->next()) { + for (const KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) { // Add a dummy property to show the alternative exists. - tile_property_list.push_back(PropertyInfo(Variant::INT, vformat("%d", E_alternative->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + tile_property_list.push_back(PropertyInfo(Variant::INT, vformat("%d", E_alternative.key), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); // Get the alternative tile's properties and append them to the list of properties. List<PropertyInfo> alternative_property_list; - E_alternative->get()->get_property_list(&alternative_property_list); + E_alternative.value->get_property_list(&alternative_property_list); for (PropertyInfo &alternative_property_info : alternative_property_list) { Variant default_value = ClassDB::class_get_default_property_value("TileData", alternative_property_info.name); - Variant value = E_alternative->get()->get(alternative_property_info.name); + Variant value = E_alternative.value->get(alternative_property_info.name); if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) { alternative_property_info.usage ^= PROPERTY_USAGE_STORAGE; } - alternative_property_info.name = vformat("%s/%s", vformat("%d", E_alternative->key()), alternative_property_info.name); + alternative_property_info.name = vformat("%s/%s", vformat("%d", E_alternative.key), alternative_property_info.name); tile_property_list.push_back(alternative_property_info); } } // Add all alternative. for (PropertyInfo &tile_property_info : tile_property_list) { - tile_property_info.name = vformat("%s/%s", vformat("%d:%d", E_tile->key().x, E_tile->key().y), tile_property_info.name); + tile_property_info.name = vformat("%s/%s", vformat("%d:%d", E_tile.key.x, E_tile.key.y), tile_property_info.name); p_list->push_back(tile_property_info); } } @@ -3373,8 +3373,8 @@ void TileSetAtlasSource::remove_tile(Vector2i p_atlas_coords) { _clear_coords_mapping_cache(p_atlas_coords); // Free tile data. - for (Map<int, TileData *>::Element *E_tile_data = tiles[p_atlas_coords].alternatives.front(); E_tile_data; E_tile_data = E_tile_data->next()) { - memdelete(E_tile_data->get()); + for (const KeyValue<int, TileData *> &E_tile_data : tiles[p_atlas_coords].alternatives) { + memdelete(E_tile_data.value); } // Delete the tile @@ -3619,8 +3619,8 @@ bool TileSetAtlasSource::has_tiles_outside_texture() { Vector2i grid_size = get_atlas_grid_size(); Vector<Vector2i> to_remove; - for (Map<Vector2i, TileSetAtlasSource::TileAlternativesData>::Element *E = tiles.front(); E; E = E->next()) { - if (E->key().x >= grid_size.x || E->key().y >= grid_size.y) { + for (const KeyValue<Vector2i, TileSetAtlasSource::TileAlternativesData> &E : tiles) { + if (E.key.x >= grid_size.x || E.key.y >= grid_size.y) { return true; } } @@ -3632,9 +3632,9 @@ void TileSetAtlasSource::clear_tiles_outside_texture() { Vector2i grid_size = get_atlas_grid_size(); Vector<Vector2i> to_remove; - for (Map<Vector2i, TileSetAtlasSource::TileAlternativesData>::Element *E = tiles.front(); E; E = E->next()) { - if (E->key().x >= grid_size.x || E->key().y >= grid_size.y) { - to_remove.append(E->key()); + for (const KeyValue<Vector2i, TileSetAtlasSource::TileAlternativesData> &E : tiles) { + if (E.key.x >= grid_size.x || E.key.y >= grid_size.y) { + to_remove.append(E.key); } } @@ -3775,9 +3775,9 @@ void TileSetAtlasSource::_bind_methods() { TileSetAtlasSource::~TileSetAtlasSource() { // Free everything needed. - for (Map<Vector2i, TileAlternativesData>::Element *E_alternatives = tiles.front(); E_alternatives; E_alternatives = E_alternatives->next()) { - for (Map<int, TileData *>::Element *E_tile_data = E_alternatives->get().alternatives.front(); E_tile_data; E_tile_data = E_tile_data->next()) { - memdelete(E_tile_data->get()); + for (KeyValue<Vector2i, TileAlternativesData> &E_alternatives : tiles) { + for (KeyValue<int, TileData *> &E_tile_data : E_alternatives.value.alternatives) { + memdelete(E_tile_data.value); } } } @@ -4316,9 +4316,26 @@ Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id) const { } // Physics -int TileData::get_collision_polygons_count(int p_layer_id) const { - ERR_FAIL_INDEX_V(p_layer_id, physics.size(), 0); - return physics[p_layer_id].polygons.size(); +void TileData::set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity) { + ERR_FAIL_INDEX(p_layer_id, physics.size()); + physics.write[p_layer_id].linear_velocity = p_velocity; + emit_signal(SNAME("changed")); +} + +Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const { + ERR_FAIL_INDEX_V(p_layer_id, physics.size(), Vector2()); + return physics[p_layer_id].linear_velocity; +} + +void TileData::set_constant_angular_velocity(int p_layer_id, real_t p_velocity) { + ERR_FAIL_INDEX(p_layer_id, physics.size()); + physics.write[p_layer_id].angular_velocity = p_velocity; + emit_signal(SNAME("changed")); +} + +real_t TileData::get_constant_angular_velocity(int p_layer_id) const { + ERR_FAIL_INDEX_V(p_layer_id, physics.size(), 0.0); + return physics[p_layer_id].angular_velocity; } void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count) { @@ -4329,6 +4346,11 @@ void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count emit_signal(SNAME("changed")); } +int TileData::get_collision_polygons_count(int p_layer_id) const { + ERR_FAIL_INDEX_V(p_layer_id, physics.size(), 0); + return physics[p_layer_id].polygons.size(); +} + void TileData::add_collision_polygon(int p_layer_id) { ERR_FAIL_INDEX(p_layer_id, physics.size()); physics.write[p_layer_id].polygons.push_back(PhysicsLayerTileData::PolygonShapeTileData()); @@ -4530,11 +4552,7 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) { // Physics layers. int layer_index = components[0].trim_prefix("physics_layer_").to_int(); ERR_FAIL_COND_V(layer_index < 0, false); - if (components.size() == 2 && components[1] == "polygons_count") { - if (p_value.get_type() != Variant::INT) { - return false; - } - + if (components.size() == 2) { if (layer_index >= physics.size()) { if (tile_set) { return false; @@ -4542,8 +4560,19 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) { physics.resize(layer_index + 1); } } - set_collision_polygons_count(layer_index, p_value); - return true; + if (components[1] == "linear_velocity") { + set_constant_linear_velocity(layer_index, p_value); + return true; + } else if (components[1] == "angular_velocity") { + set_constant_angular_velocity(layer_index, p_value); + return true; + } else if (components[1] == "polygons_count") { + if (p_value.get_type() != Variant::INT) { + return false; + } + set_collision_polygons_count(layer_index, p_value); + return true; + } } else if (components.size() == 3 && components[1].begins_with("polygon_") && components[1].trim_prefix("polygon_").is_valid_int()) { int polygon_index = components[1].trim_prefix("polygon_").to_int(); ERR_FAIL_COND_V(polygon_index < 0, false); @@ -4645,9 +4674,18 @@ bool TileData::_get(const StringName &p_name, Variant &r_ret) const { if (layer_index >= physics.size()) { return false; } - if (components.size() == 2 && components[1] == "polygons_count") { - r_ret = get_collision_polygons_count(layer_index); - return true; + + if (components.size() == 2) { + if (components[1] == "linear_velocity") { + r_ret = get_constant_linear_velocity(layer_index); + return true; + } else if (components[1] == "angular_velocity") { + r_ret = get_constant_angular_velocity(layer_index); + return true; + } else if (components[1] == "polygons_count") { + r_ret = get_collision_polygons_count(layer_index); + return true; + } } else if (components.size() == 3 && components[1].begins_with("polygon_") && components[1].trim_prefix("polygon_").is_valid_int()) { int polygon_index = components[1].trim_prefix("polygon_").to_int(); ERR_FAIL_COND_V(polygon_index < 0, false); @@ -4718,6 +4756,8 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { // Physics layers. p_list->push_back(PropertyInfo(Variant::NIL, "Physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); for (int i = 0; i < physics.size(); i++) { + p_list->push_back(PropertyInfo(Variant::VECTOR2, vformat("physics_layer_%d/linear_velocity", i), PROPERTY_HINT_NONE)); + p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/angular_velocity", i), PROPERTY_HINT_NONE)); p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/polygons_count", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); for (int j = 0; j < physics[i].polygons.size(); j++) { @@ -4807,8 +4847,12 @@ void TileData::_bind_methods() { ClassDB::bind_method(D_METHOD("get_occluder", "layer_id"), &TileData::get_occluder); // Physics. - ClassDB::bind_method(D_METHOD("get_collision_polygons_count", "layer_id"), &TileData::get_collision_polygons_count); + ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "layer_id", "velocity"), &TileData::set_constant_linear_velocity); + ClassDB::bind_method(D_METHOD("get_constant_linear_velocity", "layer_id"), &TileData::get_constant_linear_velocity); + ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "layer_id", "velocity"), &TileData::set_constant_angular_velocity); + ClassDB::bind_method(D_METHOD("get_constant_angular_velocity", "layer_id"), &TileData::get_constant_angular_velocity); ClassDB::bind_method(D_METHOD("set_collision_polygons_count", "layer_id", "polygons_count"), &TileData::set_collision_polygons_count); + ClassDB::bind_method(D_METHOD("get_collision_polygons_count", "layer_id"), &TileData::get_collision_polygons_count); ClassDB::bind_method(D_METHOD("add_collision_polygon", "layer_id"), &TileData::add_collision_polygon); ClassDB::bind_method(D_METHOD("remove_collision_polygon", "layer_id", "polygon_index"), &TileData::remove_collision_polygon); ClassDB::bind_method(D_METHOD("set_collision_polygon_points", "layer_id", "polygon_index", "polygon"), &TileData::set_collision_polygon_points); diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 46cb1fb36d..2b4929b3df 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -645,6 +645,8 @@ private: float one_way_margin = 1.0; }; + Vector2 linear_velocity; + float angular_velocity = 0.0; Vector<PolygonShapeTileData> polygons; }; Vector<PhysicsLayerTileData> physics; @@ -718,8 +720,12 @@ public: Ref<OccluderPolygon2D> get_occluder(int p_layer_id) const; // Physics - int get_collision_polygons_count(int p_layer_id) const; + void set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity); + Vector2 get_constant_linear_velocity(int p_layer_id) const; + void set_constant_angular_velocity(int p_layer_id, real_t p_velocity); + real_t get_constant_angular_velocity(int p_layer_id) const; void set_collision_polygons_count(int p_layer_id, int p_shapes_count); + int get_collision_polygons_count(int p_layer_id) const; void add_collision_polygon(int p_layer_id); void remove_collision_polygon(int p_layer_id, int p_polygon_index); void set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index e8fe3ff3cd..934d16bd7e 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -197,9 +197,9 @@ Vector<StringName> VisualShaderNode::get_editable_properties() const { Array VisualShaderNode::get_default_input_values() const { Array ret; - for (Map<int, Variant>::Element *E = default_input_values.front(); E; E = E->next()) { - ret.push_back(E->key()); - ret.push_back(E->get()); + for (const KeyValue<int, Variant> &E : default_input_values) { + ret.push_back(E.key); + ret.push_back(E.value); } return ret; } @@ -460,14 +460,14 @@ Dictionary VisualShader::get_engine_version() const { void VisualShader::update_engine_version(const Dictionary &p_new_version) { if (engine_version.is_empty()) { // before 4.0 for (int i = 0; i < TYPE_MAX; i++) { - for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { - Ref<VisualShaderNodeInput> input = Object::cast_to<VisualShaderNodeInput>(E->get().node.ptr()); + for (KeyValue<int, Node> &E : graph[i].nodes) { + Ref<VisualShaderNodeInput> input = Object::cast_to<VisualShaderNodeInput>(E.value.node.ptr()); if (input.is_valid()) { if (input->get_input_name() == "side") { input->set_input_name("front_facing"); } } - Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr()); + Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E.value.node.ptr()); if (expression.is_valid()) { for (int j = 0; j < expression->get_input_port_count(); j++) { int type = expression->get_input_port_type(j); @@ -484,7 +484,7 @@ void VisualShader::update_engine_version(const Dictionary &p_new_version) { expression->set_output_port_type(j, type); } } - Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E->get().node.ptr()); + Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E.value.node.ptr()); if (compare.is_valid()) { int ctype = int(compare->get_comparison_type()); if (int(ctype) > 0) { // + PORT_TYPE_SCALAR_INT @@ -561,8 +561,8 @@ Vector<int> VisualShader::get_node_list(Type p_type) const { const Graph *g = &graph[p_type]; Vector<int> ret; - for (Map<int, Node>::Element *E = g->nodes.front(); E; E = E->next()) { - ret.push_back(E->key()); + for (const KeyValue<int, Node> &E : g->nodes) { + ret.push_back(E.key); } return ret; @@ -575,9 +575,9 @@ int VisualShader::get_valid_node_id(Type p_type) const { } int VisualShader::find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const { - for (const Map<int, Node>::Element *E = graph[p_type].nodes.front(); E; E = E->next()) { - if (E->get().node == p_node) { - return E->key(); + for (const KeyValue<int, Node> &E : graph[p_type].nodes) { + if (E.value.node == p_node) { + return E.key; } } @@ -819,8 +819,8 @@ void VisualShader::set_mode(Mode p_mode) { flags.clear(); shader_mode = p_mode; for (int i = 0; i < TYPE_MAX; i++) { - for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { - Ref<VisualShaderNodeInput> input = E->get().node; + for (KeyValue<int, Node> &E : graph[i].nodes) { + Ref<VisualShaderNodeInput> input = E.value.node; if (input.is_valid()) { input->shader_mode = shader_mode; //input->input_index = 0; @@ -1041,8 +1041,8 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua while (true) { bool exists = false; for (int i = 0; i < TYPE_MAX; i++) { - for (const Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { - Ref<VisualShaderNodeUniform> node = E->get().node; + for (const KeyValue<int, Node> &E : graph[i].nodes) { + Ref<VisualShaderNodeUniform> node = E.value.node; if (node == p_uniform) { //do not test on self continue; } @@ -1271,8 +1271,8 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } } - for (Map<String, String>::Element *E = blend_mode_enums.front(); E; E = E->next()) { - p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E->key(), PROPERTY_HINT_ENUM, E->get())); + for (const KeyValue<String, String> &E : blend_mode_enums) { + p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E.key, PROPERTY_HINT_ENUM, E.value)); } for (Set<String>::Element *E = toggles.front(); E; E = E->next()) { @@ -1280,22 +1280,22 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } for (int i = 0; i < TYPE_MAX; i++) { - for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { + for (const KeyValue<int, Node> &E : graph[i].nodes) { String prop_name = "nodes/"; prop_name += type_string[i]; - prop_name += "/" + itos(E->key()); + prop_name += "/" + itos(E.key); - if (E->key() != NODE_ID_OUTPUT) { + if (E.key != NODE_ID_OUTPUT) { p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE)); } p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - if (Object::cast_to<VisualShaderNodeGroupBase>(E->get().node.ptr()) != nullptr) { + if (Object::cast_to<VisualShaderNodeGroupBase>(E.value.node.ptr()) != nullptr) { p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/input_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/output_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } - if (Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr()) != nullptr) { + if (Object::cast_to<VisualShaderNodeExpression>(E.value.node.ptr()) != nullptr) { p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } } @@ -1716,9 +1716,9 @@ void VisualShader::_update_shader() const { emitters.insert(i, List<int>()); } - for (Map<int, Node>::Element *M = graph[i].nodes.front(); M; M = M->next()) { - if (M->get().node == emit_particle.ptr()) { - emitters[i].push_back(M->key()); + for (const KeyValue<int, Node> &M : graph[i].nodes) { + if (M.value.node == emit_particle.ptr()) { + emitters[i].push_back(M.key); break; } } diff --git a/servers/SCsub b/servers/SCsub index 121990f2e1..76c11724d3 100644 --- a/servers/SCsub +++ b/servers/SCsub @@ -11,6 +11,7 @@ SConscript("physics_3d/SCsub") SConscript("physics_2d/SCsub") SConscript("rendering/SCsub") SConscript("audio/SCsub") +SConscript("text/SCsub") lib = env.add_library("servers", env.servers_sources) diff --git a/servers/display_server.cpp b/servers/display_server.cpp index cdf892094d..3897e5e7c2 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -285,6 +285,10 @@ String DisplayServer::keyboard_get_layout_name(int p_index) const { return "Not supported"; } +Key DisplayServer::keyboard_get_keycode_from_physical(Key p_keycode) const { + ERR_FAIL_V_MSG(p_keycode, "Not supported by this display server."); +} + void DisplayServer::force_process_and_drop_events() { } @@ -452,6 +456,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("keyboard_set_current_layout", "index"), &DisplayServer::keyboard_set_current_layout); ClassDB::bind_method(D_METHOD("keyboard_get_layout_language", "index"), &DisplayServer::keyboard_get_layout_language); ClassDB::bind_method(D_METHOD("keyboard_get_layout_name", "index"), &DisplayServer::keyboard_get_layout_name); + ClassDB::bind_method(D_METHOD("keyboard_get_keycode_from_physical", "keycode"), &DisplayServer::keyboard_get_keycode_from_physical); ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events); ClassDB::bind_method(D_METHOD("force_process_and_drop_events"), &DisplayServer::force_process_and_drop_events); diff --git a/servers/display_server.h b/servers/display_server.h index 788206768c..f411a72aa3 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -343,6 +343,7 @@ public: virtual void keyboard_set_current_layout(int p_index); virtual String keyboard_get_layout_language(int p_index) const; virtual String keyboard_get_layout_name(int p_index) const; + virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const; virtual int tablet_get_driver_count() const { return 1; }; virtual String tablet_get_driver_name(int p_driver) const { return "default"; }; diff --git a/servers/physics_2d/body_direct_state_2d_sw.cpp b/servers/physics_2d/body_direct_state_2d_sw.cpp index 1e924a831e..1c6adfe27c 100644 --- a/servers/physics_2d/body_direct_state_2d_sw.cpp +++ b/servers/physics_2d/body_direct_state_2d_sw.cpp @@ -169,22 +169,6 @@ Vector2 PhysicsDirectBodyState2DSW::get_contact_collider_velocity_at_position(in return body->contacts[p_contact_idx].collider_velocity_at_pos; } -Variant PhysicsDirectBodyState2DSW::get_contact_collider_shape_metadata(int p_contact_idx) const { - ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Variant()); - - if (!PhysicsServer2DSW::singletonsw->body_owner.owns(body->contacts[p_contact_idx].collider)) { - return Variant(); - } - Body2DSW *other = PhysicsServer2DSW::singletonsw->body_owner.getornull(body->contacts[p_contact_idx].collider); - - int sidx = body->contacts[p_contact_idx].collider_shape; - if (sidx < 0 || sidx >= other->get_shape_count()) { - return Variant(); - } - - return other->get_shape_metadata(sidx); -} - PhysicsDirectSpaceState2D *PhysicsDirectBodyState2DSW::get_space_state() { return body->get_space()->get_direct_state(); } diff --git a/servers/physics_2d/body_direct_state_2d_sw.h b/servers/physics_2d/body_direct_state_2d_sw.h index 34faa174d8..4266b24842 100644 --- a/servers/physics_2d/body_direct_state_2d_sw.h +++ b/servers/physics_2d/body_direct_state_2d_sw.h @@ -80,7 +80,6 @@ public: virtual Vector2 get_contact_collider_position(int p_contact_idx) const override; virtual ObjectID get_contact_collider_id(int p_contact_idx) const override; virtual int get_contact_collider_shape(int p_contact_idx) const override; - virtual Variant get_contact_collider_shape_metadata(int p_contact_idx) const override; virtual Vector2 get_contact_collider_velocity_at_position(int p_contact_idx) const override; diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index c92f01d120..bc7d277152 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -61,11 +61,6 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) { } } -void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) { - ERR_FAIL_INDEX(p_index, shapes.size()); - shapes.write[p_index].metadata = p_metadata; -} - void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) { ERR_FAIL_INDEX(p_index, shapes.size()); diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 69487631a6..ca258a906a 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -58,7 +58,6 @@ private: BroadPhase2DSW::ID bpid = 0; Rect2 aabb_cache; //for rayqueries Shape2DSW *shape = nullptr; - Variant metadata; bool disabled = false; bool one_way_collision = false; real_t one_way_collision_margin = 0.0; @@ -110,7 +109,6 @@ public: void add_shape(Shape2DSW *p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false); void set_shape(int p_index, Shape2DSW *p_shape); void set_shape_transform(int p_index, const Transform2D &p_transform); - void set_shape_metadata(int p_index, const Variant &p_metadata); _FORCE_INLINE_ int get_shape_count() const { return shapes.size(); } _FORCE_INLINE_ Shape2DSW *get_shape(int p_index) const { @@ -129,10 +127,6 @@ public: CRASH_BAD_INDEX(p_index, shapes.size()); return shapes[p_index].aabb_cache; } - _FORCE_INLINE_ const Variant &get_shape_metadata(int p_index) const { - CRASH_BAD_INDEX(p_index, shapes.size()); - return shapes[p_index].metadata; - } _FORCE_INLINE_ const Transform2D &get_transform() const { return transform; } _FORCE_INLINE_ const Transform2D &get_inv_transform() const { return inv_transform; } diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index e052258a92..4315b55df4 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -112,32 +112,32 @@ RID PhysicsServer2DSW::concave_polygon_shape_create() { } void PhysicsServer2DSW::shape_set_data(RID p_shape, const Variant &p_data) { - Shape2DSW *shape = shape_owner.getornull(p_shape); + Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); shape->set_data(p_data); }; void PhysicsServer2DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { - Shape2DSW *shape = shape_owner.getornull(p_shape); + Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); shape->set_custom_bias(p_bias); } PhysicsServer2D::ShapeType PhysicsServer2DSW::shape_get_type(RID p_shape) const { - const Shape2DSW *shape = shape_owner.getornull(p_shape); + const Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); return shape->get_type(); }; Variant PhysicsServer2DSW::shape_get_data(RID p_shape) const { - const Shape2DSW *shape = shape_owner.getornull(p_shape); + const Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, Variant()); ERR_FAIL_COND_V(!shape->is_configured(), Variant()); return shape->get_data(); }; real_t PhysicsServer2DSW::shape_get_custom_solver_bias(RID p_shape) const { - const Shape2DSW *shape = shape_owner.getornull(p_shape); + const Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); return shape->get_custom_bias(); } @@ -193,9 +193,9 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & } bool PhysicsServer2DSW::shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) { - Shape2DSW *shape_A = shape_owner.getornull(p_shape_A); + Shape2DSW *shape_A = shape_owner.get_or_null(p_shape_A); ERR_FAIL_COND_V(!shape_A, false); - Shape2DSW *shape_B = shape_owner.getornull(p_shape_B); + Shape2DSW *shape_B = shape_owner.get_or_null(p_shape_B); ERR_FAIL_COND_V(!shape_B, false); if (p_result_max == 0) { @@ -218,7 +218,7 @@ RID PhysicsServer2DSW::space_create() { RID id = space_owner.make_rid(space); space->set_self(id); RID area_id = area_create(); - Area2DSW *area = area_owner.getornull(area_id); + Area2DSW *area = area_owner.get_or_null(area_id); ERR_FAIL_COND_V(!area, RID()); space->set_default_area(area); area->set_space(space); @@ -228,7 +228,7 @@ RID PhysicsServer2DSW::space_create() { }; void PhysicsServer2DSW::space_set_active(RID p_space, bool p_active) { - Space2DSW *space = space_owner.getornull(p_space); + Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); if (p_active) { active_spaces.insert(space); @@ -238,45 +238,45 @@ void PhysicsServer2DSW::space_set_active(RID p_space, bool p_active) { } bool PhysicsServer2DSW::space_is_active(RID p_space) const { - const Space2DSW *space = space_owner.getornull(p_space); + const Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, false); return active_spaces.has(space); } void PhysicsServer2DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - Space2DSW *space = space_owner.getornull(p_space); + Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); space->set_param(p_param, p_value); } real_t PhysicsServer2DSW::space_get_param(RID p_space, SpaceParameter p_param) const { - const Space2DSW *space = space_owner.getornull(p_space); + const Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_param(p_param); } void PhysicsServer2DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) { - Space2DSW *space = space_owner.getornull(p_space); + Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); space->set_debug_contacts(p_max_contacts); } Vector<Vector2> PhysicsServer2DSW::space_get_contacts(RID p_space) const { - Space2DSW *space = space_owner.getornull(p_space); + Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, Vector<Vector2>()); return space->get_debug_contacts(); } int PhysicsServer2DSW::space_get_contact_count(RID p_space) const { - Space2DSW *space = space_owner.getornull(p_space); + Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_debug_contact_count(); } PhysicsDirectSpaceState2D *PhysicsServer2DSW::space_get_direct_state(RID p_space) { - Space2DSW *space = space_owner.getornull(p_space); + Space2DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, nullptr); ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); @@ -291,12 +291,12 @@ RID PhysicsServer2DSW::area_create() { }; void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); Space2DSW *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } @@ -309,7 +309,7 @@ void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) { }; RID PhysicsServer2DSW::area_get_space(RID p_area) const { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, RID()); Space2DSW *space = area->get_space(); @@ -320,34 +320,34 @@ RID PhysicsServer2DSW::area_get_space(RID p_area) const { }; void PhysicsServer2DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_space_override_mode(p_mode); } PhysicsServer2D::AreaSpaceOverrideMode PhysicsServer2DSW::area_get_space_override_mode(RID p_area) const { - const Area2DSW *area = area_owner.getornull(p_area); + const Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); return area->get_space_override_mode(); } void PhysicsServer2DSW::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform, bool p_disabled) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - Shape2DSW *shape = shape_owner.getornull(p_shape); + Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); area->add_shape(shape, p_transform, p_disabled); } void PhysicsServer2DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - Shape2DSW *shape = shape_owner.getornull(p_shape); + Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); ERR_FAIL_COND(!shape->is_configured()); @@ -355,14 +355,14 @@ void PhysicsServer2DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) } void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_shape_transform(p_shape_idx, p_transform); } void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); ERR_FAIL_INDEX(p_shape, area->get_shape_count()); FLUSH_QUERY_CHECK(area); @@ -371,14 +371,14 @@ void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_ } int PhysicsServer2DSW::area_get_shape_count(RID p_area) const { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, -1); return area->get_shape_count(); } RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, RID()); Shape2DSW *shape = area->get_shape(p_shape_idx); @@ -388,21 +388,21 @@ RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const { } Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Transform2D()); return area->get_shape_transform(p_shape_idx); } void PhysicsServer2DSW::area_remove_shape(RID p_area, int p_shape_idx) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->remove_shape(p_shape_idx); } void PhysicsServer2DSW::area_clear_shapes(RID p_area) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); while (area->get_shape_count()) { @@ -412,86 +412,86 @@ void PhysicsServer2DSW::area_clear_shapes(RID p_area) { void PhysicsServer2DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) { if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.getornull(p_area); + Space2DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_instance_id(p_id); } ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.getornull(p_area); + Space2DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, ObjectID()); return area->get_instance_id(); } void PhysicsServer2DSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_id) { if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.getornull(p_area); + Space2DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_canvas_instance_id(p_id); } ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.getornull(p_area); + Space2DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, ObjectID()); return area->get_canvas_instance_id(); } void PhysicsServer2DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.getornull(p_area); + Space2DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_param(p_param, p_value); }; void PhysicsServer2DSW::area_set_transform(RID p_area, const Transform2D &p_transform) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); }; Variant PhysicsServer2DSW::area_get_param(RID p_area, AreaParameter p_param) const { if (space_owner.owns(p_area)) { - Space2DSW *space = space_owner.getornull(p_area); + Space2DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Variant()); return area->get_param(p_param); }; Transform2D PhysicsServer2DSW::area_get_transform(RID p_area) const { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Transform2D()); return area->get_transform(); }; void PhysicsServer2DSW::area_set_pickable(RID p_area, bool p_pickable) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_pickable(p_pickable); } void PhysicsServer2DSW::area_set_monitorable(RID p_area, bool p_monitorable) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); FLUSH_QUERY_CHECK(area); @@ -499,28 +499,28 @@ void PhysicsServer2DSW::area_set_monitorable(RID p_area, bool p_monitorable) { } void PhysicsServer2DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_collision_mask(p_mask); } void PhysicsServer2DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_collision_layer(p_layer); } void PhysicsServer2DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); } void PhysicsServer2DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area2DSW *area = area_owner.getornull(p_area); + Area2DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); @@ -536,11 +536,11 @@ RID PhysicsServer2DSW::body_create() { } void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); Space2DSW *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } @@ -553,7 +553,7 @@ void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) { }; RID PhysicsServer2DSW::body_get_space(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, RID()); Space2DSW *space = body->get_space(); @@ -564,7 +564,7 @@ RID PhysicsServer2DSW::body_get_space(RID p_body) const { }; void PhysicsServer2DSW::body_set_mode(RID p_body, BodyMode p_mode) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); FLUSH_QUERY_CHECK(body); @@ -572,27 +572,27 @@ void PhysicsServer2DSW::body_set_mode(RID p_body, BodyMode p_mode) { }; PhysicsServer2D::BodyMode PhysicsServer2DSW::body_get_mode(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); return body->get_mode(); }; void PhysicsServer2DSW::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform, bool p_disabled) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - Shape2DSW *shape = shape_owner.getornull(p_shape); + Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); body->add_shape(shape, p_transform, p_disabled); } void PhysicsServer2DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - Shape2DSW *shape = shape_owner.getornull(p_shape); + Shape2DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); ERR_FAIL_COND(!shape->is_configured()); @@ -600,33 +600,21 @@ void PhysicsServer2DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) } void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_shape_transform(p_shape_idx, p_transform); } -void PhysicsServer2DSW::body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant &p_metadata) { - Body2DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND(!body); - body->set_shape_metadata(p_shape_idx, p_metadata); -} - -Variant PhysicsServer2DSW::body_get_shape_metadata(RID p_body, int p_shape_idx) const { - Body2DSW *body = body_owner.getornull(p_body); - ERR_FAIL_COND_V(!body, Variant()); - return body->get_shape_metadata(p_shape_idx); -} - int PhysicsServer2DSW::body_get_shape_count(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_shape_count(); } RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, RID()); Shape2DSW *shape = body->get_shape(p_shape_idx); @@ -636,21 +624,21 @@ RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const { } Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Transform2D()); return body->get_shape_transform(p_shape_idx); } void PhysicsServer2DSW::body_remove_shape(RID p_body, int p_shape_idx) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->remove_shape(p_shape_idx); } void PhysicsServer2DSW::body_clear_shapes(RID p_body) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); while (body->get_shape_count()) { @@ -659,7 +647,7 @@ void PhysicsServer2DSW::body_clear_shapes(RID p_body) { } void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); FLUSH_QUERY_CHECK(body); @@ -668,7 +656,7 @@ void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo } void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); FLUSH_QUERY_CHECK(body); @@ -677,109 +665,109 @@ void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_sh } void PhysicsServer2DSW::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_continuous_collision_detection_mode(p_mode); } PhysicsServer2DSW::CCDMode PhysicsServer2DSW::body_get_continuous_collision_detection_mode(RID p_body) const { - const Body2DSW *body = body_owner.getornull(p_body); + const Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, CCD_MODE_DISABLED); return body->get_continuous_collision_detection_mode(); } void PhysicsServer2DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_instance_id(p_id); }; ObjectID PhysicsServer2DSW::body_get_object_instance_id(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, ObjectID()); return body->get_instance_id(); }; void PhysicsServer2DSW::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_canvas_instance_id(p_id); }; ObjectID PhysicsServer2DSW::body_get_canvas_instance_id(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, ObjectID()); return body->get_canvas_instance_id(); }; void PhysicsServer2DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); }; uint32_t PhysicsServer2DSW::body_get_collision_layer(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_layer(); }; void PhysicsServer2DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); }; uint32_t PhysicsServer2DSW::body_get_collision_mask(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_mask(); }; void PhysicsServer2DSW::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_param(p_param, p_value); }; Variant PhysicsServer2DSW::body_get_param(RID p_body, BodyParameter p_param) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_param(p_param); }; void PhysicsServer2DSW::body_reset_mass_properties(RID p_body) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); return body->reset_mass_properties(); } void PhysicsServer2DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_state(p_state, p_variant); }; Variant PhysicsServer2DSW::body_get_state(RID p_body, BodyState p_state) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Variant()); return body->get_state(p_state); }; void PhysicsServer2DSW::body_set_applied_force(RID p_body, const Vector2 &p_force) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_applied_force(p_force); @@ -787,13 +775,13 @@ void PhysicsServer2DSW::body_set_applied_force(RID p_body, const Vector2 &p_forc }; Vector2 PhysicsServer2DSW::body_get_applied_force(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Vector2()); return body->get_applied_force(); }; void PhysicsServer2DSW::body_set_applied_torque(RID p_body, real_t p_torque) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_applied_torque(p_torque); @@ -801,14 +789,14 @@ void PhysicsServer2DSW::body_set_applied_torque(RID p_body, real_t p_torque) { }; real_t PhysicsServer2DSW::body_get_applied_torque(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_applied_torque(); }; void PhysicsServer2DSW::body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->apply_central_impulse(p_impulse); @@ -816,7 +804,7 @@ void PhysicsServer2DSW::body_apply_central_impulse(RID p_body, const Vector2 &p_ } void PhysicsServer2DSW::body_apply_torque_impulse(RID p_body, real_t p_torque) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); _update_shapes(); @@ -826,7 +814,7 @@ void PhysicsServer2DSW::body_apply_torque_impulse(RID p_body, real_t p_torque) { } void PhysicsServer2DSW::body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); _update_shapes(); @@ -836,7 +824,7 @@ void PhysicsServer2DSW::body_apply_impulse(RID p_body, const Vector2 &p_impulse, }; void PhysicsServer2DSW::body_add_central_force(RID p_body, const Vector2 &p_force) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_central_force(p_force); @@ -844,7 +832,7 @@ void PhysicsServer2DSW::body_add_central_force(RID p_body, const Vector2 &p_forc }; void PhysicsServer2DSW::body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_force(p_force, p_position); @@ -852,7 +840,7 @@ void PhysicsServer2DSW::body_add_force(RID p_body, const Vector2 &p_force, const }; void PhysicsServer2DSW::body_add_torque(RID p_body, real_t p_torque) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_torque(p_torque); @@ -860,7 +848,7 @@ void PhysicsServer2DSW::body_add_torque(RID p_body, real_t p_torque) { }; void PhysicsServer2DSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); _update_shapes(); @@ -874,7 +862,7 @@ void PhysicsServer2DSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis }; void PhysicsServer2DSW::body_add_collision_exception(RID p_body, RID p_body_b) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_exception(p_body_b); @@ -882,7 +870,7 @@ void PhysicsServer2DSW::body_add_collision_exception(RID p_body, RID p_body_b) { }; void PhysicsServer2DSW::body_remove_collision_exception(RID p_body, RID p_body_b) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->remove_exception(p_body_b); @@ -890,7 +878,7 @@ void PhysicsServer2DSW::body_remove_collision_exception(RID p_body, RID p_body_b }; void PhysicsServer2DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); for (int i = 0; i < body->get_exceptions().size(); i++) { @@ -899,55 +887,55 @@ void PhysicsServer2DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_e }; void PhysicsServer2DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); }; real_t PhysicsServer2DSW::body_get_contacts_reported_depth_threshold(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return 0; }; void PhysicsServer2DSW::body_set_omit_force_integration(RID p_body, bool p_omit) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_omit_force_integration(p_omit); }; bool PhysicsServer2DSW::body_is_omitting_force_integration(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); return body->get_omit_force_integration(); }; void PhysicsServer2DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_max_contacts_reported(p_contacts); } int PhysicsServer2DSW::body_get_max_contacts_reported(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_max_contacts_reported(); } void PhysicsServer2DSW::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_state_sync_callback(p_instance, p_callback); } void PhysicsServer2DSW::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_force_integration_callback(p_callable, p_udata); } bool PhysicsServer2DSW::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_INDEX_V(p_body_shape, body->get_shape_count(), false); @@ -955,13 +943,13 @@ bool PhysicsServer2DSW::body_collide_shape(RID p_body, int p_body_shape, RID p_s } void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_pickable(p_pickable); } bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin, MotionResult *r_result, bool p_collide_separation_ray, const Set<RID> &p_exclude) { - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); ERR_FAIL_COND_V(body->get_space()->is_locked(), false); @@ -974,7 +962,7 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) { ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); - Body2DSW *body = body_owner.getornull(p_body); + Body2DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, nullptr); ERR_FAIL_COND_V(!body->get_space(), nullptr); @@ -993,7 +981,7 @@ RID PhysicsServer2DSW::joint_create() { } void PhysicsServer2DSW::joint_clear(RID p_joint) { - Joint2DSW *joint = joint_owner.getornull(p_joint); + Joint2DSW *joint = joint_owner.get_or_null(p_joint); if (joint->get_type() != JOINT_TYPE_MAX) { Joint2DSW *empty_joint = memnew(Joint2DSW); empty_joint->copy_settings_from(joint); @@ -1004,7 +992,7 @@ void PhysicsServer2DSW::joint_clear(RID p_joint) { } void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) { - Joint2DSW *joint = joint_owner.getornull(p_joint); + Joint2DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); switch (p_param) { @@ -1021,7 +1009,7 @@ void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t } real_t PhysicsServer2DSW::joint_get_param(RID p_joint, JointParam p_param) const { - const Joint2DSW *joint = joint_owner.getornull(p_joint); + const Joint2DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, -1); switch (p_param) { @@ -1040,7 +1028,7 @@ real_t PhysicsServer2DSW::joint_get_param(RID p_joint, JointParam p_param) const } void PhysicsServer2DSW::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { - Joint2DSW *joint = joint_owner.getornull(p_joint); + Joint2DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); joint->disable_collisions_between_bodies(p_disable); @@ -1060,22 +1048,22 @@ void PhysicsServer2DSW::joint_disable_collisions_between_bodies(RID p_joint, con } bool PhysicsServer2DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) const { - const Joint2DSW *joint = joint_owner.getornull(p_joint); + const Joint2DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, true); return joint->is_disabled_collisions_between_bodies(); } void PhysicsServer2DSW::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.getornull(p_body_a); + Body2DSW *A = body_owner.get_or_null(p_body_a); ERR_FAIL_COND(!A); Body2DSW *B = nullptr; if (body_owner.owns(p_body_b)) { - B = body_owner.getornull(p_body_b); + B = body_owner.get_or_null(p_body_b); ERR_FAIL_COND(!B); } - Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + Joint2DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint2DSW *joint = memnew(PinJoint2DSW(p_pos, A, B)); @@ -1086,13 +1074,13 @@ void PhysicsServer2DSW::joint_make_pin(RID p_joint, const Vector2 &p_pos, RID p_ } void PhysicsServer2DSW::joint_make_groove(RID p_joint, const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.getornull(p_body_a); + Body2DSW *A = body_owner.get_or_null(p_body_a); ERR_FAIL_COND(!A); - Body2DSW *B = body_owner.getornull(p_body_b); + Body2DSW *B = body_owner.get_or_null(p_body_b); ERR_FAIL_COND(!B); - Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + Joint2DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint2DSW *joint = memnew(GrooveJoint2DSW(p_a_groove1, p_a_groove2, p_b_anchor, A, B)); @@ -1103,13 +1091,13 @@ void PhysicsServer2DSW::joint_make_groove(RID p_joint, const Vector2 &p_a_groove } void PhysicsServer2DSW::joint_make_damped_spring(RID p_joint, const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.getornull(p_body_a); + Body2DSW *A = body_owner.get_or_null(p_body_a); ERR_FAIL_COND(!A); - Body2DSW *B = body_owner.getornull(p_body_b); + Body2DSW *B = body_owner.get_or_null(p_body_b); ERR_FAIL_COND(!B); - Joint2DSW *prev_joint = joint_owner.getornull(p_joint); + Joint2DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint2DSW *joint = memnew(DampedSpringJoint2DSW(p_anchor_a, p_anchor_b, A, B)); @@ -1120,7 +1108,7 @@ void PhysicsServer2DSW::joint_make_damped_spring(RID p_joint, const Vector2 &p_a } void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - Joint2DSW *j = joint_owner.getornull(p_joint); + Joint2DSW *j = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!j); ERR_FAIL_COND(j->get_type() != JOINT_TYPE_PIN); @@ -1129,7 +1117,7 @@ void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, } real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { - Joint2DSW *j = joint_owner.getornull(p_joint); + Joint2DSW *j = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!j, 0); ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_PIN, 0); @@ -1138,7 +1126,7 @@ real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param } void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) { - Joint2DSW *j = joint_owner.getornull(p_joint); + Joint2DSW *j = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!j); ERR_FAIL_COND(j->get_type() != JOINT_TYPE_DAMPED_SPRING); @@ -1147,7 +1135,7 @@ void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringP } real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const { - Joint2DSW *j = joint_owner.getornull(p_joint); + Joint2DSW *j = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!j, 0); ERR_FAIL_COND_V(j->get_type() != JOINT_TYPE_DAMPED_SPRING, 0); @@ -1156,7 +1144,7 @@ real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSprin } PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const { - Joint2DSW *joint = joint_owner.getornull(p_joint); + Joint2DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); return joint->get_type(); @@ -1166,7 +1154,7 @@ void PhysicsServer2DSW::free(RID p_rid) { _update_shapes(); // just in case if (shape_owner.owns(p_rid)) { - Shape2DSW *shape = shape_owner.getornull(p_rid); + Shape2DSW *shape = shape_owner.get_or_null(p_rid); while (shape->get_owners().size()) { ShapeOwner2DSW *so = shape->get_owners().front()->key(); @@ -1176,7 +1164,7 @@ void PhysicsServer2DSW::free(RID p_rid) { shape_owner.free(p_rid); memdelete(shape); } else if (body_owner.owns(p_rid)) { - Body2DSW *body = body_owner.getornull(p_rid); + Body2DSW *body = body_owner.get_or_null(p_rid); /* if (body->get_state_query()) @@ -1196,7 +1184,7 @@ void PhysicsServer2DSW::free(RID p_rid) { memdelete(body); } else if (area_owner.owns(p_rid)) { - Area2DSW *area = area_owner.getornull(p_rid); + Area2DSW *area = area_owner.get_or_null(p_rid); /* if (area->get_monitor_query()) @@ -1212,7 +1200,7 @@ void PhysicsServer2DSW::free(RID p_rid) { area_owner.free(p_rid); memdelete(area); } else if (space_owner.owns(p_rid)) { - Space2DSW *space = space_owner.getornull(p_rid); + Space2DSW *space = space_owner.get_or_null(p_rid); while (space->get_objects().size()) { CollisionObject2DSW *co = (CollisionObject2DSW *)space->get_objects().front()->get(); @@ -1224,7 +1212,7 @@ void PhysicsServer2DSW::free(RID p_rid) { space_owner.free(p_rid); memdelete(space); } else if (joint_owner.owns(p_rid)) { - Joint2DSW *joint = joint_owner.getornull(p_rid); + Joint2DSW *joint = joint_owner.get_or_null(p_rid); joint_owner.free(p_rid); memdelete(joint); diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index 1db4dd8343..1f35e83995 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -177,12 +177,10 @@ public: virtual void body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false) override; virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) override; virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) override; - virtual void body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant &p_metadata) override; virtual int body_get_shape_count(RID p_body) const override; virtual RID body_get_shape(RID p_body, int p_shape_idx) const override; virtual Transform2D body_get_shape_transform(RID p_body, int p_shape_idx) const override; - virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const override; virtual void body_remove_shape(RID p_body, int p_shape_idx) override; virtual void body_clear_shapes(RID p_body) override; diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index f8733863aa..7925344d76 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -184,11 +184,9 @@ public: FUNC4(body_add_shape, RID, RID, const Transform2D &, bool); FUNC3(body_set_shape, RID, int, RID); FUNC3(body_set_shape_transform, RID, int, const Transform2D &); - FUNC3(body_set_shape_metadata, RID, int, const Variant &); FUNC1RC(int, body_get_shape_count, RID); FUNC2RC(Transform2D, body_get_shape_transform, RID, int); - FUNC2RC(Variant, body_get_shape_metadata, RID, int); FUNC2RC(RID, body_get_shape, RID, int); FUNC3(body_set_shape_disabled, RID, int, bool); diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index b5953bfdaf..bde882ac24 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -36,8 +36,8 @@ void Shape2DSW::configure(const Rect2 &p_aabb) { aabb = p_aabb; configured = true; - for (Map<ShapeOwner2DSW *, int>::Element *E = owners.front(); E; E = E->next()) { - ShapeOwner2DSW *co = (ShapeOwner2DSW *)E->key(); + for (const KeyValue<ShapeOwner2DSW *, int> &E : owners) { + ShapeOwner2DSW *co = (ShapeOwner2DSW *)E.key; co->_shape_changed(); } } @@ -875,9 +875,9 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { points.resize(pointmap.size()); aabb.position = pointmap.front()->key(); - for (Map<Point2, int>::Element *E = pointmap.front(); E; E = E->next()) { - aabb.expand_to(E->key()); - points.write[E->get()] = E->key(); + for (const KeyValue<Point2, int> &E : pointmap) { + aabb.expand_to(E.key); + points.write[E.value] = E.key; } Vector<BVH> main_vbh; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 1058f75407..5cd9bf3223 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -105,7 +105,6 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S } r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; - r_results[cc].metadata = col_obj->get_shape_metadata(shape_idx); cc++; } @@ -193,7 +192,6 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec r_result.collider = ObjectDB::get_instance(r_result.collider_id); } r_result.normal = res_normal; - r_result.metadata = res_obj->get_shape_metadata(res_shape); r_result.position = res_point; r_result.rid = res_obj->get_self(); r_result.shape = res_shape; @@ -206,7 +204,7 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans return 0; } - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); + Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); Rect2 aabb = p_xform.xform(shape->get_aabb()); @@ -242,7 +240,6 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans } r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; - r_results[cc].metadata = col_obj->get_shape_metadata(shape_idx); cc++; } @@ -251,7 +248,7 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans } bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); + Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, false); Rect2 aabb = p_xform.xform(shape->get_aabb()); @@ -338,7 +335,7 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D & return false; } - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); + Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); Rect2 aabb = p_shape_xform.xform(shape->get_aabb()); @@ -435,7 +432,7 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, } bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); + Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; @@ -484,7 +481,6 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh r_info->normal = rcd.best_normal; r_info->point = rcd.best_contact; r_info->rid = rcd.best_object->get_self(); - r_info->metadata = rcd.best_object->get_shape_metadata(rcd.best_shape); if (rcd.best_object->get_type() == CollisionObject2DSW::TYPE_BODY) { const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object); Vector2 rel_vec = r_info->point - (body->get_transform().get_origin() + body->get_center_of_mass()); @@ -961,7 +957,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co r_result->collision_depth = rcd.best_len; r_result->collision_safe_fraction = safe; r_result->collision_unsafe_fraction = unsafe; - r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape); const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object); Vector2 rel_vec = r_result->collision_point - (body->get_transform().get_origin() + body->get_center_of_mass()); diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/body_3d_sw.cpp index 91fe80a3dc..069374d122 100644 --- a/servers/physics_3d/body_3d_sw.cpp +++ b/servers/physics_3d/body_3d_sw.cpp @@ -688,13 +688,13 @@ void BodySW::simulate_motion(const Transform3D& p_xform,real_t p_step) { */ void Body3DSW::wakeup_neighbours() { - for (Map<Constraint3DSW *, int>::Element *E = constraint_map.front(); E; E = E->next()) { - const Constraint3DSW *c = E->key(); + for (const KeyValue<Constraint3DSW *, int> &E : constraint_map) { + const Constraint3DSW *c = E.key; Body3DSW **n = c->get_body_ptr(); int bc = c->get_body_count(); for (int i = 0; i < bc; i++) { - if (i == E->get()) { + if (i == E.value) { continue; } Body3DSW *b = n[i]; diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index 8fbb0ba477..36f81e072d 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -102,25 +102,25 @@ RID PhysicsServer3DSW::custom_shape_create() { } void PhysicsServer3DSW::shape_set_data(RID p_shape, const Variant &p_data) { - Shape3DSW *shape = shape_owner.getornull(p_shape); + Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); shape->set_data(p_data); }; void PhysicsServer3DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { - Shape3DSW *shape = shape_owner.getornull(p_shape); + Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); shape->set_custom_bias(p_bias); } PhysicsServer3D::ShapeType PhysicsServer3DSW::shape_get_type(RID p_shape) const { - const Shape3DSW *shape = shape_owner.getornull(p_shape); + const Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); return shape->get_type(); }; Variant PhysicsServer3DSW::shape_get_data(RID p_shape) const { - const Shape3DSW *shape = shape_owner.getornull(p_shape); + const Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, Variant()); ERR_FAIL_COND_V(!shape->is_configured(), Variant()); return shape->get_data(); @@ -134,7 +134,7 @@ real_t PhysicsServer3DSW::shape_get_margin(RID p_shape) const { } real_t PhysicsServer3DSW::shape_get_custom_solver_bias(RID p_shape) const { - const Shape3DSW *shape = shape_owner.getornull(p_shape); + const Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); return shape->get_custom_bias(); } @@ -144,7 +144,7 @@ RID PhysicsServer3DSW::space_create() { RID id = space_owner.make_rid(space); space->set_self(id); RID area_id = area_create(); - Area3DSW *area = area_owner.getornull(area_id); + Area3DSW *area = area_owner.get_or_null(area_id); ERR_FAIL_COND_V(!area, RID()); space->set_default_area(area); area->set_space(space); @@ -158,7 +158,7 @@ RID PhysicsServer3DSW::space_create() { }; void PhysicsServer3DSW::space_set_active(RID p_space, bool p_active) { - Space3DSW *space = space_owner.getornull(p_space); + Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); if (p_active) { active_spaces.insert(space); @@ -168,27 +168,27 @@ void PhysicsServer3DSW::space_set_active(RID p_space, bool p_active) { } bool PhysicsServer3DSW::space_is_active(RID p_space) const { - const Space3DSW *space = space_owner.getornull(p_space); + const Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, false); return active_spaces.has(space); } void PhysicsServer3DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - Space3DSW *space = space_owner.getornull(p_space); + Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); space->set_param(p_param, p_value); } real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) const { - const Space3DSW *space = space_owner.getornull(p_space); + const Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_param(p_param); } PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) { - Space3DSW *space = space_owner.getornull(p_space); + Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, nullptr); ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); @@ -196,19 +196,19 @@ PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space } void PhysicsServer3DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) { - Space3DSW *space = space_owner.getornull(p_space); + Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); space->set_debug_contacts(p_max_contacts); } Vector<Vector3> PhysicsServer3DSW::space_get_contacts(RID p_space) const { - Space3DSW *space = space_owner.getornull(p_space); + Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, Vector<Vector3>()); return space->get_debug_contacts(); } int PhysicsServer3DSW::space_get_contact_count(RID p_space) const { - Space3DSW *space = space_owner.getornull(p_space); + Space3DSW *space = space_owner.get_or_null(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_debug_contact_count(); } @@ -221,12 +221,12 @@ RID PhysicsServer3DSW::area_create() { }; void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); Space3DSW *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } @@ -239,7 +239,7 @@ void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) { }; RID PhysicsServer3DSW::area_get_space(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, RID()); Space3DSW *space = area->get_space(); @@ -250,34 +250,34 @@ RID PhysicsServer3DSW::area_get_space(RID p_area) const { }; void PhysicsServer3DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_space_override_mode(p_mode); } PhysicsServer3D::AreaSpaceOverrideMode PhysicsServer3DSW::area_get_space_override_mode(RID p_area) const { - const Area3DSW *area = area_owner.getornull(p_area); + const Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); return area->get_space_override_mode(); } void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - Shape3DSW *shape = shape_owner.getornull(p_shape); + Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); area->add_shape(shape, p_transform, p_disabled); } void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - Shape3DSW *shape = shape_owner.getornull(p_shape); + Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); ERR_FAIL_COND(!shape->is_configured()); @@ -285,21 +285,21 @@ void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) } void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform3D &p_transform) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_shape_transform(p_shape_idx, p_transform); } int PhysicsServer3DSW::area_get_shape_count(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, -1); return area->get_shape_count(); } RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, RID()); Shape3DSW *shape = area->get_shape(p_shape_idx); @@ -309,21 +309,21 @@ RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const { } Transform3D PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Transform3D()); return area->get_shape_transform(p_shape_idx); } void PhysicsServer3DSW::area_remove_shape(RID p_area, int p_shape_idx) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->remove_shape(p_shape_idx); } void PhysicsServer3DSW::area_clear_shapes(RID p_area) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); while (area->get_shape_count()) { @@ -332,7 +332,7 @@ void PhysicsServer3DSW::area_clear_shapes(RID p_area) { } void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count()); FLUSH_QUERY_CHECK(area); @@ -341,74 +341,74 @@ void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, boo void PhysicsServer3DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) { if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.getornull(p_area); + Space3DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_instance_id(p_id); } ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.getornull(p_area); + Space3DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, ObjectID()); return area->get_instance_id(); } void PhysicsServer3DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.getornull(p_area); + Space3DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_param(p_param, p_value); }; void PhysicsServer3DSW::area_set_transform(RID p_area, const Transform3D &p_transform) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); }; Variant PhysicsServer3DSW::area_get_param(RID p_area, AreaParameter p_param) const { if (space_owner.owns(p_area)) { - Space3DSW *space = space_owner.getornull(p_area); + Space3DSW *space = space_owner.get_or_null(p_area); p_area = space->get_default_area()->get_self(); } - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Variant()); return area->get_param(p_param); }; Transform3D PhysicsServer3DSW::area_get_transform(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND_V(!area, Transform3D()); return area->get_transform(); }; void PhysicsServer3DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_collision_layer(p_layer); } void PhysicsServer3DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_collision_mask(p_mask); } void PhysicsServer3DSW::area_set_monitorable(RID p_area, bool p_monitorable) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); FLUSH_QUERY_CHECK(area); @@ -416,21 +416,21 @@ void PhysicsServer3DSW::area_set_monitorable(RID p_area, bool p_monitorable) { } void PhysicsServer3DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); } void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_ray_pickable(p_enable); } void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area3DSW *area = area_owner.getornull(p_area); + Area3DSW *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); @@ -446,12 +446,12 @@ RID PhysicsServer3DSW::body_create() { }; void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); Space3DSW *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } @@ -464,7 +464,7 @@ void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) { }; RID PhysicsServer3DSW::body_get_space(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, RID()); Space3DSW *space = body->get_space(); @@ -475,55 +475,55 @@ RID PhysicsServer3DSW::body_get_space(RID p_body) const { }; void PhysicsServer3DSW::body_set_mode(RID p_body, BodyMode p_mode) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_mode(p_mode); }; PhysicsServer3D::BodyMode PhysicsServer3DSW::body_get_mode(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); return body->get_mode(); }; void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform3D &p_transform, bool p_disabled) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - Shape3DSW *shape = shape_owner.getornull(p_shape); + Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); body->add_shape(shape, p_transform, p_disabled); } void PhysicsServer3DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); - Shape3DSW *shape = shape_owner.getornull(p_shape); + Shape3DSW *shape = shape_owner.get_or_null(p_shape); ERR_FAIL_COND(!shape); ERR_FAIL_COND(!shape->is_configured()); body->set_shape(p_shape_idx, shape); } void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform3D &p_transform) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_shape_transform(p_shape_idx, p_transform); } int PhysicsServer3DSW::body_get_shape_count(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_shape_count(); } RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, RID()); Shape3DSW *shape = body->get_shape(p_shape_idx); @@ -533,7 +533,7 @@ RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const { } void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); FLUSH_QUERY_CHECK(body); @@ -542,21 +542,21 @@ void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo } Transform3D PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Transform3D()); return body->get_shape_transform(p_shape_idx); } void PhysicsServer3DSW::body_remove_shape(RID p_body, int p_shape_idx) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->remove_shape(p_shape_idx); } void PhysicsServer3DSW::body_clear_shapes(RID p_body) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); while (body->get_shape_count()) { @@ -565,21 +565,21 @@ void PhysicsServer3DSW::body_clear_shapes(RID p_body) { } void PhysicsServer3DSW::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_continuous_collision_detection(p_enable); } bool PhysicsServer3DSW::body_is_continuous_collision_detection_enabled(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); return body->is_continuous_collision_detection_enabled(); } void PhysicsServer3DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); @@ -587,14 +587,14 @@ void PhysicsServer3DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { } uint32_t PhysicsServer3DSW::body_get_collision_layer(RID p_body) const { - const Body3DSW *body = body_owner.getornull(p_body); + const Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_layer(); } void PhysicsServer3DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); @@ -602,20 +602,20 @@ void PhysicsServer3DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { } uint32_t PhysicsServer3DSW::body_get_collision_mask(RID p_body) const { - const Body3DSW *body = body_owner.getornull(p_body); + const Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_mask(); } void PhysicsServer3DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); if (body) { body->set_instance_id(p_id); return; } - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); if (soft_body) { soft_body->set_instance_id(p_id); return; @@ -625,61 +625,61 @@ void PhysicsServer3DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id }; ObjectID PhysicsServer3DSW::body_get_object_instance_id(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, ObjectID()); return body->get_instance_id(); }; void PhysicsServer3DSW::body_set_user_flags(RID p_body, uint32_t p_flags) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); }; uint32_t PhysicsServer3DSW::body_get_user_flags(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return 0; }; void PhysicsServer3DSW::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_param(p_param, p_value); }; Variant PhysicsServer3DSW::body_get_param(RID p_body, BodyParameter p_param) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_param(p_param); }; void PhysicsServer3DSW::body_reset_mass_properties(RID p_body) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); return body->reset_mass_properties(); } void PhysicsServer3DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_state(p_state, p_variant); }; Variant PhysicsServer3DSW::body_get_state(RID p_body, BodyState p_state) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Variant()); return body->get_state(p_state); }; void PhysicsServer3DSW::body_set_applied_force(RID p_body, const Vector3 &p_force) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_applied_force(p_force); @@ -687,13 +687,13 @@ void PhysicsServer3DSW::body_set_applied_force(RID p_body, const Vector3 &p_forc }; Vector3 PhysicsServer3DSW::body_get_applied_force(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Vector3()); return body->get_applied_force(); }; void PhysicsServer3DSW::body_set_applied_torque(RID p_body, const Vector3 &p_torque) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_applied_torque(p_torque); @@ -701,14 +701,14 @@ void PhysicsServer3DSW::body_set_applied_torque(RID p_body, const Vector3 &p_tor }; Vector3 PhysicsServer3DSW::body_get_applied_torque(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, Vector3()); return body->get_applied_torque(); }; void PhysicsServer3DSW::body_add_central_force(RID p_body, const Vector3 &p_force) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_central_force(p_force); @@ -716,7 +716,7 @@ void PhysicsServer3DSW::body_add_central_force(RID p_body, const Vector3 &p_forc } void PhysicsServer3DSW::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_force(p_force, p_position); @@ -724,7 +724,7 @@ void PhysicsServer3DSW::body_add_force(RID p_body, const Vector3 &p_force, const }; void PhysicsServer3DSW::body_add_torque(RID p_body, const Vector3 &p_torque) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_torque(p_torque); @@ -732,7 +732,7 @@ void PhysicsServer3DSW::body_add_torque(RID p_body, const Vector3 &p_torque) { }; void PhysicsServer3DSW::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); _update_shapes(); @@ -742,7 +742,7 @@ void PhysicsServer3DSW::body_apply_central_impulse(RID p_body, const Vector3 &p_ } void PhysicsServer3DSW::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); _update_shapes(); @@ -752,7 +752,7 @@ void PhysicsServer3DSW::body_apply_impulse(RID p_body, const Vector3 &p_impulse, }; void PhysicsServer3DSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); _update_shapes(); @@ -762,7 +762,7 @@ void PhysicsServer3DSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_i }; void PhysicsServer3DSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); _update_shapes(); @@ -776,7 +776,7 @@ void PhysicsServer3DSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis }; void PhysicsServer3DSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_axis_lock(p_axis, p_lock); @@ -784,13 +784,13 @@ void PhysicsServer3DSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_l } bool PhysicsServer3DSW::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { - const Body3DSW *body = body_owner.getornull(p_body); + const Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return body->is_axis_locked(p_axis); } void PhysicsServer3DSW::body_add_collision_exception(RID p_body, RID p_body_b) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->add_exception(p_body_b); @@ -798,7 +798,7 @@ void PhysicsServer3DSW::body_add_collision_exception(RID p_body, RID p_body_b) { }; void PhysicsServer3DSW::body_remove_collision_exception(RID p_body, RID p_body_b) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->remove_exception(p_body_b); @@ -806,7 +806,7 @@ void PhysicsServer3DSW::body_remove_collision_exception(RID p_body, RID p_body_b }; void PhysicsServer3DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); for (int i = 0; i < body->get_exceptions().size(); i++) { @@ -815,61 +815,61 @@ void PhysicsServer3DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_e }; void PhysicsServer3DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); }; real_t PhysicsServer3DSW::body_get_contacts_reported_depth_threshold(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, 0); return 0; }; void PhysicsServer3DSW::body_set_omit_force_integration(RID p_body, bool p_omit) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_omit_force_integration(p_omit); }; bool PhysicsServer3DSW::body_is_omitting_force_integration(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); return body->get_omit_force_integration(); }; void PhysicsServer3DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_max_contacts_reported(p_contacts); } int PhysicsServer3DSW::body_get_max_contacts_reported(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_max_contacts_reported(); } void PhysicsServer3DSW::body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_state_sync_callback(p_instance, p_callback); } void PhysicsServer3DSW::body_set_force_integration_callback(RID p_body, const Callable &p_callable, const Variant &p_udata) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_force_integration_callback(p_callable, p_udata); } void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND(!body); body->set_ray_pickable(p_enable); } bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from, const Vector3 &p_motion, real_t p_margin, MotionResult *r_result, int p_max_collisions, bool p_collide_separation_ray, const Set<RID> &p_exclude) { - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); ERR_FAIL_COND_V(body->get_space()->is_locked(), false); @@ -882,7 +882,7 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform3D &p_from, PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); - Body3DSW *body = body_owner.getornull(p_body); + Body3DSW *body = body_owner.get_or_null(p_body); ERR_FAIL_NULL_V(body, nullptr); ERR_FAIL_NULL_V(body->get_space(), nullptr); @@ -901,19 +901,19 @@ RID PhysicsServer3DSW::soft_body_create() { } void PhysicsServer3DSW::soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->update_rendering_server(p_rendering_server_handler); } void PhysicsServer3DSW::soft_body_set_space(RID p_body, RID p_space) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); Space3DSW *space = nullptr; if (p_space.is_valid()) { - space = space_owner.getornull(p_space); + space = space_owner.get_or_null(p_space); ERR_FAIL_COND(!space); } @@ -925,7 +925,7 @@ void PhysicsServer3DSW::soft_body_set_space(RID p_body, RID p_space) { } RID PhysicsServer3DSW::soft_body_get_space(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, RID()); Space3DSW *space = soft_body->get_space(); @@ -936,49 +936,49 @@ RID PhysicsServer3DSW::soft_body_get_space(RID p_body) const { } void PhysicsServer3DSW::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_collision_layer(p_layer); } uint32_t PhysicsServer3DSW::soft_body_get_collision_layer(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0); return soft_body->get_collision_layer(); } void PhysicsServer3DSW::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_collision_mask(p_mask); } uint32_t PhysicsServer3DSW::soft_body_get_collision_mask(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0); return soft_body->get_collision_mask(); } void PhysicsServer3DSW::soft_body_add_collision_exception(RID p_body, RID p_body_b) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->add_exception(p_body_b); } void PhysicsServer3DSW::soft_body_remove_collision_exception(RID p_body, RID p_body_b) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->remove_exception(p_body_b); } void PhysicsServer3DSW::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); for (int i = 0; i < soft_body->get_exceptions().size(); i++) { @@ -987,154 +987,154 @@ void PhysicsServer3DSW::soft_body_get_collision_exceptions(RID p_body, List<RID> } void PhysicsServer3DSW::soft_body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_state(p_state, p_variant); } Variant PhysicsServer3DSW::soft_body_get_state(RID p_body, BodyState p_state) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, Variant()); return soft_body->get_state(p_state); } void PhysicsServer3DSW::soft_body_set_transform(RID p_body, const Transform3D &p_transform) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_state(BODY_STATE_TRANSFORM, p_transform); } void PhysicsServer3DSW::soft_body_set_ray_pickable(RID p_body, bool p_enable) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_ray_pickable(p_enable); } void PhysicsServer3DSW::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_iteration_count(p_simulation_precision); } int PhysicsServer3DSW::soft_body_get_simulation_precision(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0.f); return soft_body->get_iteration_count(); } void PhysicsServer3DSW::soft_body_set_total_mass(RID p_body, real_t p_total_mass) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_total_mass(p_total_mass); } real_t PhysicsServer3DSW::soft_body_get_total_mass(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0.f); return soft_body->get_total_mass(); } void PhysicsServer3DSW::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_linear_stiffness(p_stiffness); } real_t PhysicsServer3DSW::soft_body_get_linear_stiffness(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0.f); return soft_body->get_linear_stiffness(); } void PhysicsServer3DSW::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_pressure_coefficient(p_pressure_coefficient); } real_t PhysicsServer3DSW::soft_body_get_pressure_coefficient(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0.f); return soft_body->get_pressure_coefficient(); } void PhysicsServer3DSW::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_damping_coefficient(p_damping_coefficient); } real_t PhysicsServer3DSW::soft_body_get_damping_coefficient(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0.f); return soft_body->get_damping_coefficient(); } void PhysicsServer3DSW::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_drag_coefficient(p_drag_coefficient); } real_t PhysicsServer3DSW::soft_body_get_drag_coefficient(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, 0.f); return soft_body->get_drag_coefficient(); } -void PhysicsServer3DSW::soft_body_set_mesh(RID p_body, const REF &p_mesh) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); +void PhysicsServer3DSW::soft_body_set_mesh(RID p_body, RID p_mesh) { + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_mesh(p_mesh); } AABB PhysicsServer3DSW::soft_body_get_bounds(RID p_body) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, AABB()); return soft_body->get_bounds(); } void PhysicsServer3DSW::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->set_vertex_position(p_point_index, p_global_position); } Vector3 PhysicsServer3DSW::soft_body_get_point_global_position(RID p_body, int p_point_index) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, Vector3()); return soft_body->get_vertex_position(p_point_index); } void PhysicsServer3DSW::soft_body_remove_all_pinned_points(RID p_body) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); soft_body->unpin_all_vertices(); } void PhysicsServer3DSW::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); if (p_pin) { @@ -1145,7 +1145,7 @@ void PhysicsServer3DSW::soft_body_pin_point(RID p_body, int p_point_index, bool } bool PhysicsServer3DSW::soft_body_is_point_pinned(RID p_body, int p_point_index) const { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_body); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND_V(!soft_body, false); return soft_body->is_vertex_pinned(p_point_index); @@ -1161,7 +1161,7 @@ RID PhysicsServer3DSW::joint_create() { } void PhysicsServer3DSW::joint_clear(RID p_joint) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); if (joint->get_type() != JOINT_TYPE_MAX) { Joint3DSW *empty_joint = memnew(Joint3DSW); empty_joint->copy_settings_from(joint); @@ -1172,7 +1172,7 @@ void PhysicsServer3DSW::joint_clear(RID p_joint) { } void PhysicsServer3DSW::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); + Body3DSW *body_A = body_owner.get_or_null(p_body_A); ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { @@ -1180,12 +1180,12 @@ void PhysicsServer3DSW::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 p_body_B = body_A->get_space()->get_static_global_body(); } - Body3DSW *body_B = body_owner.getornull(p_body_B); + Body3DSW *body_B = body_owner.get_or_null(p_body_B); ERR_FAIL_COND(!body_B); ERR_FAIL_COND(body_A == body_B); - Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(PinJoint3DSW(body_A, p_local_A, body_B, p_local_B)); @@ -1196,7 +1196,7 @@ void PhysicsServer3DSW::joint_make_pin(RID p_joint, RID p_body_A, const Vector3 } void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); @@ -1204,7 +1204,7 @@ void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, } real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, 0); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); @@ -1212,7 +1212,7 @@ real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param } void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); @@ -1220,7 +1220,7 @@ void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { } Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); @@ -1228,7 +1228,7 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { } void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); @@ -1236,7 +1236,7 @@ void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { } Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_PIN, Vector3()); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); @@ -1244,7 +1244,7 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { } void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transform3D &p_frame_A, RID p_body_B, const Transform3D &p_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); + Body3DSW *body_A = body_owner.get_or_null(p_body_A); ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { @@ -1252,12 +1252,12 @@ void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transf p_body_B = body_A->get_space()->get_static_global_body(); } - Body3DSW *body_B = body_owner.getornull(p_body_B); + Body3DSW *body_B = body_owner.get_or_null(p_body_B); ERR_FAIL_COND(!body_B); ERR_FAIL_COND(body_A == body_B); - Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_frame_A, p_frame_B)); @@ -1268,7 +1268,7 @@ void PhysicsServer3DSW::joint_make_hinge(RID p_joint, RID p_body_A, const Transf } void PhysicsServer3DSW::joint_make_hinge_simple(RID p_joint, RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); + Body3DSW *body_A = body_owner.get_or_null(p_body_A); ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { @@ -1276,12 +1276,12 @@ void PhysicsServer3DSW::joint_make_hinge_simple(RID p_joint, RID p_body_A, const p_body_B = body_A->get_space()->get_static_global_body(); } - Body3DSW *body_B = body_owner.getornull(p_body_B); + Body3DSW *body_B = body_owner.get_or_null(p_body_B); ERR_FAIL_COND(!body_B); ERR_FAIL_COND(body_A == body_B); - Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(HingeJoint3DSW(body_A, body_B, p_pivot_A, p_pivot_B, p_axis_A, p_axis_B)); @@ -1292,7 +1292,7 @@ void PhysicsServer3DSW::joint_make_hinge_simple(RID p_joint, RID p_body_A, const } void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); @@ -1300,7 +1300,7 @@ void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_par } real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, 0); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); @@ -1308,7 +1308,7 @@ real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_p } void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); @@ -1316,7 +1316,7 @@ void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, } bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_HINGE, false); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); @@ -1324,19 +1324,19 @@ bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) } void PhysicsServer3DSW::joint_set_solver_priority(RID p_joint, int p_priority) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); joint->set_priority(p_priority); } int PhysicsServer3DSW::joint_get_solver_priority(RID p_joint) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); return joint->get_priority(); } void PhysicsServer3DSW::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); joint->disable_collisions_between_bodies(p_disable); @@ -1356,20 +1356,20 @@ void PhysicsServer3DSW::joint_disable_collisions_between_bodies(RID p_joint, con } bool PhysicsServer3DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, true); return joint->is_disabled_collisions_between_bodies(); } PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, JOINT_TYPE_PIN); return joint->get_type(); } void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); + Body3DSW *body_A = body_owner.get_or_null(p_body_A); ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { @@ -1377,12 +1377,12 @@ void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Trans p_body_B = body_A->get_space()->get_static_global_body(); } - Body3DSW *body_B = body_owner.getornull(p_body_B); + Body3DSW *body_B = body_owner.get_or_null(p_body_B); ERR_FAIL_COND(!body_B); ERR_FAIL_COND(body_A == body_B); - Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(SliderJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); @@ -1393,7 +1393,7 @@ void PhysicsServer3DSW::joint_make_slider(RID p_joint, RID p_body_A, const Trans } void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_SLIDER); SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); @@ -1401,7 +1401,7 @@ void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_p } real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); @@ -1409,7 +1409,7 @@ real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p } void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); + Body3DSW *body_A = body_owner.get_or_null(p_body_A); ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { @@ -1417,12 +1417,12 @@ void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const T p_body_B = body_A->get_space()->get_static_global_body(); } - Body3DSW *body_B = body_owner.getornull(p_body_B); + Body3DSW *body_B = body_owner.get_or_null(p_body_B); ERR_FAIL_COND(!body_B); ERR_FAIL_COND(body_A == body_B); - Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(ConeTwistJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B)); @@ -1433,7 +1433,7 @@ void PhysicsServer3DSW::joint_make_cone_twist(RID p_joint, RID p_body_A, const T } void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_CONE_TWIST); ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); @@ -1441,7 +1441,7 @@ void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointPa } real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_CONE_TWIST, 0); ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); @@ -1449,7 +1449,7 @@ real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJoint } void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const Transform3D &p_local_frame_A, RID p_body_B, const Transform3D &p_local_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); + Body3DSW *body_A = body_owner.get_or_null(p_body_A); ERR_FAIL_COND(!body_A); if (!p_body_B.is_valid()) { @@ -1457,12 +1457,12 @@ void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const p_body_B = body_A->get_space()->get_static_global_body(); } - Body3DSW *body_B = body_owner.getornull(p_body_B); + Body3DSW *body_B = body_owner.get_or_null(p_body_B); ERR_FAIL_COND(!body_B); ERR_FAIL_COND(body_A == body_B); - Joint3DSW *prev_joint = joint_owner.getornull(p_joint); + Joint3DSW *prev_joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(prev_joint == nullptr); Joint3DSW *joint = memnew(Generic6DOFJoint3DSW(body_A, body_B, p_local_frame_A, p_local_frame_B, true)); @@ -1473,7 +1473,7 @@ void PhysicsServer3DSW::joint_make_generic_6dof(RID p_joint, RID p_body_A, const } void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); @@ -1481,7 +1481,7 @@ void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis } real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, 0); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); @@ -1489,7 +1489,7 @@ real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axi } void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_TYPE_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); @@ -1497,7 +1497,7 @@ void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p } bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); + Joint3DSW *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_TYPE_6DOF, false); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); @@ -1508,7 +1508,7 @@ void PhysicsServer3DSW::free(RID p_rid) { _update_shapes(); //just in case if (shape_owner.owns(p_rid)) { - Shape3DSW *shape = shape_owner.getornull(p_rid); + Shape3DSW *shape = shape_owner.get_or_null(p_rid); while (shape->get_owners().size()) { ShapeOwner3DSW *so = shape->get_owners().front()->key(); @@ -1518,7 +1518,7 @@ void PhysicsServer3DSW::free(RID p_rid) { shape_owner.free(p_rid); memdelete(shape); } else if (body_owner.owns(p_rid)) { - Body3DSW *body = body_owner.getornull(p_rid); + Body3DSW *body = body_owner.get_or_null(p_rid); /* if (body->get_state_query()) @@ -1537,14 +1537,14 @@ void PhysicsServer3DSW::free(RID p_rid) { body_owner.free(p_rid); memdelete(body); } else if (soft_body_owner.owns(p_rid)) { - SoftBody3DSW *soft_body = soft_body_owner.getornull(p_rid); + SoftBody3DSW *soft_body = soft_body_owner.get_or_null(p_rid); soft_body->set_space(nullptr); soft_body_owner.free(p_rid); memdelete(soft_body); } else if (area_owner.owns(p_rid)) { - Area3DSW *area = area_owner.getornull(p_rid); + Area3DSW *area = area_owner.get_or_null(p_rid); /* if (area->get_monitor_query()) @@ -1560,7 +1560,7 @@ void PhysicsServer3DSW::free(RID p_rid) { area_owner.free(p_rid); memdelete(area); } else if (space_owner.owns(p_rid)) { - Space3DSW *space = space_owner.getornull(p_rid); + Space3DSW *space = space_owner.get_or_null(p_rid); while (space->get_objects().size()) { CollisionObject3DSW *co = (CollisionObject3DSW *)space->get_objects().front()->get(); @@ -1574,7 +1574,7 @@ void PhysicsServer3DSW::free(RID p_rid) { space_owner.free(p_rid); memdelete(space); } else if (joint_owner.owns(p_rid)) { - Joint3DSW *joint = joint_owner.getornull(p_rid); + Joint3DSW *joint = joint_owner.get_or_null(p_rid); joint_owner.free(p_rid); memdelete(joint); diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 357bfba1d7..106e260311 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -291,7 +291,7 @@ public: virtual void soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) override; virtual real_t soft_body_get_drag_coefficient(RID p_body) const override; - virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) override; + virtual void soft_body_set_mesh(RID p_body, RID p_mesh) override; virtual AABB soft_body_get_bounds(RID p_body) const override; diff --git a/servers/physics_3d/physics_server_3d_wrap_mt.h b/servers/physics_3d/physics_server_3d_wrap_mt.h index 6869484f8c..a86fb5a3d3 100644 --- a/servers/physics_3d/physics_server_3d_wrap_mt.h +++ b/servers/physics_3d/physics_server_3d_wrap_mt.h @@ -308,7 +308,7 @@ public: FUNC2(soft_body_set_drag_coefficient, RID, real_t); FUNC1RC(real_t, soft_body_get_drag_coefficient, RID); - FUNC2(soft_body_set_mesh, RID, const REF &); + FUNC2(soft_body_set_mesh, RID, RID); FUNC1RC(AABB, soft_body_get_bounds, RID); diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index 7deddb000e..0fb6d582c8 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -61,8 +61,8 @@ subject to the following restrictions: void Shape3DSW::configure(const AABB &p_aabb) { aabb = p_aabb; configured = true; - for (Map<ShapeOwner3DSW *, int>::Element *E = owners.front(); E; E = E->next()) { - ShapeOwner3DSW *co = (ShapeOwner3DSW *)E->key(); + for (const KeyValue<ShapeOwner3DSW *, int> &E : owners) { + ShapeOwner3DSW *co = (ShapeOwner3DSW *)E.key; co->_shape_changed(); } } diff --git a/servers/physics_3d/soft_body_3d_sw.cpp b/servers/physics_3d/soft_body_3d_sw.cpp index 5f6e202c73..5e8f8692ba 100644 --- a/servers/physics_3d/soft_body_3d_sw.cpp +++ b/servers/physics_3d/soft_body_3d_sw.cpp @@ -33,6 +33,7 @@ #include "core/math/geometry_3d.h" #include "core/templates/map.h" +#include "servers/rendering_server.h" // Based on Bullet soft body. @@ -127,7 +128,7 @@ void SoftBody3DSW::set_space(Space3DSW *p_space) { } } -void SoftBody3DSW::set_mesh(const Ref<Mesh> &p_mesh) { +void SoftBody3DSW::set_mesh(RID p_mesh) { destroy(); soft_mesh = p_mesh; @@ -136,13 +137,11 @@ void SoftBody3DSW::set_mesh(const Ref<Mesh> &p_mesh) { return; } - Array arrays = soft_mesh->surface_get_arrays(0); - ERR_FAIL_COND(!(soft_mesh->surface_get_format(0) & RS::ARRAY_FORMAT_INDEX)); + Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0); - bool success = create_from_trimesh(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]); + bool success = create_from_trimesh(arrays[RenderingServer::ARRAY_INDEX], arrays[RenderingServer::ARRAY_VERTEX]); if (!success) { destroy(); - soft_mesh = Ref<Mesh>(); } } @@ -249,8 +248,10 @@ void SoftBody3DSW::update_area() { // Node area. LocalVector<int> counts; - counts.resize(nodes.size()); - memset(counts.ptr(), 0, counts.size() * sizeof(int)); + if (nodes.size() > 0) { + counts.resize(nodes.size()); + memset(counts.ptr(), 0, counts.size() * sizeof(int)); + } for (i = 0, ni = nodes.size(); i < ni; ++i) { nodes[i].area = 0.0; @@ -465,6 +466,9 @@ Vector3 SoftBody3DSW::get_face_normal(uint32_t p_face_index) const { } bool SoftBody3DSW::create_from_trimesh(const Vector<int> &p_indices, const Vector<Vector3> &p_vertices) { + ERR_FAIL_COND_V(p_indices.is_empty(), false); + ERR_FAIL_COND_V(p_vertices.is_empty(), false); + uint32_t node_count = 0; LocalVector<Vector3> vertices; const int visual_vertex_count(p_vertices.size()); @@ -1225,6 +1229,8 @@ void SoftBody3DSW::deinitialize_shape() { } void SoftBody3DSW::destroy() { + soft_mesh = RID(); + map_visual_to_physics.clear(); node_tree.clear(); diff --git a/servers/physics_3d/soft_body_3d_sw.h b/servers/physics_3d/soft_body_3d_sw.h index 58fd234fde..7d4b83d0ee 100644 --- a/servers/physics_3d/soft_body_3d_sw.h +++ b/servers/physics_3d/soft_body_3d_sw.h @@ -40,12 +40,11 @@ #include "core/templates/local_vector.h" #include "core/templates/set.h" #include "core/templates/vset.h" -#include "scene/resources/mesh.h" class Constraint3DSW; class SoftBody3DSW : public CollisionObject3DSW { - Ref<Mesh> soft_mesh; + RID soft_mesh; struct Node { Vector3 s; // Source position @@ -159,7 +158,7 @@ public: virtual void set_space(Space3DSW *p_space); - void set_mesh(const Ref<Mesh> &p_mesh); + void set_mesh(RID p_mesh); void update_rendering_server(RenderingServerHandler *p_rendering_server_handler); diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index 78c4e30c83..369dad45eb 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -187,7 +187,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans return 0; } - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_xform.xform(shape->get_aabb()); @@ -238,7 +238,7 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans } bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform3D &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, false); AABB aabb = p_xform.xform(shape->get_aabb()); @@ -361,7 +361,7 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform3D & return false; } - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); AABB aabb = p_shape_xform.xform(shape->get_aabb()); @@ -487,7 +487,7 @@ static void _rest_cbk_result(const Vector3 &p_point_A, int p_index_A, const Vect } bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.getornull(p_shape); + Shape3DSW *shape = PhysicsServer3DSW::singletonsw->shape_owner.get_or_null(p_shape); ERR_FAIL_COND_V(!shape, 0); real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR; @@ -543,9 +543,9 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_sh } Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - CollisionObject3DSW *obj = PhysicsServer3DSW::singletonsw->area_owner.getornull(p_object); + CollisionObject3DSW *obj = PhysicsServer3DSW::singletonsw->area_owner.get_or_null(p_object); if (!obj) { - obj = PhysicsServer3DSW::singletonsw->body_owner.getornull(p_object); + obj = PhysicsServer3DSW::singletonsw->body_owner.get_or_null(p_object); } ERR_FAIL_COND_V(!obj, Vector3()); @@ -941,7 +941,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co collision.normal = result.normal; collision.position = result.contact; collision.depth = result.len; - //r_result->collider_metadata = result.object->get_shape_metadata(result.shape); const Body3DSW *body = static_cast<const Body3DSW *>(result.object); diff --git a/servers/physics_3d/step_3d_sw.cpp b/servers/physics_3d/step_3d_sw.cpp index 7c18944b4d..6572d58c91 100644 --- a/servers/physics_3d/step_3d_sw.cpp +++ b/servers/physics_3d/step_3d_sw.cpp @@ -47,8 +47,8 @@ void Step3DSW::_populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_bod p_body_island.push_back(p_body); } - for (Map<Constraint3DSW *, int>::Element *E = p_body->get_constraint_map().front(); E; E = E->next()) { - Constraint3DSW *constraint = (Constraint3DSW *)E->key(); + for (const KeyValue<Constraint3DSW *, int> &E : p_body->get_constraint_map()) { + Constraint3DSW *constraint = (Constraint3DSW *)E.key; if (constraint->get_island_step() == _step) { continue; // Already processed. } @@ -59,7 +59,7 @@ void Step3DSW::_populate_island(Body3DSW *p_body, LocalVector<Body3DSW *> &p_bod // Find connected rigid bodies. for (int i = 0; i < constraint->get_body_count(); i++) { - if (i == E->get()) { + if (i == E.value) { continue; } Body3DSW *other_body = constraint->get_body_ptr()[i]; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 3fc94cd727..8e743e0dc0 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -112,7 +112,6 @@ void PhysicsDirectBodyState2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_contact_collider_id", "contact_idx"), &PhysicsDirectBodyState2D::get_contact_collider_id); ClassDB::bind_method(D_METHOD("get_contact_collider_object", "contact_idx"), &PhysicsDirectBodyState2D::get_contact_collider_object); ClassDB::bind_method(D_METHOD("get_contact_collider_shape", "contact_idx"), &PhysicsDirectBodyState2D::get_contact_collider_shape); - ClassDB::bind_method(D_METHOD("get_contact_collider_shape_metadata", "contact_idx"), &PhysicsDirectBodyState2D::get_contact_collider_shape_metadata); ClassDB::bind_method(D_METHOD("get_contact_collider_velocity_at_position", "contact_idx"), &PhysicsDirectBodyState2D::get_contact_collider_velocity_at_position); ClassDB::bind_method(D_METHOD("get_step"), &PhysicsDirectBodyState2D::get_step); ClassDB::bind_method(D_METHOD("integrate_forces"), &PhysicsDirectBodyState2D::integrate_forces); @@ -279,7 +278,6 @@ Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Vector2 &p_from, cons d["collider"] = inters.collider; d["shape"] = inters.shape; d["rid"] = inters.rid; - d["metadata"] = inters.metadata; return d; } @@ -298,7 +296,6 @@ Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryPar d["collider_id"] = sr[i].collider_id; d["collider"] = sr[i].collider; d["shape"] = sr[i].shape; - d["metadata"] = sr[i].metadata; ret[i] = d; } @@ -348,7 +345,6 @@ Array PhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, i d["collider_id"] = ret[i].collider_id; d["collider"] = ret[i].collider; d["shape"] = ret[i].shape; - d["metadata"] = ret[i].metadata; r[i] = d; } return r; @@ -397,7 +393,6 @@ Dictionary PhysicsDirectSpaceState2D::_get_rest_info(const Ref<PhysicsShapeQuery r["collider_id"] = sri.collider_id; r["shape"] = sri.shape; r["linear_velocity"] = sri.linear_velocity; - r["metadata"] = sri.metadata; return r; } @@ -578,12 +573,10 @@ void PhysicsServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("body_add_shape", "body", "shape", "transform", "disabled"), &PhysicsServer2D::body_add_shape, DEFVAL(Transform2D()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("body_set_shape", "body", "shape_idx", "shape"), &PhysicsServer2D::body_set_shape); ClassDB::bind_method(D_METHOD("body_set_shape_transform", "body", "shape_idx", "transform"), &PhysicsServer2D::body_set_shape_transform); - ClassDB::bind_method(D_METHOD("body_set_shape_metadata", "body", "shape_idx", "metadata"), &PhysicsServer2D::body_set_shape_metadata); ClassDB::bind_method(D_METHOD("body_get_shape_count", "body"), &PhysicsServer2D::body_get_shape_count); ClassDB::bind_method(D_METHOD("body_get_shape", "body", "shape_idx"), &PhysicsServer2D::body_get_shape); ClassDB::bind_method(D_METHOD("body_get_shape_transform", "body", "shape_idx"), &PhysicsServer2D::body_get_shape_transform); - ClassDB::bind_method(D_METHOD("body_get_shape_metadata", "body", "shape_idx"), &PhysicsServer2D::body_get_shape_metadata); ClassDB::bind_method(D_METHOD("body_remove_shape", "body", "shape_idx"), &PhysicsServer2D::body_remove_shape); ClassDB::bind_method(D_METHOD("body_clear_shapes", "body"), &PhysicsServer2D::body_clear_shapes); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 4b85382fe5..ed0584aaa6 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -84,7 +84,6 @@ public: virtual ObjectID get_contact_collider_id(int p_contact_idx) const = 0; virtual Object *get_contact_collider_object(int p_contact_idx) const; virtual int get_contact_collider_shape(int p_contact_idx) const = 0; - virtual Variant get_contact_collider_shape_metadata(int p_contact_idx) const = 0; virtual Vector2 get_contact_collider_velocity_at_position(int p_contact_idx) const = 0; virtual real_t get_step() const = 0; @@ -165,7 +164,6 @@ public: ObjectID collider_id; Object *collider = nullptr; int shape = 0; - Variant metadata; }; virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; @@ -175,7 +173,6 @@ public: ObjectID collider_id; Object *collider = nullptr; int shape = 0; - Variant metadata; }; virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, bool p_pick_point = false) = 0; @@ -194,7 +191,6 @@ public: ObjectID collider_id; int shape = 0; Vector2 linear_velocity; //velocity at contact point - Variant metadata; }; virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = UINT32_MAX, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0; @@ -363,12 +359,10 @@ public: virtual void body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform = Transform2D(), bool p_disabled = false) = 0; virtual void body_set_shape(RID p_body, int p_shape_idx, RID p_shape) = 0; virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) = 0; - virtual void body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant &p_metadata) = 0; virtual int body_get_shape_count(RID p_body) const = 0; virtual RID body_get_shape(RID p_body, int p_shape_idx) const = 0; virtual Transform2D body_get_shape_transform(RID p_body, int p_shape_idx) const = 0; - virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const = 0; virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) = 0; virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, real_t p_margin = 0) = 0; @@ -485,7 +479,6 @@ public: ObjectID collider_id; RID collider; int collider_shape = 0; - Variant collider_metadata; real_t get_angle(Vector2 p_up_direction) const { return Math::acos(collision_normal.dot(p_up_direction)); @@ -503,7 +496,6 @@ public: ObjectID collider_id; RID collider; int collider_shape; - Variant collider_metadata; }; /* JOINT API */ diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 14d395e714..dbd734ba32 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -492,7 +492,6 @@ public: ObjectID collider_id; RID collider; int collider_shape = 0; - Variant collider_metadata; real_t get_angle(Vector3 p_up_direction) const { return Math::acos(normal.dot(p_up_direction)); @@ -521,7 +520,7 @@ public: virtual void soft_body_set_space(RID p_body, RID p_space) = 0; virtual RID soft_body_get_space(RID p_body) const = 0; - virtual void soft_body_set_mesh(RID p_body, const REF &p_mesh) = 0; + virtual void soft_body_set_mesh(RID p_body, RID p_mesh) = 0; virtual AABB soft_body_get_bounds(RID p_body) const = 0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 41c8b45113..d5eccce88e 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -70,6 +70,7 @@ #include "rendering/rendering_device_binds.h" #include "rendering_server.h" #include "servers/rendering/shader_types.h" +#include "text/text_server_extension.h" #include "text_server.h" #include "xr/xr_interface.h" #include "xr/xr_interface_extension.h" @@ -107,15 +108,11 @@ static bool has_server_feature_callback(const String &p_feature) { void preregister_server_types() { shader_types = memnew(ShaderTypes); - GLOBAL_DEF("internationalization/rendering/text_driver", ""); - String text_driver_options; - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - if (i > 0) { - text_driver_options += ","; - } - text_driver_options += TextServerManager::get_interface_name(i); - } - ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options)); + GDREGISTER_CLASS(TextServerManager); + GDREGISTER_VIRTUAL_CLASS(TextServer); + GDREGISTER_CLASS(TextServerExtension); + + Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager")); } void register_server_types() { @@ -125,8 +122,6 @@ void register_server_types() { GDREGISTER_VIRTUAL_CLASS(RenderingServer); GDREGISTER_CLASS(AudioServer); - GDREGISTER_CLASS(TextServerManager); - GDREGISTER_VIRTUAL_CLASS(TextServer); TextServer::initialize_hex_code_box_fonts(); GDREGISTER_VIRTUAL_CLASS(PhysicsServer2D); @@ -255,7 +250,6 @@ void register_server_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton(), "PhysicsServer3D")); Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton_mut(), "NavigationServer2D")); Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton_mut(), "NavigationServer3D")); - Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager")); Engine::get_singleton()->add_singleton(Engine::Singleton("XRServer", XRServer::get_singleton(), "XRServer")); Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton(), "CameraServer")); } diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h index 35bb7722e7..f95221c05b 100644 --- a/servers/rendering/rasterizer_dummy.h +++ b/servers/rendering/rasterizer_dummy.h @@ -224,7 +224,7 @@ public: return texture_owner.make_rid(texture); } void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override { - DummyTexture *t = texture_owner.getornull(p_texture); + DummyTexture *t = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!t); t->image = p_image->duplicate(); } @@ -241,7 +241,7 @@ public: void texture_3d_placeholder_initialize(RID p_texture) override {} Ref<Image> texture_2d_get(RID p_texture) const override { - DummyTexture *t = texture_owner.getornull(p_texture); + DummyTexture *t = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!t, Ref<Image>()); return t->image; } @@ -661,7 +661,7 @@ public: bool free(RID p_rid) override { if (texture_owner.owns(p_rid)) { // delete the texture - DummyTexture *texture = texture_owner.getornull(p_rid); + DummyTexture *texture = texture_owner.get_or_null(p_rid); texture_owner.free(p_rid); memdelete(texture); return true; diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 456c736731..46683e8e68 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -100,7 +100,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2 void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_Owner<RendererCanvasCull::Item, true> &canvas_item_owner) { do { ysort_owner->ysort_children_count = -1; - ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr; + ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.get_or_null(ysort_owner->parent) : nullptr; } while (ysort_owner && ysort_owner->sort_y); } @@ -396,9 +396,9 @@ void RendererCanvasCull::canvas_initialize(RID p_rid) { } void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) { - Canvas *canvas = canvas_owner.getornull(p_canvas); + Canvas *canvas = canvas_owner.get_or_null(p_canvas); ERR_FAIL_COND(!canvas); - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); int idx = canvas->find_item(canvas_item); @@ -407,7 +407,7 @@ void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, con } void RendererCanvasCull::canvas_set_modulate(RID p_canvas, const Color &p_color) { - Canvas *canvas = canvas_owner.getornull(p_canvas); + Canvas *canvas = canvas_owner.get_or_null(p_canvas); ERR_FAIL_COND(!canvas); canvas->modulate = p_color; } @@ -417,7 +417,7 @@ void RendererCanvasCull::canvas_set_disable_scale(bool p_disable) { } void RendererCanvasCull::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) { - Canvas *canvas = canvas_owner.getornull(p_canvas); + Canvas *canvas = canvas_owner.get_or_null(p_canvas); ERR_FAIL_COND(!canvas); canvas->parent = p_parent; @@ -432,15 +432,15 @@ void RendererCanvasCull::canvas_item_initialize(RID p_rid) { } void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); if (canvas_item->parent.is_valid()) { if (canvas_owner.owns(canvas_item->parent)) { - Canvas *canvas = canvas_owner.getornull(canvas_item->parent); + Canvas *canvas = canvas_owner.get_or_null(canvas_item->parent); canvas->erase_item(canvas_item); } else if (canvas_item_owner.owns(canvas_item->parent)) { - Item *item_owner = canvas_item_owner.getornull(canvas_item->parent); + Item *item_owner = canvas_item_owner.get_or_null(canvas_item->parent); item_owner->child_items.erase(canvas_item); if (item_owner->sort_y) { @@ -453,13 +453,13 @@ void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) { if (p_parent.is_valid()) { if (canvas_owner.owns(p_parent)) { - Canvas *canvas = canvas_owner.getornull(p_parent); + Canvas *canvas = canvas_owner.get_or_null(p_parent); Canvas::ChildItem ci; ci.item = canvas_item; canvas->child_items.push_back(ci); canvas->children_order_dirty = true; } else if (canvas_item_owner.owns(p_parent)) { - Item *item_owner = canvas_item_owner.getornull(p_parent); + Item *item_owner = canvas_item_owner.get_or_null(p_parent); item_owner->child_items.push_back(canvas_item); item_owner->children_order_dirty = true; @@ -476,7 +476,7 @@ void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) { } void RendererCanvasCull::canvas_item_set_visible(RID p_item, bool p_visible) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->visible = p_visible; @@ -485,35 +485,35 @@ void RendererCanvasCull::canvas_item_set_visible(RID p_item, bool p_visible) { } void RendererCanvasCull::canvas_item_set_light_mask(RID p_item, int p_mask) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->light_mask = p_mask; } void RendererCanvasCull::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->xform = p_transform; } void RendererCanvasCull::canvas_item_set_clip(RID p_item, bool p_clip) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clip = p_clip; } void RendererCanvasCull::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->distance_field = p_enable; } void RendererCanvasCull::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->custom_rect = p_custom_rect; @@ -521,35 +521,35 @@ void RendererCanvasCull::canvas_item_set_custom_rect(RID p_item, bool p_custom_r } void RendererCanvasCull::canvas_item_set_modulate(RID p_item, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->modulate = p_color; } void RendererCanvasCull::canvas_item_set_self_modulate(RID p_item, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->self_modulate = p_color; } void RendererCanvasCull::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->behind = p_enable; } void RendererCanvasCull::canvas_item_set_update_when_visible(RID p_item, bool p_update) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->update_when_visible = p_update; } void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandPrimitive *line = canvas_item->alloc_command<Item::CommandPrimitive>(); @@ -573,7 +573,7 @@ void RendererCanvasCull::canvas_item_add_line(RID p_item, const Point2 &p_from, void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { ERR_FAIL_COND(p_points.size() < 2); - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Color color = Color(1, 1, 1, 1); @@ -714,7 +714,7 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { ERR_FAIL_COND(p_points.size() < 2); - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>(); @@ -730,7 +730,7 @@ void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Poin } void RendererCanvasCull::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>(); @@ -740,7 +740,7 @@ void RendererCanvasCull::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, c } void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandPolygon *circle = canvas_item->alloc_command<Item::CommandPolygon>(); @@ -776,7 +776,7 @@ void RendererCanvasCull::canvas_item_add_circle(RID p_item, const Point2 &p_pos, } void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>(); @@ -807,7 +807,7 @@ void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p } void RendererCanvasCull::canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, int p_outline_size, float p_px_range) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>(); @@ -841,7 +841,7 @@ void RendererCanvasCull::canvas_item_add_msdf_texture_rect_region(RID p_item, co } void RendererCanvasCull::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>(); @@ -882,7 +882,7 @@ void RendererCanvasCull::canvas_item_add_texture_rect_region(RID p_item, const R } void RendererCanvasCull::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandNinePatch *style = canvas_item->alloc_command<Item::CommandNinePatch>(); @@ -906,7 +906,7 @@ void RendererCanvasCull::canvas_item_add_primitive(RID p_item, const Vector<Poin uint32_t pc = p_points.size(); ERR_FAIL_COND(pc == 0 || pc > 4); - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandPrimitive *prim = canvas_item->alloc_command<Item::CommandPrimitive>(); @@ -932,7 +932,7 @@ void RendererCanvasCull::canvas_item_add_primitive(RID p_item, const Vector<Poin } void RendererCanvasCull::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); #ifdef DEBUG_ENABLED int pointcount = p_points.size(); @@ -953,7 +953,7 @@ void RendererCanvasCull::canvas_item_add_polygon(RID p_item, const Vector<Point2 } void RendererCanvasCull::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); int vertex_count = p_points.size(); @@ -976,7 +976,7 @@ void RendererCanvasCull::canvas_item_add_triangle_array(RID p_item, const Vector } void RendererCanvasCull::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandTransform *tr = canvas_item->alloc_command<Item::CommandTransform>(); @@ -985,7 +985,7 @@ void RendererCanvasCull::canvas_item_add_set_transform(RID p_item, const Transfo } void RendererCanvasCull::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); ERR_FAIL_COND(!p_mesh.is_valid()); @@ -1004,7 +1004,7 @@ void RendererCanvasCull::canvas_item_add_mesh(RID p_item, const RID &p_mesh, con } void RendererCanvasCull::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandParticles *part = canvas_item->alloc_command<Item::CommandParticles>(); @@ -1018,7 +1018,7 @@ void RendererCanvasCull::canvas_item_add_particles(RID p_item, RID p_particles, } void RendererCanvasCull::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandMultiMesh *mm = canvas_item->alloc_command<Item::CommandMultiMesh>(); @@ -1029,7 +1029,7 @@ void RendererCanvasCull::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p } void RendererCanvasCull::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandClipIgnore *ci = canvas_item->alloc_command<Item::CommandClipIgnore>(); @@ -1038,7 +1038,7 @@ void RendererCanvasCull::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) } void RendererCanvasCull::canvas_item_add_animation_slice(RID p_item, double p_animation_length, double p_slice_begin, double p_slice_end, double p_offset) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandAnimationSlice *as = canvas_item->alloc_command<Item::CommandAnimationSlice>(); @@ -1050,7 +1050,7 @@ void RendererCanvasCull::canvas_item_add_animation_slice(RID p_item, double p_an } void RendererCanvasCull::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->sort_y = p_enable; @@ -1061,21 +1061,21 @@ void RendererCanvasCull::canvas_item_set_sort_children_by_y(RID p_item, bool p_e void RendererCanvasCull::canvas_item_set_z_index(RID p_item, int p_z) { ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN || p_z > RS::CANVAS_ITEM_Z_MAX); - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->z_index = p_z; } void RendererCanvasCull::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->z_relative = p_enable; } void RendererCanvasCull::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); if (canvas_item->skeleton == p_skeleton) { return; @@ -1104,7 +1104,7 @@ void RendererCanvasCull::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) } void RendererCanvasCull::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); if (p_enable && (canvas_item->copy_back_buffer == nullptr)) { canvas_item->copy_back_buffer = memnew(RendererCanvasRender::Item::CopyBackBuffer); @@ -1121,25 +1121,25 @@ void RendererCanvasCull::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_e } void RendererCanvasCull::canvas_item_clear(RID p_item) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clear(); } void RendererCanvasCull::canvas_item_set_draw_index(RID p_item, int p_index) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->index = p_index; if (canvas_item_owner.owns(canvas_item->parent)) { - Item *canvas_item_parent = canvas_item_owner.getornull(canvas_item->parent); + Item *canvas_item_parent = canvas_item_owner.get_or_null(canvas_item->parent); canvas_item_parent->children_order_dirty = true; return; } - Canvas *canvas = canvas_owner.getornull(canvas_item->parent); + Canvas *canvas = canvas_owner.get_or_null(canvas_item->parent); if (canvas) { canvas->children_order_dirty = true; return; @@ -1147,21 +1147,21 @@ void RendererCanvasCull::canvas_item_set_draw_index(RID p_item, int p_index) { } void RendererCanvasCull::canvas_item_set_material(RID p_item, RID p_material) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->material = p_material; } void RendererCanvasCull::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->use_parent_material = p_enable; } void RendererCanvasCull::canvas_item_set_visibility_notifier(RID p_item, bool p_enable, const Rect2 &p_area, const Callable &p_enter_callable, const Callable &p_exit_callable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); if (p_enable) { @@ -1181,7 +1181,7 @@ void RendererCanvasCull::canvas_item_set_visibility_notifier(RID p_item, bool p_ } void RendererCanvasCull::canvas_item_set_canvas_group_mode(RID p_item, RS::CanvasGroupMode p_mode, float p_clear_margin, bool p_fit_empty, float p_fit_margin, bool p_blur_mipmaps) { - Item *canvas_item = canvas_item_owner.getornull(p_item); + Item *canvas_item = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!canvas_item); if (p_mode == RS::CANVAS_GROUP_MODE_DISABLED) { @@ -1206,12 +1206,12 @@ RID RendererCanvasCull::canvas_light_allocate() { } void RendererCanvasCull::canvas_light_initialize(RID p_rid) { canvas_light_owner.initialize_rid(p_rid); - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_rid); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_rid); clight->light_internal = RSG::canvas_render->light_create(); } void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); if (clight->mode == p_mode) { @@ -1232,11 +1232,11 @@ void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode } void RendererCanvasCull::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); if (clight->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(clight->canvas); + Canvas *canvas = canvas_owner.get_or_null(clight->canvas); if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) { canvas->lights.erase(clight); } else { @@ -1251,7 +1251,7 @@ void RendererCanvasCull::canvas_light_attach_to_canvas(RID p_light, RID p_canvas clight->canvas = p_canvas; if (clight->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(clight->canvas); + Canvas *canvas = canvas_owner.get_or_null(clight->canvas); if (clight->mode == RS::CANVAS_LIGHT_MODE_POINT) { canvas->lights.insert(clight); } else { @@ -1261,28 +1261,28 @@ void RendererCanvasCull::canvas_light_attach_to_canvas(RID p_light, RID p_canvas } void RendererCanvasCull::canvas_light_set_enabled(RID p_light, bool p_enabled) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->enabled = p_enabled; } void RendererCanvasCull::canvas_light_set_texture_scale(RID p_light, float p_scale) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->scale = p_scale; } void RendererCanvasCull::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->xform = p_transform; } void RendererCanvasCull::canvas_light_set_texture(RID p_light, RID p_texture) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); if (clight->texture == p_texture) { @@ -1294,35 +1294,35 @@ void RendererCanvasCull::canvas_light_set_texture(RID p_light, RID p_texture) { } void RendererCanvasCull::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->texture_offset = p_offset; } void RendererCanvasCull::canvas_light_set_color(RID p_light, const Color &p_color) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->color = p_color; } void RendererCanvasCull::canvas_light_set_height(RID p_light, float p_height) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->height = p_height; } void RendererCanvasCull::canvas_light_set_energy(RID p_light, float p_energy) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->energy = p_energy; } void RendererCanvasCull::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->z_min = p_min_z; @@ -1330,7 +1330,7 @@ void RendererCanvasCull::canvas_light_set_z_range(RID p_light, int p_min_z, int } void RendererCanvasCull::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->layer_max = p_max_layer; @@ -1338,35 +1338,35 @@ void RendererCanvasCull::canvas_light_set_layer_range(RID p_light, int p_min_lay } void RendererCanvasCull::canvas_light_set_item_cull_mask(RID p_light, int p_mask) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->item_mask = p_mask; } void RendererCanvasCull::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->item_shadow_mask = p_mask; } void RendererCanvasCull::canvas_light_set_directional_distance(RID p_light, float p_distance) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->directional_distance = p_distance; } void RendererCanvasCull::canvas_light_set_blend_mode(RID p_light, RS::CanvasLightBlendMode p_mode) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->blend_mode = p_mode; } void RendererCanvasCull::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); if (clight->use_shadow == p_enabled) { @@ -1378,21 +1378,21 @@ void RendererCanvasCull::canvas_light_set_shadow_enabled(RID p_light, bool p_ena } void RendererCanvasCull::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->shadow_filter = p_filter; } void RendererCanvasCull::canvas_light_set_shadow_color(RID p_light, const Color &p_color) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->shadow_color = p_color; } void RendererCanvasCull::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) { - RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_light); + RendererCanvasRender::Light *clight = canvas_light_owner.get_or_null(p_light); ERR_FAIL_COND(!clight); clight->shadow_smooth = p_smooth; } @@ -1405,11 +1405,11 @@ void RendererCanvasCull::canvas_light_occluder_initialize(RID p_rid) { } void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { - RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); if (occluder->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); + Canvas *canvas = canvas_owner.get_or_null(occluder->canvas); canvas->occluders.erase(occluder); } @@ -1420,24 +1420,24 @@ void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, occluder->canvas = p_canvas; if (occluder->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); + Canvas *canvas = canvas_owner.get_or_null(occluder->canvas); canvas->occluders.insert(occluder); } } void RendererCanvasCull::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) { - RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); occluder->enabled = p_enabled; } void RendererCanvasCull::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) { - RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); if (occluder->polygon.is_valid()) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_polygon); + LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get_or_null(p_polygon); if (occluder_poly) { occluder_poly->owners.erase(occluder); } @@ -1447,7 +1447,7 @@ void RendererCanvasCull::canvas_light_occluder_set_polygon(RID p_occluder, RID p occluder->occluder = RID(); if (occluder->polygon.is_valid()) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_polygon); + LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get_or_null(p_polygon); if (!occluder_poly) { occluder->polygon = RID(); ERR_FAIL_COND(!occluder_poly); @@ -1461,19 +1461,19 @@ void RendererCanvasCull::canvas_light_occluder_set_polygon(RID p_occluder, RID p } void RendererCanvasCull::canvas_light_occluder_set_as_sdf_collision(RID p_occluder, bool p_enable) { - RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); } void RendererCanvasCull::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) { - RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); occluder->xform = p_xform; } void RendererCanvasCull::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) { - RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.get_or_null(p_occluder); ERR_FAIL_COND(!occluder); occluder->light_mask = p_mask; @@ -1484,12 +1484,12 @@ RID RendererCanvasCull::canvas_occluder_polygon_allocate() { } void RendererCanvasCull::canvas_occluder_polygon_initialize(RID p_rid) { canvas_light_occluder_polygon_owner.initialize_rid(p_rid); - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_rid); + LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get_or_null(p_rid); occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create(); } void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); + LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get_or_null(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); uint32_t pc = p_shape.size(); @@ -1513,7 +1513,7 @@ void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygo } void RendererCanvasCull::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); + LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get_or_null(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); occluder_poly->cull_mode = p_mode; RSG::canvas_render->occluder_polygon_set_cull_mode(occluder_poly->occluder, p_mode); @@ -1550,12 +1550,12 @@ void RendererCanvasCull::canvas_texture_set_texture_repeat(RID p_canvas_texture, } void RendererCanvasCull::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) { - Item *ci = canvas_item_owner.getornull(p_item); + Item *ci = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!ci); ci->texture_filter = p_filter; } void RendererCanvasCull::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) { - Item *ci = canvas_item_owner.getornull(p_item); + Item *ci = canvas_item_owner.get_or_null(p_item); ERR_FAIL_COND(!ci); ci->texture_repeat = p_repeat; } @@ -1600,11 +1600,11 @@ void RendererCanvasCull::update_visibility_notifiers() { bool RendererCanvasCull::free(RID p_rid) { if (canvas_owner.owns(p_rid)) { - Canvas *canvas = canvas_owner.getornull(p_rid); + Canvas *canvas = canvas_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!canvas, false); while (canvas->viewports.size()) { - RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get()); + RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.get_or_null(canvas->viewports.front()->get()); ERR_FAIL_COND_V(!vp, true); Map<RID, RendererViewport::Viewport::CanvasData>::Element *E = vp->canvas_map.find(p_rid); @@ -1629,15 +1629,15 @@ bool RendererCanvasCull::free(RID p_rid) { canvas_owner.free(p_rid); } else if (canvas_item_owner.owns(p_rid)) { - Item *canvas_item = canvas_item_owner.getornull(p_rid); + Item *canvas_item = canvas_item_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!canvas_item, true); if (canvas_item->parent.is_valid()) { if (canvas_owner.owns(canvas_item->parent)) { - Canvas *canvas = canvas_owner.getornull(canvas_item->parent); + Canvas *canvas = canvas_owner.get_or_null(canvas_item->parent); canvas->erase_item(canvas_item); } else if (canvas_item_owner.owns(canvas_item->parent)) { - Item *item_owner = canvas_item_owner.getornull(canvas_item->parent); + Item *item_owner = canvas_item_owner.get_or_null(canvas_item->parent); item_owner->child_items.erase(canvas_item); if (item_owner->sort_y) { @@ -1663,11 +1663,11 @@ bool RendererCanvasCull::free(RID p_rid) { canvas_item_owner.free(p_rid); } else if (canvas_light_owner.owns(p_rid)) { - RendererCanvasRender::Light *canvas_light = canvas_light_owner.getornull(p_rid); + RendererCanvasRender::Light *canvas_light = canvas_light_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!canvas_light, true); if (canvas_light->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(canvas_light->canvas); + Canvas *canvas = canvas_owner.get_or_null(canvas_light->canvas); if (canvas) { canvas->lights.erase(canvas_light); } @@ -1678,25 +1678,25 @@ bool RendererCanvasCull::free(RID p_rid) { canvas_light_owner.free(p_rid); } else if (canvas_light_occluder_owner.owns(p_rid)) { - RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid); + RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!occluder, true); if (occluder->polygon.is_valid()) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(occluder->polygon); + LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get_or_null(occluder->polygon); if (occluder_poly) { occluder_poly->owners.erase(occluder); } } if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); + Canvas *canvas = canvas_owner.get_or_null(occluder->canvas); canvas->occluders.erase(occluder); } canvas_light_occluder_owner.free(p_rid); } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_rid); + LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!occluder_poly, true); RSG::canvas_render->free(occluder_poly->occluder); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index fa3741c077..2377702738 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -2695,7 +2695,7 @@ void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geome } break; #if 0 case RS::INSTANCE_IMMEDIATE: { - RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base); + RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.get_or_null(inst->base); ERR_CONTINUE(!immediate); _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 1947680a7a..0416b06d0d 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -344,36 +344,36 @@ void SceneShaderForwardClustered::ShaderData::set_default_texture_param(const St void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { continue; } - if (E->get().texture_order >= 0) { - order[E->get().texture_order + 100000] = E->key(); + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; } else { - order[E->get().order] = E->key(); + order[E.value.order] = E.key; } } - for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); - pi.name = E->get(); + for (const KeyValue<int, StringName> &E : order) { + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; p_param_list->push_back(pi); } } void SceneShaderForwardClustered::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } RendererStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E->get()); - p.info.name = E->key(); //supply name - p.index = E->get().instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint); p_param_list->push_back(p); } } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index a5cc2db48f..75de2f6fbd 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2440,7 +2440,7 @@ void RenderForwardMobile::_geometry_instance_update(GeometryInstance *p_geometry } break; #if 0 case RS::INSTANCE_IMMEDIATE: { - RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getornull(inst->base); + RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.get_or_null(inst->base); ERR_CONTINUE(!immediate); _add_geometry(immediate, inst, nullptr, -1, p_depth_pass, p_shadow_pass); diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index cd314d8c56..4118735cf2 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -336,36 +336,36 @@ void SceneShaderForwardMobile::ShaderData::set_default_texture_param(const Strin void SceneShaderForwardMobile::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { continue; } - if (E->get().texture_order >= 0) { - order[E->get().texture_order + 100000] = E->key(); + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; } else { - order[E->get().order] = E->key(); + order[E.value.order] = E.key; } } - for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); - pi.name = E->get(); + for (const KeyValue<int, StringName> &E : order) { + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; p_param_list->push_back(pi); } } void SceneShaderForwardMobile::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } RendererStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E->get()); - p.info.name = E->key(); //supply name - p.index = E->get().instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint); p_param_list->push_back(p); } } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index c2227587ec..b792ec9971 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1144,7 +1144,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p continue; } - CanvasLight *clight = canvas_light_owner.getornull(l->light_internal); + CanvasLight *clight = canvas_light_owner.get_or_null(l->light_internal); if (!clight) { //unused or invalid texture l->render_index_cache = -1; l = l->next_ptr; @@ -1207,7 +1207,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p continue; } - CanvasLight *clight = canvas_light_owner.getornull(l->light_internal); + CanvasLight *clight = canvas_light_owner.get_or_null(l->light_internal); if (!clight) { //unused or invalid texture l->render_index_cache = -1; l = l->next_ptr; @@ -1481,7 +1481,7 @@ RID RendererCanvasRenderRD::light_create() { } void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); + CanvasLight *cl = canvas_light_owner.get_or_null(p_rid); ERR_FAIL_COND(!cl); if (cl->texture == p_texture) { return; @@ -1497,7 +1497,7 @@ void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) { } void RendererCanvasRenderRD::light_set_use_shadow(RID p_rid, bool p_enable) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); + CanvasLight *cl = canvas_light_owner.get_or_null(p_rid); ERR_FAIL_COND(!cl); cl->shadow.enabled = p_enable; @@ -1537,7 +1537,7 @@ void RendererCanvasRenderRD::_update_shadow_atlas() { } } void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); + CanvasLight *cl = canvas_light_owner.get_or_null(p_rid); ERR_FAIL_COND(!cl->shadow.enabled); _update_shadow_atlas(); @@ -1591,7 +1591,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, LightOccluderInstance *instance = p_occluders; while (instance) { - OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder); + OccluderPolygon *co = occluder_polygon_owner.get_or_null(instance->occluder); if (!co || co->index_array.is_null() || !(p_light_mask & instance->light_mask)) { instance = instance->next; @@ -1615,7 +1615,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, } void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); + CanvasLight *cl = canvas_light_owner.get_or_null(p_rid); ERR_FAIL_COND(!cl->shadow.enabled); _update_shadow_atlas(); @@ -1666,7 +1666,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh LightOccluderInstance *instance = p_occluders; while (instance) { - OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder); + OccluderPolygon *co = occluder_polygon_owner.get_or_null(instance->occluder); if (!co || co->index_array.is_null() || !(p_light_mask & instance->light_mask)) { instance = instance->next; @@ -1732,7 +1732,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan LightOccluderInstance *instance = p_occluders; while (instance) { - OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder); + OccluderPolygon *co = occluder_polygon_owner.get_or_null(instance->occluder); if (!co || co->sdf_index_array.is_null()) { instance = instance->next; @@ -1766,7 +1766,7 @@ RID RendererCanvasRenderRD::occluder_polygon_create() { } void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) { - OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); + OccluderPolygon *oc = occluder_polygon_owner.get_or_null(p_occluder); ERR_FAIL_COND(!oc); Vector<Vector2> lines; @@ -1935,7 +1935,7 @@ void RendererCanvasRenderRD::occluder_polygon_set_shape(RID p_occluder, const Ve } void RendererCanvasRenderRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) { - OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); + OccluderPolygon *oc = occluder_polygon_owner.get_or_null(p_occluder); ERR_FAIL_COND(!oc); oc->cull_mode = p_mode; } @@ -2133,35 +2133,35 @@ void RendererCanvasRenderRD::ShaderData::set_default_texture_param(const StringN void RendererCanvasRenderRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { continue; } - if (E->get().texture_order >= 0) { - order[E->get().texture_order + 100000] = E->key(); + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; } else { - order[E->get().order] = E->key(); + order[E.value.order] = E.key; } } - for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); - pi.name = E->get(); + for (const KeyValue<int, StringName> &E : order) { + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; p_param_list->push_back(pi); } } void RendererCanvasRenderRD::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } RendererStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E->get()); - p.info.name = E->key(); //supply name - p.index = E->get().instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint); p_param_list->push_back(p); } } @@ -2611,7 +2611,7 @@ void fragment() { bool RendererCanvasRenderRD::free(RID p_rid) { if (canvas_light_owner.owns(p_rid)) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); + CanvasLight *cl = canvas_light_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!cl, false); light_set_use_shadow(p_rid, false); canvas_light_owner.free(p_rid); diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index fb308da38d..ecc560fc5d 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -1450,7 +1450,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re break; } - RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.getornull(p_scene_render->render_state.sdfgi_update_data->directional_lights->get(j)); + RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->directional_lights->get(j)); ERR_CONTINUE(!li); if (storage->light_directional_is_sky_only(li->light)) { @@ -1484,7 +1484,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re break; } - RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.getornull(p_scene_render->render_state.sdfgi_update_data->positional_light_instances[j]); + RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->positional_light_instances[j]); ERR_CONTINUE(!li); uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light); @@ -1534,7 +1534,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { //print_line("rendering region " + itos(p_region)); - RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers); + RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... AABB bounds; Vector3i from; @@ -1892,7 +1892,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) { - RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers); + RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs"); @@ -1921,7 +1921,7 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32 break; } - RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.getornull(p_positional_light_cull_result[i][j]); + RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_positional_light_cull_result[i][j]); ERR_CONTINUE(!li); uint32_t max_sdfgi_cascade = storage->light_get_max_sdfgi_cascade(li->light); @@ -3024,7 +3024,7 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra r_voxel_gi_instances_used = 0; // feels a little dirty to use our container this way but.... - RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers); + RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(rb == nullptr); RID voxel_gi_buffer = p_scene_render->render_buffers_get_voxel_gi_buffer(p_render_buffers); @@ -3119,9 +3119,9 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { RD::get_singleton()->draw_command_begin_label("GI Render"); - RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers); + RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(rb == nullptr); - RendererSceneEnvironmentRD *env = p_scene_render->environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = p_scene_render->environment_owner.get_or_null(p_environment); if (rb->ambient_buffer.is_null() || rb->gi.using_half_size_gi != half_resolution) { if (rb->ambient_buffer.is_valid()) { @@ -3393,7 +3393,7 @@ void RendererSceneGIRD::voxel_gi_update(RID p_probe, bool p_update_light_instanc } void RendererSceneGIRD::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { - VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.getornull(p_voxel_gi); + VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha); diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h index 0b4622646f..5bd41a104e 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h @@ -383,7 +383,7 @@ public: mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner; _FORCE_INLINE_ VoxelGIInstance *get_probe_instance(RID p_probe) const { - return voxel_gi_instance_owner.getornull(p_probe); + return voxel_gi_instance_owner.get_or_null(p_probe); }; _FORCE_INLINE_ RID voxel_gi_instance_get_texture(RID p_probe) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 0f98417215..a1c2f4f49c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -48,8 +48,8 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) { } void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); bool needs_sdfgi = env && env->sdfgi_enabled; if (!needs_sdfgi) { @@ -83,7 +83,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment } int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers) const { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, 0); @@ -113,7 +113,7 @@ AABB RendererSceneRenderRD::sdfgi_get_pending_region_bounds(RID p_render_buffers AABB bounds; Vector3i from; Vector3i size; - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, AABB()); ERR_FAIL_COND_V(rb->sdfgi == nullptr, AABB()); @@ -126,7 +126,7 @@ uint32_t RendererSceneRenderRD::sdfgi_get_pending_region_cascade(RID p_render_bu AABB bounds; Vector3i from; Vector3i size; - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(rb == nullptr, -1); ERR_FAIL_COND_V(rb->sdfgi == nullptr, -1); @@ -164,139 +164,139 @@ void RendererSceneRenderRD::environment_initialize(RID p_rid) { } void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->background = p_bg; } void RendererSceneRenderRD::environment_set_sky(RID p_env, RID p_sky) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->sky = p_sky; } void RendererSceneRenderRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->sky_custom_fov = p_scale; } void RendererSceneRenderRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->sky_orientation = p_orientation; } void RendererSceneRenderRD::environment_set_bg_color(RID p_env, const Color &p_color) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->bg_color = p_color; } void RendererSceneRenderRD::environment_set_bg_energy(RID p_env, float p_energy) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->bg_energy = p_energy; } void RendererSceneRenderRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->canvas_max_layer = p_max_layer; } void RendererSceneRenderRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_ambient_light(p_color, p_ambient, p_energy, p_sky_contribution, p_reflection_source, p_ao_color); } RS::EnvironmentBG RendererSceneRenderRD::environment_get_background(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); return env->background; } RID RendererSceneRenderRD::environment_get_sky(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RID()); return env->sky; } float RendererSceneRenderRD::environment_get_sky_custom_fov(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->sky_custom_fov; } Basis RendererSceneRenderRD::environment_get_sky_orientation(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Basis()); return env->sky_orientation; } Color RendererSceneRenderRD::environment_get_bg_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->bg_color; } float RendererSceneRenderRD::environment_get_bg_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->bg_energy; } int RendererSceneRenderRD::environment_get_canvas_max_layer(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->canvas_max_layer; } Color RendererSceneRenderRD::environment_get_ambient_light_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ambient_light; } RS::EnvironmentAmbientSource RendererSceneRenderRD::environment_get_ambient_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); return env->ambient_source; } float RendererSceneRenderRD::environment_get_ambient_light_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_light_energy; } float RendererSceneRenderRD::environment_get_ambient_sky_contribution(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_sky_contribution; } RS::EnvironmentReflectionSource RendererSceneRenderRD::environment_get_reflection_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED); return env->reflection_source; } Color RendererSceneRenderRD::environment_get_ao_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ao_color; } void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_tonemap(p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale); } void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_glow(p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap); } @@ -310,7 +310,7 @@ void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable) } void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); if (!is_dynamic_gi_supported()) { @@ -321,58 +321,58 @@ void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS:: } void RendererSceneRenderRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_fog(p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_fog_aerial_perspective); } bool RendererSceneRenderRD::environment_is_fog_enabled(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->fog_enabled; } Color RendererSceneRenderRD::environment_get_fog_light_color(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Color()); return env->fog_light_color; } float RendererSceneRenderRD::environment_get_fog_light_energy(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_light_energy; } float RendererSceneRenderRD::environment_get_fog_sun_scatter(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_sun_scatter; } float RendererSceneRenderRD::environment_get_fog_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_density; } float RendererSceneRenderRD::environment_get_fog_height(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_height; } float RendererSceneRenderRD::environment_get_fog_height_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_height_density; } float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0); return env->fog_aerial_perspective; } void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); if (!is_volumetric_supported()) { @@ -403,7 +403,7 @@ void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::Env } void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_ssr(p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance); @@ -418,7 +418,7 @@ RS::EnvironmentSSRRoughnessQuality RendererSceneRenderRD::environment_get_ssr_ro } void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->set_ssao(p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect); @@ -434,30 +434,30 @@ void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQual } bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->ssao_enabled; } float RendererSceneRenderRD::environment_get_ssao_ao_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0.0); return env->ssao_ao_channel_affect; } float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, 0.0); return env->ssao_direct_light_affect; } bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->ssr_enabled; } bool RendererSceneRenderRD::environment_is_sdfgi_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, false); return env->sdfgi_enabled; } @@ -467,7 +467,7 @@ bool RendererSceneRenderRD::is_environment(RID p_env) const { } Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND_V(!env, Ref<Image>()); if (env->background == RS::ENV_BG_CAMERA_FEED || env->background == RS::ENV_BG_CANVAS || env->background == RS::ENV_BG_KEEP) { @@ -522,7 +522,7 @@ RID RendererSceneRenderRD::reflection_atlas_create() { } void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) { - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas); ERR_FAIL_COND(!ra); if (ra->size == p_reflection_size && ra->count == p_reflection_count) { @@ -557,7 +557,7 @@ void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_ref } int RendererSceneRenderRD::reflection_atlas_get_size(RID p_ref_atlas) const { - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas); ERR_FAIL_COND_V(!ra, 0); return ra->size; @@ -573,7 +573,7 @@ RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) { } void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!rpi); rpi->transform = p_transform; @@ -581,13 +581,13 @@ void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instan } void RendererSceneRenderRD::reflection_probe_release_atlas_index(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!rpi); if (rpi->atlas.is_null()) { return; //nothing to release } - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND(!atlas); ERR_FAIL_INDEX(rpi->atlas_index, atlas->reflections.size()); atlas->reflections.write[rpi->atlas_index].owner = RID(); @@ -596,7 +596,7 @@ void RendererSceneRenderRD::reflection_probe_release_atlas_index(RID p_instance) } bool RendererSceneRenderRD::reflection_probe_instance_needs_redraw(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); if (rpi->rendering) { @@ -615,18 +615,18 @@ bool RendererSceneRenderRD::reflection_probe_instance_needs_redraw(RID p_instanc } bool RendererSceneRenderRD::reflection_probe_instance_has_reflection(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); return rpi->atlas.is_valid(); } bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_reflection_atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas); ERR_FAIL_COND_V(!atlas, false); - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); RD::get_singleton()->draw_command_begin_label("Reflection probe render"); @@ -701,7 +701,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc uint64_t pass_min = 0; for (int i = 0; i < atlas->reflections.size(); i++) { - ReflectionProbeInstance *rpi2 = reflection_probe_instance_owner.getornull(atlas->reflections[i].owner); + ReflectionProbeInstance *rpi2 = reflection_probe_instance_owner.get_or_null(atlas->reflections[i].owner); if (rpi2->last_pass < pass_min) { pass_min = rpi2->last_pass; rpi->atlas_index = i; @@ -733,12 +733,12 @@ RID RendererSceneRenderRD::reflection_probe_create_framebuffer(RID p_color, RID } bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, false); ERR_FAIL_COND_V(!rpi->rendering, false); ERR_FAIL_COND_V(rpi->atlas.is_null(), false); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); if (!atlas || rpi->atlas_index == -1) { //does not belong to an atlas anymore, cancel (was removed from atlas or atlas changed while rendering) rpi->rendering = false; @@ -779,30 +779,30 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins } uint32_t RendererSceneRenderRD::reflection_probe_instance_get_resolution(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, 0); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND_V(!atlas, 0); return atlas->size; } RID RendererSceneRenderRD::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, RID()); ERR_FAIL_INDEX_V(p_index, 6, RID()); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND_V(!atlas, RID()); return atlas->reflections[rpi->atlas_index].fbs[p_index]; } RID RendererSceneRenderRD::reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, RID()); ERR_FAIL_INDEX_V(p_index, 6, RID()); - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas); ERR_FAIL_COND_V(!atlas, RID()); return atlas->depth_fb; } @@ -829,7 +829,7 @@ void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) { } void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); p_size = next_power_of_2(p_size); @@ -850,8 +850,8 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool } //erase shadow atlas reference from lights - for (Map<RID, uint32_t>::Element *E = shadow_atlas->shadow_owners.front(); E; E = E->next()) { - LightInstance *li = light_instance_owner.getornull(E->key()); + for (const KeyValue<RID, uint32_t> &E : shadow_atlas->shadow_owners) { + LightInstance *li = light_instance_owner.get_or_null(E.key); ERR_CONTINUE(!li); li->shadow_atlases.erase(p_atlas); } @@ -864,7 +864,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool } void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_INDEX(p_quadrant, 4); ERR_FAIL_INDEX(p_subdivision, 16384); @@ -886,7 +886,7 @@ void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, i for (int i = 0; i < shadow_atlas->quadrants[p_quadrant].shadows.size(); i++) { if (shadow_atlas->quadrants[p_quadrant].shadows[i].owner.is_valid()) { shadow_atlas->shadow_owners.erase(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); - LightInstance *li = light_instance_owner.getornull(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); + LightInstance *li = light_instance_owner.get_or_null(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); ERR_CONTINUE(!li); li->shadow_atlases.erase(p_atlas); } @@ -947,7 +947,7 @@ bool RendererSceneRenderRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, break; } - LightInstance *sli = light_instance_owner.getornull(sarr[j].owner); + LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner); ERR_CONTINUE(!sli); if (sli->last_scene_pass != scene_pass) { @@ -999,7 +999,7 @@ bool RendererSceneRenderRD::_shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_ uint64_t pass = 0; if (sarr[j].owner.is_valid()) { - LightInstance *sli = light_instance_owner.getornull(sarr[j].owner); + LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner); ERR_CONTINUE(!sli); if (sli->last_scene_pass == scene_pass) { @@ -1014,7 +1014,7 @@ bool RendererSceneRenderRD::_shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_ } if (sarr[j + 1].owner.is_valid()) { - LightInstance *sli = light_instance_owner.getornull(sarr[j + 1].owner); + LightInstance *sli = light_instance_owner.get_or_null(sarr[j + 1].owner); ERR_CONTINUE(!sli); if (sli->last_scene_pass == scene_pass) { @@ -1053,10 +1053,10 @@ bool RendererSceneRenderRD::_shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_ } bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND_V(!shadow_atlas, false); - LightInstance *li = light_instance_owner.getornull(p_light_intance); + LightInstance *li = light_instance_owner.get_or_null(p_light_intance); ERR_FAIL_COND_V(!li, false); if (shadow_atlas->size == 0 || shadow_atlas->smallest_subdiv == 0) { @@ -1179,7 +1179,7 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i void RendererSceneRenderRD::_shadow_atlas_invalidate_shadow(RendererSceneRenderRD::ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, RendererSceneRenderRD::ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx) { if (p_shadow->owner.is_valid()) { - LightInstance *sli = light_instance_owner.getornull(p_shadow->owner); + LightInstance *sli = light_instance_owner.get_or_null(p_shadow->owner); uint32_t old_key = p_shadow_atlas->shadow_owners[p_shadow->owner]; if (old_key & ShadowAtlas::OMNI_LIGHT_FLAG) { @@ -1260,7 +1260,7 @@ int RendererSceneRenderRD::get_directional_light_shadow_size(RID p_light_intance Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0); - LightInstance *light_instance = light_instance_owner.getornull(p_light_intance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_intance); ERR_FAIL_COND_V(!light_instance, 0); switch (storage->light_directional_get_shadow_mode(light_instance->light)) { @@ -1296,7 +1296,7 @@ void RendererSceneRenderRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokeh } void RendererSceneRenderRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) { - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + CameraEffects *camfx = camera_effects_owner.get_or_null(p_camera_effects); ERR_FAIL_COND(!camfx); camfx->dof_blur_far_enabled = p_far_enable; @@ -1311,7 +1311,7 @@ void RendererSceneRenderRD::camera_effects_set_dof_blur(RID p_camera_effects, bo } void RendererSceneRenderRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + CameraEffects *camfx = camera_effects_owner.get_or_null(p_camera_effects); ERR_FAIL_COND(!camfx); camfx->override_exposure_enabled = p_enable; @@ -1321,7 +1321,7 @@ void RendererSceneRenderRD::camera_effects_set_custom_exposure(RID p_camera_effe RID RendererSceneRenderRD::light_instance_create(RID p_light) { RID li = light_instance_owner.make_rid(LightInstance()); - LightInstance *light_instance = light_instance_owner.getornull(li); + LightInstance *light_instance = light_instance_owner.get_or_null(li); light_instance->self = li; light_instance->light = p_light; @@ -1334,21 +1334,21 @@ RID RendererSceneRenderRD::light_instance_create(RID p_light) { } void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->transform = p_transform; } void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->aabb = p_aabb; } void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); ERR_FAIL_INDEX(p_pass, 6); @@ -1364,7 +1364,7 @@ void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_inst } void RendererSceneRenderRD::light_instance_mark_visible(RID p_light_instance) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); light_instance->last_scene_pass = scene_pass; @@ -1407,7 +1407,7 @@ RID RendererSceneRenderRD::decal_instance_create(RID p_decal) { } void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) { - DecalInstance *di = decal_instance_owner.getornull(p_decal); + DecalInstance *di = decal_instance_owner.get_or_null(p_decal); ERR_FAIL_COND(!di); di->transform = p_transform; } @@ -1420,7 +1420,7 @@ RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) { return lightmap_instance_owner.make_rid(li); } void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) { - LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap); + LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!li); li->transform = p_transform; } @@ -1452,7 +1452,7 @@ void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_ins } void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); if (!rb->sdfgi) { @@ -1790,7 +1790,7 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { } void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); bool can_use_effects = rb->width >= 8 && rb->height >= 8; @@ -1808,7 +1808,7 @@ void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatri } void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); bool can_use_effects = rb->width >= 8 && rb->height >= 8; @@ -1819,7 +1819,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb return; } - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); ERR_FAIL_COND(!env); ERR_FAIL_COND(!env->ssr_enabled); @@ -1860,10 +1860,10 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb } void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); ERR_FAIL_COND(!env); RENDER_TIMESTAMP("Process SSAO"); @@ -2005,7 +2005,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen } void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); RD::get_singleton()->draw_command_begin_label("Copy screen texture"); @@ -2034,7 +2034,7 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData } void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); RD::get_singleton()->draw_command_begin_label("Copy depth texture"); @@ -2057,12 +2057,12 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR } void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); //glow (if enabled) - CameraEffects *camfx = camera_effects_owner.getornull(p_render_data->camera_effects); + CameraEffects *camfx = camera_effects_owner.get_or_null(p_render_data->camera_effects); bool can_use_effects = rb->width >= 8 && rb->height >= 8; bool can_use_storage = _render_buffers_can_be_storage(); @@ -2251,10 +2251,10 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data) { RD::get_singleton()->draw_command_begin_label("Post Process Subpass"); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); bool can_use_effects = rb->width >= 8 && rb->height >= 8; @@ -2311,7 +2311,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr } void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_data) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); storage->render_target_disable_clear_request(rb->render_target); @@ -2320,7 +2320,7 @@ void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) { EffectsRD *effects = storage->get_effects(); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS) { @@ -2386,7 +2386,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID } void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); ERR_FAIL_COND(!env); env->adjustments_enabled = p_enable; @@ -2398,7 +2398,7 @@ void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, } RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->blur[0].texture.is_valid()) { return RID(); //not valid at the moment @@ -2407,7 +2407,7 @@ RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_b } RID RendererSceneRenderRD::render_buffers_get_back_depth_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->depth_back_texture.is_valid()) { return RID(); //not valid at the moment @@ -2416,21 +2416,21 @@ RID RendererSceneRenderRD::render_buffers_get_back_depth_texture(RID p_render_bu } RID RendererSceneRenderRD::render_buffers_get_depth_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->depth_texture; } RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->ssao.ao_final; } RID RendererSceneRenderRD::render_buffers_get_voxel_gi_buffer(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (rb->gi.voxel_gi_buffer.is_null()) { rb->gi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::VoxelGIData) * RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES); @@ -2443,31 +2443,31 @@ RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() { } RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->ambient_buffer; } RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); return rb->reflection_buffer; } uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); return rb->sdfgi->cascades.size(); } bool RendererSceneRenderRD::render_buffers_is_sdfgi_enabled(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, false); return rb->sdfgi != nullptr; } RID RendererSceneRenderRD::render_buffers_get_sdfgi_irradiance_probes(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); ERR_FAIL_COND_V(!rb->sdfgi, RID()); @@ -2475,7 +2475,7 @@ RID RendererSceneRenderRD::render_buffers_get_sdfgi_irradiance_probes(RID p_rend } Vector3 RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_offset(RID p_render_buffers, uint32_t p_cascade) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, Vector3()); ERR_FAIL_COND_V(!rb->sdfgi, Vector3()); ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), Vector3()); @@ -2484,7 +2484,7 @@ Vector3 RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_offset(RID p_ren } Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RID p_render_buffers, uint32_t p_cascade) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, Vector3i()); ERR_FAIL_COND_V(!rb->sdfgi, Vector3i()); ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), Vector3i()); @@ -2494,14 +2494,14 @@ Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RI } float RendererSceneRenderRD::render_buffers_get_sdfgi_normal_bias(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); return rb->sdfgi->normal_bias; } float RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_render_buffers, uint32_t p_cascade) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), 0); @@ -2509,7 +2509,7 @@ float RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_size(RID p_r return float(rb->sdfgi->cascade_size) * rb->sdfgi->cascades[p_cascade].cell_size / float(rb->sdfgi->probe_axis_count - 1); } uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_count(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); @@ -2517,7 +2517,7 @@ uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_count(RID } uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_size(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0); ERR_FAIL_COND_V(!rb->sdfgi, 0); @@ -2525,7 +2525,7 @@ uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_size(RID p_rend } bool RendererSceneRenderRD::render_buffers_is_sdfgi_using_occlusion(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, false); ERR_FAIL_COND_V(!rb->sdfgi, false); @@ -2533,14 +2533,14 @@ bool RendererSceneRenderRD::render_buffers_is_sdfgi_using_occlusion(RID p_render } float RendererSceneRenderRD::render_buffers_get_sdfgi_energy(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, 0.0); ERR_FAIL_COND_V(!rb->sdfgi, 0.0); return rb->sdfgi->energy; } RID RendererSceneRenderRD::render_buffers_get_sdfgi_occlusion_texture(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); ERR_FAIL_COND_V(!rb->sdfgi, RID()); @@ -2548,20 +2548,20 @@ RID RendererSceneRenderRD::render_buffers_get_sdfgi_occlusion_texture(RID p_rend } bool RendererSceneRenderRD::render_buffers_has_volumetric_fog(RID p_render_buffers) const { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, false); return rb->volumetric_fog != nullptr; } RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_texture(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, RID()); return rb->volumetric_fog->fog_map; } RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->volumetric_fog) { @@ -2572,12 +2572,12 @@ RID RendererSceneRenderRD::render_buffers_get_volumetric_fog_sky_uniform_set(RID } float RendererSceneRenderRD::render_buffers_get_volumetric_fog_end(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0); return rb->volumetric_fog->length; } float RendererSceneRenderRD::render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers) { - const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + const RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb || !rb->volumetric_fog, 0); return rb->volumetric_fog->spread; } @@ -2597,7 +2597,7 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() { void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) { ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view"); - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); // Should we add an overrule per viewport? rb->width = p_width; @@ -2801,7 +2801,7 @@ bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const { } RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_get_data(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, nullptr); return rb->data; } @@ -2814,7 +2814,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti break; } - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_reflections[i]); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_reflections[i]); if (!rpi) { continue; } @@ -2900,7 +2900,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const r_directional_light_soft_shadows = false; for (int i = 0; i < (int)p_lights.size(); i++) { - LightInstance *li = light_instance_owner.getornull(p_lights[i]); + LightInstance *li = light_instance_owner.get_or_null(p_lights[i]); if (!li) { continue; } @@ -3129,7 +3129,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const ShadowAtlas *shadow_atlas = nullptr; if (p_shadow_atlas.is_valid() && p_using_shadows) { - shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); } bool using_forward_ids = _uses_forward_ids(); @@ -3312,7 +3312,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const break; } - DecalInstance *di = decal_instance_owner.getornull(p_decals[i]); + DecalInstance *di = decal_instance_owner.get_or_null(p_decals[i]); if (!di) { continue; } @@ -3495,9 +3495,9 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) { void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count) { ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); float ratio = float(rb->width) / float((rb->width + rb->height) / 2); uint32_t target_width = uint32_t(float(volumetric_fog_size) * ratio); @@ -3566,7 +3566,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { @@ -3888,7 +3888,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { if (p_render_data->render_buffers.is_valid()) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); if (rb->sdfgi != nullptr) { return true; } @@ -3899,14 +3899,14 @@ bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_da void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { if (p_render_data->render_buffers.is_valid()) { if (p_use_gi) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi == nullptr) { return; } - RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment); - rb->sdfgi->update_probes(env, sky.sky_owner.getornull(env->sky)); + RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); + rb->sdfgi->update_probes(env, sky.sky_owner.get_or_null(env->sky)); } } } @@ -3923,7 +3923,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool // Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time if (p_render_data->render_buffers.is_valid() && p_use_gi) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(rb == nullptr); if (rb->sdfgi != nullptr) { rb->sdfgi->store_probes(); @@ -3938,7 +3938,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier(); { for (int i = 0; i < render_state.render_shadow_count; i++) { - LightInstance *li = light_instance_owner.getornull(render_state.render_shadows[i].light); + LightInstance *li = light_instance_owner.get_or_null(render_state.render_shadows[i].light); if (storage->light_get_type(li->light) == RS::LIGHT_DIRECTIONAL) { render_state.directional_shadows.push_back(i); @@ -4058,7 +4058,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData // getting this here now so we can direct call a bunch of things more easily RenderBuffers *rb = nullptr; if (p_render_buffers.is_valid()) { - rb = render_buffers_owner.getornull(p_render_buffers); + rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); } @@ -4140,7 +4140,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData //assign render indices to voxel_gi_instances if (is_dynamic_gi_supported()) { for (uint32_t i = 0; i < (uint32_t)p_voxel_gi_instances.size(); i++) { - RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.getornull(p_voxel_gi_instances[i]); + RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]); if (voxel_gi_inst) { voxel_gi_inst->render_index = i; } @@ -4151,8 +4151,8 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData // render_data.render_buffers == p_render_buffers so we can use our already retrieved rb current_cluster_builder = rb->cluster_builder; } else if (reflection_probe_instance_owner.owns(render_data.reflection_probe)) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_data.reflection_probe); - ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(render_data.reflection_probe); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(rpi->atlas); if (!ra) { ERR_PRINT("reflection probe has no reflection atlas! Bug?"); current_cluster_builder = nullptr; @@ -4230,7 +4230,7 @@ void RendererSceneRenderRD::_debug_draw_cluster(RID p_render_buffers) { } void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { - LightInstance *light_instance = light_instance_owner.getornull(p_light); + LightInstance *light_instance = light_instance_owner.get_or_null(p_light); ERR_FAIL_COND(!light_instance); Rect2i atlas_rect; @@ -4301,7 +4301,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } else { //set from shadow atlas - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light)); @@ -4424,7 +4424,7 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, bool RendererSceneRenderRD::free(RID p_rid) { if (render_buffers_owner.owns(p_rid)) { - RenderBuffers *rb = render_buffers_owner.getornull(p_rid); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_rid); _free_render_buffer_data(rb); memdelete(rb->data); if (rb->sdfgi) { @@ -4447,24 +4447,24 @@ bool RendererSceneRenderRD::free(RID p_rid) { camera_effects_owner.free(p_rid); } else if (reflection_atlas_owner.owns(p_rid)) { reflection_atlas_set_size(p_rid, 0, 0); - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_rid); + ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_rid); if (ra->cluster_builder) { memdelete(ra->cluster_builder); } reflection_atlas_owner.free(p_rid); } else if (reflection_probe_instance_owner.owns(p_rid)) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_rid); _free_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id); reflection_probe_release_atlas_index(p_rid); reflection_probe_instance_owner.free(p_rid); } else if (decal_instance_owner.owns(p_rid)) { - DecalInstance *di = decal_instance_owner.getornull(p_rid); + DecalInstance *di = decal_instance_owner.get_or_null(p_rid); _free_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id); decal_instance_owner.free(p_rid); } else if (lightmap_instance_owner.owns(p_rid)) { lightmap_instance_owner.free(p_rid); } else if (gi.voxel_gi_instance_owner.owns(p_rid)) { - RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.getornull(p_rid); + RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid); if (voxel_gi->texture.is_valid()) { RD::get_singleton()->free(voxel_gi->texture); RD::get_singleton()->free(voxel_gi->write_buffer); @@ -4480,11 +4480,11 @@ bool RendererSceneRenderRD::free(RID p_rid) { sky.update_dirty_skys(); sky.free_sky(p_rid); } else if (light_instance_owner.owns(p_rid)) { - LightInstance *light_instance = light_instance_owner.getornull(p_rid); + LightInstance *light_instance = light_instance_owner.get_or_null(p_rid); //remove from shadow atlases.. for (Set<RID>::Element *E = light_instance->shadow_atlases.front(); E; E = E->next()) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(E->get()); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E->get()); ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_rid)); uint32_t key = shadow_atlas->shadow_owners[p_rid]; uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; @@ -4801,8 +4801,8 @@ void RendererSceneRenderRD::init() { } RendererSceneRenderRD::~RendererSceneRenderRD() { - for (Map<int, ShadowCubemap>::Element *E = shadow_cubemaps.front(); E; E = E->next()) { - RD::get_singleton()->free(E->get().cubemap); + for (const KeyValue<int, ShadowCubemap> &E : shadow_cubemaps) { + RD::get_singleton()->free(E.value.cubemap); } if (sky.sky_scene_state.uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky.sky_scene_state.uniform_set)) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index db423b7d25..fa80b84cfe 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -149,7 +149,7 @@ protected: RendererSceneEnvironmentRD *get_environment(RID p_environment) { if (p_environment.is_valid()) { - return environment_owner.getornull(p_environment); + return environment_owner.get_or_null(p_environment); } else { return nullptr; } @@ -814,19 +814,19 @@ public: virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override; virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override; _FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) { - ShadowAtlas *atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND_V(!atlas, false); return atlas->shadow_owners.has(p_light_intance); } _FORCE_INLINE_ RID shadow_atlas_get_texture(RID p_atlas) { - ShadowAtlas *atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND_V(!atlas, RID()); return atlas->depth; } _FORCE_INLINE_ Size2i shadow_atlas_get_size(RID p_atlas) { - ShadowAtlas *atlas = shadow_atlas_owner.getornull(p_atlas); + ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_COND_V(!atlas, Size2i()); return Size2(atlas->size, atlas->size); } @@ -942,7 +942,7 @@ public: virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override; bool camera_effects_uses_dof(RID p_camera_effects) { - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); + CameraEffects *camfx = camera_effects_owner.get_or_null(p_camera_effects); return camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0; } @@ -954,18 +954,18 @@ public: virtual void light_instance_mark_visible(RID p_light_instance) override; _FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->light; } _FORCE_INLINE_ Transform3D light_instance_get_base_transform(RID p_light_instance) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->transform; } _FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas, Vector2i &r_omni_offset) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); - LightInstance *li = light_instance_owner.getornull(p_light_instance); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); uint32_t key = shadow_atlas->shadow_owners[li->self]; uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; @@ -1000,16 +1000,16 @@ public: } _FORCE_INLINE_ CameraMatrix light_instance_get_shadow_camera(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].camera; } _FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) { #ifdef DEBUG_ENABLED - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0); #endif - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); ERR_FAIL_COND_V(!shadow_atlas, 0); #ifdef DEBUG_ENABLED ERR_FAIL_COND_V(!shadow_atlas->shadow_owners.has(p_light_instance), 0); @@ -1027,59 +1027,59 @@ public: _FORCE_INLINE_ Transform3D light_instance_get_shadow_transform(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].transform; } _FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].bias_scale; } _FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].farplane; } _FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].range_begin; } _FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].uv_scale; } _FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].atlas_rect; } _FORCE_INLINE_ float light_instance_get_directional_shadow_split(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].split; } _FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].shadow_texel_size; } _FORCE_INLINE_ void light_instance_set_render_pass(RID p_light_instance, uint64_t p_pass) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); li->last_pass = p_pass; } _FORCE_INLINE_ uint64_t light_instance_get_render_pass(RID p_light_instance) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->last_pass; } _FORCE_INLINE_ ForwardID light_instance_get_forward_id(RID p_light_instance) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->forward_id; } _FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); + LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->light_type; } @@ -1088,7 +1088,7 @@ public: virtual int reflection_atlas_get_size(RID p_ref_atlas) const override; _FORCE_INLINE_ RID reflection_atlas_get_texture(RID p_ref_atlas) { - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_ref_atlas); + ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_ref_atlas); ERR_FAIL_COND_V(!atlas, RID()); return atlas->reflection; } @@ -1107,41 +1107,41 @@ public: RID reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index); _FORCE_INLINE_ RID reflection_probe_instance_get_probe(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, RID()); return rpi->probe; } _FORCE_INLINE_ ForwardID reflection_probe_instance_get_forward_id(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, 0); return rpi->forward_id; } _FORCE_INLINE_ void reflection_probe_instance_set_render_pass(RID p_instance, uint32_t p_render_pass) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!rpi); rpi->last_pass = p_render_pass; } _FORCE_INLINE_ uint32_t reflection_probe_instance_get_render_pass(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, 0); return rpi->last_pass; } _FORCE_INLINE_ Transform3D reflection_probe_instance_get_transform(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, Transform3D()); return rpi->transform; } _FORCE_INLINE_ int reflection_probe_instance_get_atlas_index(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!rpi, -1); return rpi->atlas_index; @@ -1151,32 +1151,32 @@ public: virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override; _FORCE_INLINE_ RID decal_instance_get_base(RID p_decal) const { - DecalInstance *decal = decal_instance_owner.getornull(p_decal); + DecalInstance *decal = decal_instance_owner.get_or_null(p_decal); return decal->decal; } _FORCE_INLINE_ ForwardID decal_instance_get_forward_id(RID p_decal) const { - DecalInstance *decal = decal_instance_owner.getornull(p_decal); + DecalInstance *decal = decal_instance_owner.get_or_null(p_decal); return decal->forward_id; } _FORCE_INLINE_ Transform3D decal_instance_get_transform(RID p_decal) const { - DecalInstance *decal = decal_instance_owner.getornull(p_decal); + DecalInstance *decal = decal_instance_owner.get_or_null(p_decal); return decal->transform; } virtual RID lightmap_instance_create(RID p_lightmap) override; virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override; _FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) { - return lightmap_instance_owner.getornull(p_lightmap_instance) != nullptr; + return lightmap_instance_owner.get_or_null(p_lightmap_instance) != nullptr; } _FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) { - LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance); + LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap_instance); return li->lightmap; } _FORCE_INLINE_ Transform3D lightmap_instance_get_transform(RID p_lightmap_instance) { - LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance); + LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap_instance); return li->transform; } diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index c388da755c..830b0e7bae 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -148,36 +148,36 @@ void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringNa void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } - if (E->get().texture_order >= 0) { - order[E->get().texture_order + 100000] = E->key(); + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; } else { - order[E->get().order] = E->key(); + order[E.value.order] = E.key; } } - for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); - pi.name = E->get(); + for (const KeyValue<int, StringName> &E : order) { + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; p_param_list->push_back(pi); } } void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } RendererStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E->get()); - p.info.name = E->key(); //supply name - p.index = E->get().instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint); p_param_list->push_back(p); } } @@ -1772,7 +1772,7 @@ void RendererSceneSkyRD::initialize_sky_rid(RID p_rid) { } RendererSceneSkyRD::Sky *RendererSceneSkyRD::get_sky(RID p_sky) const { - return sky_owner.getornull(p_sky); + return sky_owner.get_or_null(p_sky); } void RendererSceneSkyRD::free_sky(RID p_sky) { diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index ed87932762..5ef1f46742 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -842,7 +842,7 @@ void RendererStorageRD::texture_3d_initialize(RID p_texture, Image::Format p_for } void RendererStorageRD::texture_proxy_initialize(RID p_texture, RID p_base) { - Texture *tex = texture_owner.getornull(p_base); + Texture *tex = texture_owner.get_or_null(p_base); ERR_FAIL_COND(!tex); Texture proxy_tex = *tex; @@ -865,7 +865,7 @@ void RendererStorageRD::texture_proxy_initialize(RID p_texture, RID p_base) { void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { ERR_FAIL_COND(p_image.is_null() || p_image->is_empty()); - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->is_render_target); ERR_FAIL_COND(p_image->get_width() != tex->width || p_image->get_height() != tex->height); @@ -889,7 +889,7 @@ void RendererStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_ima } void RendererStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->type != Texture::TYPE_3D); Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data); @@ -926,10 +926,10 @@ void RendererStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image> } void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(!tex->is_proxy); - Texture *proxy_to = texture_owner.getornull(p_proxy_to); + Texture *proxy_to = texture_owner.get_or_null(p_proxy_to); ERR_FAIL_COND(!proxy_to); ERR_FAIL_COND(proxy_to->is_proxy); @@ -943,7 +943,7 @@ void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { RD::get_singleton()->free(tex->rd_texture_srgb); tex->rd_texture_srgb = RID(); } - Texture *prev_tex = texture_owner.getornull(tex->proxy_to); + Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to); ERR_FAIL_COND(!prev_tex); prev_tex->proxies.erase(p_texture); } @@ -1030,7 +1030,7 @@ void RendererStorageRD::texture_3d_placeholder_initialize(RID p_texture) { } Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!tex, Ref<Image>()); #ifdef TOOLS_ENABLED @@ -1058,7 +1058,7 @@ Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const { } Ref<Image> RendererStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!tex, Ref<Image>()); Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer); @@ -1075,7 +1075,7 @@ Ref<Image> RendererStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) c } Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>()); ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>()); @@ -1106,10 +1106,10 @@ Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const { } void RendererStorageRD::texture_replace(RID p_texture, RID p_by_texture) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->proxy_to.is_valid()); //can't replace proxy - Texture *by_tex = texture_owner.getornull(p_by_texture); + Texture *by_tex = texture_owner.get_or_null(p_by_texture); ERR_FAIL_COND(!by_tex); ERR_FAIL_COND(by_tex->proxy_to.is_valid()); //can't replace proxy @@ -1155,7 +1155,7 @@ void RendererStorageRD::texture_replace(RID p_texture, RID p_by_texture) { } void RendererStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->type != Texture::TYPE_2D); tex->width_2d = p_width; @@ -1163,7 +1163,7 @@ void RendererStorageRD::texture_set_size_override(RID p_texture, int p_width, in } void RendererStorageRD::texture_set_path(RID p_texture, const String &p_path) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); tex->path = p_path; } @@ -1173,21 +1173,21 @@ String RendererStorageRD::texture_get_path(RID p_texture) const { } void RendererStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); tex->detect_3d_callback_ud = p_userdata; tex->detect_3d_callback = p_callback; } void RendererStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); tex->detect_normal_callback_ud = p_userdata; tex->detect_normal_callback = p_callback; } void RendererStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) { - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); ERR_FAIL_COND(!tex); tex->detect_roughness_callback_ud = p_userdata; tex->detect_roughness_callback = p_callback; @@ -1235,7 +1235,7 @@ void RendererStorageRD::canvas_texture_initialize(RID p_rid) { } void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { - CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); switch (p_channel) { case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: { ct->diffuse = p_texture; @@ -1252,7 +1252,7 @@ void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::Can } void RendererStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { - CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); ct->specular_color.r = p_specular_color.r; ct->specular_color.g = p_specular_color.g; ct->specular_color.b = p_specular_color.b; @@ -1261,13 +1261,13 @@ void RendererStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_textu } void RendererStorageRD::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { - CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); ct->texture_filter = p_filter; ct->clear_sets(); } void RendererStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { - CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture); + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); ct->texture_repeat = p_repeat; ct->clear_sets(); } @@ -1275,7 +1275,7 @@ void RendererStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture, bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) { CanvasTexture *ct = nullptr; - Texture *t = texture_owner.getornull(p_texture); + Texture *t = texture_owner.get_or_null(p_texture); if (t) { //regular texture @@ -1286,7 +1286,7 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas ct = t->canvas_texture; } else { - ct = canvas_texture_owner.getornull(p_texture); + ct = canvas_texture_owner.get_or_null(p_texture); } if (!ct) { @@ -1308,7 +1308,7 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - t = texture_owner.getornull(ct->diffuse); + t = texture_owner.get_or_null(ct->diffuse); if (!t) { u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); ct->size_cache = Size2i(1, 1); @@ -1323,7 +1323,7 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - t = texture_owner.getornull(ct->normal_map); + t = texture_owner.get_or_null(ct->normal_map); if (!t) { u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL)); ct->use_normal_cache = false; @@ -1338,7 +1338,7 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - t = texture_owner.getornull(ct->specular); + t = texture_owner.get_or_null(ct->specular); if (!t) { u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); ct->use_specular_cache = false; @@ -1384,7 +1384,7 @@ void RendererStorageRD::shader_initialize(RID p_rid) { } void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) { - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); shader->code = p_code; @@ -1438,8 +1438,8 @@ void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) { } if (shader->data) { - for (Map<StringName, RID>::Element *E = shader->default_texture_parameter.front(); E; E = E->next()) { - shader->data->set_default_texture_param(E->key(), E->get()); + for (const KeyValue<StringName, RID> &E : shader->default_texture_parameter) { + shader->data->set_default_texture_param(E.key, E.value); } } } @@ -1456,13 +1456,13 @@ void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) { } String RendererStorageRD::shader_get_code(RID p_shader) const { - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, String()); return shader->code; } void RendererStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { return shader->data->get_param_list(p_param_list); @@ -1470,7 +1470,7 @@ void RendererStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> * } void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) { - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); if (p_texture.is_valid() && texture_owner.owns(p_texture)) { @@ -1488,7 +1488,7 @@ void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const Str } RID RendererStorageRD::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const { - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RID()); if (shader->default_texture_parameter.has(p_name)) { return shader->default_texture_parameter[p_name]; @@ -1498,7 +1498,7 @@ RID RendererStorageRD::shader_get_default_texture_param(RID p_shader, const Stri } Variant RendererStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const { - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, Variant()); if (shader->data) { return shader->data->get_default_parameter(p_param); @@ -1512,7 +1512,7 @@ void RendererStorageRD::shader_set_data_request_function(ShaderType p_shader_typ } RS::ShaderNativeSourceCode RendererStorageRD::shader_get_native_source_code(RID p_shader) const { - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, RS::ShaderNativeSourceCode()); if (shader->data) { return shader->data->get_native_source_code(); @@ -1527,7 +1527,7 @@ RID RendererStorageRD::material_allocate() { } void RendererStorageRD::material_initialize(RID p_rid) { material_owner.initialize_rid(p_rid); - Material *material = material_owner.getornull(p_rid); + Material *material = material_owner.get_or_null(p_rid); material->self = p_rid; } @@ -1543,7 +1543,7 @@ void RendererStorageRD::_material_queue_update(Material *material, bool p_unifor } void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->data) { @@ -1563,7 +1563,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { return; } - Shader *shader = shader_owner.getornull(p_shader); + Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); material->shader = shader; material->shader_type = shader->type; @@ -1586,7 +1586,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) { } void RendererStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (p_value.get_type() == Variant::NIL) { @@ -1605,7 +1605,7 @@ void RendererStorageRD::material_set_param(RID p_material, const StringName &p_p } Variant RendererStorageRD::material_get_param(RID p_material, const StringName &p_param) const { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND_V(!material, Variant()); if (material->params.has(p_param)) { return material->params[p_param]; @@ -1615,7 +1615,7 @@ Variant RendererStorageRD::material_get_param(RID p_material, const StringName & } void RendererStorageRD::material_set_next_pass(RID p_material, RID p_next_material) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->next_pass == p_next_material) { @@ -1631,7 +1631,7 @@ void RendererStorageRD::material_set_next_pass(RID p_material, RID p_next_materi } void RendererStorageRD::material_set_render_priority(RID p_material, int priority) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); material->priority = priority; if (material->data) { @@ -1640,7 +1640,7 @@ void RendererStorageRD::material_set_render_priority(RID p_material, int priorit } bool RendererStorageRD::material_is_animated(RID p_material) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND_V(!material, false); if (material->shader && material->shader->data) { if (material->shader->data->is_animated()) { @@ -1653,7 +1653,7 @@ bool RendererStorageRD::material_is_animated(RID p_material) { } bool RendererStorageRD::material_casts_shadows(RID p_material) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND_V(!material, true); if (material->shader && material->shader->data) { if (material->shader->data->casts_shadows()) { @@ -1666,7 +1666,7 @@ bool RendererStorageRD::material_casts_shadows(RID p_material) { } void RendererStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { material->shader->data->get_instance_param_list(r_parameters); @@ -1678,7 +1678,7 @@ void RendererStorageRD::material_get_instance_shader_parameters(RID p_material, } void RendererStorageRD::material_update_dependency(RID p_material, DependencyTracker *p_instance) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); ERR_FAIL_COND(!material); p_instance->update_dependency(&material->dependency); if (material->next_pass.is_valid()) { @@ -2136,28 +2136,28 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { bool uses_global_buffer = false; - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) { - if (E->get().order < 0) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : p_uniforms) { + if (E.value.order < 0) { continue; // texture, does not go here } - if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; //instance uniforms don't appear in the bufferr } - if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { + if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { //this is a global variable, get the index to it RendererStorageRD *rs = base_singleton; - GlobalVariables::Variable *gv = rs->global_variables.variables.getptr(E->key()); + GlobalVariables::Variable *gv = rs->global_variables.variables.getptr(E.key); uint32_t index = 0; if (gv) { index = gv->buffer_index; } else { - WARN_PRINT("Shader uses global uniform '" + E->key() + "', but it was removed at some point. Material will not display correctly."); + WARN_PRINT("Shader uses global uniform '" + E.key + "', but it was removed at some point. Material will not display correctly."); } - uint32_t offset = p_uniform_offsets[E->get().order]; + uint32_t offset = p_uniform_offsets[E.value.order]; uint32_t *intptr = (uint32_t *)&p_buffer[offset]; *intptr = index; uses_global_buffer = true; @@ -2165,30 +2165,30 @@ void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName } //regular uniform - uint32_t offset = p_uniform_offsets[E->get().order]; + uint32_t offset = p_uniform_offsets[E.value.order]; #ifdef DEBUG_ENABLED - uint32_t size = ShaderLanguage::get_type_size(E->get().type); + uint32_t size = ShaderLanguage::get_type_size(E.value.type); ERR_CONTINUE(offset + size > p_buffer_size); #endif uint8_t *data = &p_buffer[offset]; - const Map<StringName, Variant>::Element *V = p_parameters.find(E->key()); + const Map<StringName, Variant>::Element *V = p_parameters.find(E.key); if (V) { //user provided - _fill_std140_variant_ubo_value(E->get().type, V->get(), data, p_use_linear_color); + _fill_std140_variant_ubo_value(E.value.type, V->get(), data, p_use_linear_color); - } else if (E->get().default_value.size()) { + } else if (E.value.default_value.size()) { //default value - _fill_std140_ubo_value(E->get().type, E->get().default_value, data); - //value=E->get().default_value; + _fill_std140_ubo_value(E.value.type, E.value.default_value, data); + //value=E.value.default_value; } else { //zero because it was not provided - if (E->get().type == ShaderLanguage::TYPE_VEC4 && E->get().hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + if (E.value.type == ShaderLanguage::TYPE_VEC4 && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { //colors must be set as black, with alpha as 1.0 - _fill_std140_variant_ubo_value(E->get().type, Color(0, 0, 0, 1), data, p_use_linear_color); + _fill_std140_variant_ubo_value(E.value.type, Color(0, 0, 0, 1), data, p_use_linear_color); } else { //else just zero it out - _fill_std140_ubo_empty(E->get().type, data); + _fill_std140_ubo_empty(E.value.type, data); } } } @@ -2215,8 +2215,8 @@ RendererStorageRD::MaterialData::~MaterialData() { //unregister global textures RendererStorageRD *rs = base_singleton; - for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) { - GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E->key()); + for (const KeyValue<StringName, uint64_t> &E : used_global_textures) { + GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } @@ -2309,7 +2309,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari } else { bool srgb = p_use_linear_color && (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO); - Texture *tex = singleton->texture_owner.getornull(texture); + Texture *tex = singleton->texture_owner.get_or_null(texture); if (tex) { rd_texture = (srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; @@ -2470,14 +2470,14 @@ bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<St void RendererStorageRD::_material_uniform_set_erased(const RID &p_set, void *p_material) { RID rid = *(RID *)p_material; - Material *material = base_singleton->material_owner.getornull(rid); + Material *material = base_singleton->material_owner.get_or_null(rid); if (material) { material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL); } } void RendererStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); if (material->shader_type != p_shader_type) { return; } @@ -2518,7 +2518,7 @@ void RendererStorageRD::mesh_initialize(RID p_rid) { void RendererStorageRD::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) { ERR_FAIL_COND(p_blend_shape_count < 0); - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_COND(mesh->surface_count > 0); //surfaces already exist @@ -2528,7 +2528,7 @@ void RendererStorageRD::mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape /// Returns stride void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_COND(mesh->surface_count == RS::MAX_MESH_SURFACES); @@ -2732,13 +2732,13 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su } int RendererStorageRD::mesh_get_blend_shape_count(RID p_mesh) const { - const Mesh *mesh = mesh_owner.getornull(p_mesh); + const Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, -1); return mesh->blend_shape_count; } void RendererStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_INDEX((int)p_mode, 2); @@ -2746,13 +2746,13 @@ void RendererStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode } RS::BlendShapeMode RendererStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, RS::BLEND_SHAPE_MODE_NORMALIZED); return mesh->blend_shape_mode; } void RendererStorageRD::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); ERR_FAIL_COND(p_data.size() == 0); @@ -2763,7 +2763,7 @@ void RendererStorageRD::mesh_surface_update_vertex_region(RID p_mesh, int p_surf } void RendererStorageRD::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); ERR_FAIL_COND(p_data.size() == 0); @@ -2775,7 +2775,7 @@ void RendererStorageRD::mesh_surface_update_attribute_region(RID p_mesh, int p_s } void RendererStorageRD::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); ERR_FAIL_COND(p_data.size() == 0); @@ -2787,7 +2787,7 @@ void RendererStorageRD::mesh_surface_update_skin_region(RID p_mesh, int p_surfac } void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count); mesh->surfaces[p_surface]->material = p_material; @@ -2797,7 +2797,7 @@ void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID } RID RendererStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, RID()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RID()); @@ -2805,7 +2805,7 @@ RID RendererStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) cons } RS::SurfaceData RendererStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, RS::SurfaceData()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData()); @@ -2845,32 +2845,32 @@ RS::SurfaceData RendererStorageRD::mesh_get_surface(RID p_mesh, int p_surface) c } int RendererStorageRD::mesh_get_surface_count(RID p_mesh) const { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, 0); return mesh->surface_count; } void RendererStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; } AABB RendererStorageRD::mesh_get_custom_aabb(RID p_mesh) const { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, AABB()); return mesh->custom_aabb; } AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, AABB()); if (mesh->custom_aabb != AABB()) { return mesh->custom_aabb; } - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); if (!skeleton || skeleton->size == 0) { return mesh->aabb; @@ -2968,16 +2968,16 @@ AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { } void RendererStorageRD::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); - Mesh *shadow_mesh = mesh_owner.getornull(mesh->shadow_mesh); + Mesh *shadow_mesh = mesh_owner.get_or_null(mesh->shadow_mesh); if (shadow_mesh) { shadow_mesh->shadow_owners.erase(mesh); } mesh->shadow_mesh = p_shadow_mesh; - shadow_mesh = mesh_owner.getornull(mesh->shadow_mesh); + shadow_mesh = mesh_owner.get_or_null(mesh->shadow_mesh); if (shadow_mesh) { shadow_mesh->shadow_owners.insert(mesh); @@ -2987,7 +2987,7 @@ void RendererStorageRD::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { } void RendererStorageRD::mesh_clear(RID p_mesh) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); for (uint32_t i = 0; i < mesh->surface_count; i++) { Mesh::Surface &s = *mesh->surfaces[i]; @@ -3041,7 +3041,7 @@ void RendererStorageRD::mesh_clear(RID p_mesh) { } bool RendererStorageRD::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, false); return mesh->blend_shape_count > 0 || (mesh->has_bone_weights && p_has_skeleton); @@ -3050,11 +3050,11 @@ bool RendererStorageRD::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) { /* MESH INSTANCE */ RID RendererStorageRD::mesh_instance_create(RID p_base) { - Mesh *mesh = mesh_owner.getornull(p_base); + Mesh *mesh = mesh_owner.get_or_null(p_base); ERR_FAIL_COND_V(!mesh, RID()); RID rid = mesh_instance_owner.make_rid(); - MeshInstance *mi = mesh_instance_owner.getornull(rid); + MeshInstance *mi = mesh_instance_owner.get_or_null(rid); mi->mesh = mesh; @@ -3069,7 +3069,7 @@ RID RendererStorageRD::mesh_instance_create(RID p_base) { return rid; } void RendererStorageRD::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) { - MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance); + MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance); if (mi->skeleton == p_skeleton) { return; } @@ -3079,7 +3079,7 @@ void RendererStorageRD::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_sk } void RendererStorageRD::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) { - MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance); + MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance); ERR_FAIL_COND(!mi); ERR_FAIL_INDEX(p_shape, (int)mi->blend_weights.size()); mi->blend_weights[p_shape] = p_weight; @@ -3151,7 +3151,7 @@ void RendererStorageRD::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, } void RendererStorageRD::mesh_instance_check_for_update(RID p_mesh_instance) { - MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance); + MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance); bool needs_update = mi->dirty; @@ -3165,7 +3165,7 @@ void RendererStorageRD::mesh_instance_check_for_update(RID p_mesh_instance) { } if (!needs_update && mi->skeleton.is_valid()) { - Skeleton *sk = skeleton_owner.getornull(mi->skeleton); + Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton); if (sk && sk->version != mi->skeleton_version) { needs_update = true; } @@ -3196,7 +3196,7 @@ void RendererStorageRD::update_mesh_instances() { while (dirty_mesh_instance_arrays.first()) { MeshInstance *mi = dirty_mesh_instance_arrays.first()->self(); - Skeleton *sk = skeleton_owner.getornull(mi->skeleton); + Skeleton *sk = skeleton_owner.get_or_null(mi->skeleton); for (uint32_t i = 0; i < mi->surfaces.size(); i++) { if (mi->surfaces[i].uniform_set == RID() || mi->mesh->surfaces[i]->uniform_set == RID()) { @@ -3443,7 +3443,7 @@ void RendererStorageRD::multimesh_initialize(RID p_rid) { } void RendererStorageRD::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); if (multimesh->instances == p_instances && multimesh->xform_format == p_transform_format && multimesh->uses_colors == p_use_colors && multimesh->uses_custom_data == p_use_custom_data) { @@ -3486,13 +3486,13 @@ void RendererStorageRD::multimesh_allocate_data(RID p_multimesh, int p_instances } int RendererStorageRD::multimesh_get_instance_count(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, 0); return multimesh->instances; } void RendererStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); if (multimesh->mesh == p_mesh) { return; @@ -3638,7 +3638,7 @@ void RendererStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const fl } void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D); @@ -3668,7 +3668,7 @@ void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_ } void RendererStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); ERR_FAIL_COND(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D); @@ -3694,7 +3694,7 @@ void RendererStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int } void RendererStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); ERR_FAIL_COND(!multimesh->uses_colors); @@ -3716,7 +3716,7 @@ void RendererStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_inde } void RendererStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); ERR_FAIL_COND(!multimesh->uses_custom_data); @@ -3738,14 +3738,14 @@ void RendererStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int } RID RendererStorageRD::multimesh_get_mesh(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, RID()); return multimesh->mesh; } Transform3D RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform3D()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform3D()); ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform3D()); @@ -3776,7 +3776,7 @@ Transform3D RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, } Transform2D RendererStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform2D()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D()); ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_2D, Transform2D()); @@ -3801,7 +3801,7 @@ Transform2D RendererStorageRD::multimesh_instance_get_transform_2d(RID p_multime } Color RendererStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); ERR_FAIL_COND_V(!multimesh->uses_colors, Color()); @@ -3824,7 +3824,7 @@ Color RendererStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_ind } Color RendererStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); ERR_FAIL_COND_V(!multimesh->uses_custom_data, Color()); @@ -3847,7 +3847,7 @@ Color RendererStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int } void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_buffer) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache)); @@ -3880,7 +3880,7 @@ void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float } Vector<float> RendererStorageRD::multimesh_get_buffer(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, Vector<float>()); if (multimesh->buffer.is_null()) { return Vector<float>(); @@ -3903,7 +3903,7 @@ Vector<float> RendererStorageRD::multimesh_get_buffer(RID p_multimesh) const { } void RendererStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances); if (multimesh->visible_instances == p_visible) { @@ -3921,13 +3921,13 @@ void RendererStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_v } int RendererStorageRD::multimesh_get_visible_instances(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, 0); return multimesh->visible_instances; } AABB RendererStorageRD::multimesh_get_aabb(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); ERR_FAIL_COND_V(!multimesh, AABB()); if (multimesh->aabb_dirty) { const_cast<RendererStorageRD *>(this)->_update_dirty_multimeshes(); @@ -3998,7 +3998,7 @@ void RendererStorageRD::particles_initialize(RID p_rid) { } void RendererStorageRD::particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); if (particles->mode == p_mode) { return; @@ -4010,7 +4010,7 @@ void RendererStorageRD::particles_set_mode(RID p_particles, RS::ParticlesMode p_ } void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->emitting = p_emitting; @@ -4018,7 +4018,7 @@ void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting) bool RendererStorageRD::particles_get_emitting(RID p_particles) { ERR_FAIL_COND_V_MSG(RSG::threaded, false, "This function should never be used with threaded rendering, as it stalls the renderer."); - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, false); return particles->emitting; @@ -4073,7 +4073,7 @@ void RendererStorageRD::_particles_free_data(Particles *particles) { } void RendererStorageRD::particles_set_amount(RID p_particles, int p_amount) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); if (particles->amount == p_amount) { @@ -4093,48 +4093,48 @@ void RendererStorageRD::particles_set_amount(RID p_particles, int p_amount) { } void RendererStorageRD::particles_set_lifetime(RID p_particles, double p_lifetime) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->lifetime = p_lifetime; } void RendererStorageRD::particles_set_one_shot(RID p_particles, bool p_one_shot) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->one_shot = p_one_shot; } void RendererStorageRD::particles_set_pre_process_time(RID p_particles, double p_time) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->pre_process_time = p_time; } void RendererStorageRD::particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->explosiveness = p_ratio; } void RendererStorageRD::particles_set_randomness_ratio(RID p_particles, real_t p_ratio) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->randomness = p_ratio; } void RendererStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->custom_aabb = p_aabb; particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::particles_set_speed_scale(RID p_particles, double p_scale) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->speed_scale = p_scale; } void RendererStorageRD::particles_set_use_local_coordinates(RID p_particles, bool p_enable) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->use_local_coords = p_enable; @@ -4142,7 +4142,7 @@ void RendererStorageRD::particles_set_use_local_coordinates(RID p_particles, boo } void RendererStorageRD::particles_set_fixed_fps(RID p_particles, int p_fps) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->fixed_fps = p_fps; @@ -4158,21 +4158,21 @@ void RendererStorageRD::particles_set_fixed_fps(RID p_particles, int p_fps) { } void RendererStorageRD::particles_set_interpolate(RID p_particles, bool p_enable) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->interpolate = p_enable; } void RendererStorageRD::particles_set_fractional_delta(RID p_particles, bool p_enable) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->fractional_delta = p_enable; } void RendererStorageRD::particles_set_trails(RID p_particles, bool p_enable, double p_length) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_COND(p_length < 0.1); p_length = MIN(10.0, p_length); @@ -4191,7 +4191,7 @@ void RendererStorageRD::particles_set_trails(RID p_particles, bool p_enable, dou } void RendererStorageRD::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); if (particles->trail_bind_pose_buffer.is_valid() && particles->trail_bind_poses.size() != p_bind_poses.size()) { _particles_free_data(particles); @@ -4208,49 +4208,49 @@ void RendererStorageRD::particles_set_trail_bind_poses(RID p_particles, const Ve } void RendererStorageRD::particles_set_collision_base_size(RID p_particles, real_t p_size) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->collision_base_size = p_size; } void RendererStorageRD::particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->transform_align = p_transform_align; } void RendererStorageRD::particles_set_process_material(RID p_particles, RID p_material) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->process_material = p_material; } void RendererStorageRD::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->draw_order = p_order; } void RendererStorageRD::particles_set_draw_passes(RID p_particles, int p_passes) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->draw_passes.resize(p_passes); } void RendererStorageRD::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_INDEX(p_pass, particles->draw_passes.size()); particles->draw_passes.write[p_pass] = p_mesh; } void RendererStorageRD::particles_restart(RID p_particles) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->restart_request = true; @@ -4274,7 +4274,7 @@ void RendererStorageRD::_particles_allocate_emission_buffer(Particles *particles } void RendererStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_COND(p_particles == p_subemitter_particles); @@ -4287,7 +4287,7 @@ void RendererStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitt } void RendererStorageRD::particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); ERR_FAIL_COND(particles->amount == 0); @@ -4330,7 +4330,7 @@ void RendererStorageRD::particles_emit(RID p_particles, const Transform3D &p_tra } void RendererStorageRD::particles_request_process(RID p_particles) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); if (!particles->dirty) { @@ -4345,7 +4345,7 @@ AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) { WARN_PRINT_ONCE("Calling this function with threaded rendering enabled stalls the renderer, use with care."); } - const Particles *particles = particles_owner.getornull(p_particles); + const Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, AABB()); int total_amount = particles->amount; @@ -4393,28 +4393,28 @@ AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) { } AABB RendererStorageRD::particles_get_aabb(RID p_particles) const { - const Particles *particles = particles_owner.getornull(p_particles); + const Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, AABB()); return particles->custom_aabb; } void RendererStorageRD::particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->emission_transform = p_transform; } int RendererStorageRD::particles_get_draw_passes(RID p_particles) const { - const Particles *particles = particles_owner.getornull(p_particles); + const Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, 0); return particles->draw_passes.size(); } RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { - const Particles *particles = particles_owner.getornull(p_particles); + const Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, RID()); ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID()); @@ -4422,19 +4422,19 @@ RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass) } void RendererStorageRD::particles_add_collision(RID p_particles, RID p_particles_collision_instance) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->collisions.insert(p_particles_collision_instance); } void RendererStorageRD::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->collisions.erase(p_particles_collision_instance); } void RendererStorageRD::particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); particles->has_sdf_collision = p_enable; particles->sdf_collision_transform = p_xform; @@ -4476,7 +4476,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - Particles *sub_emitter = particles_owner.getornull(p_particles->sub_emitter); + Particles *sub_emitter = particles_owner.get_or_null(p_particles->sub_emitter); if (sub_emitter) { if (sub_emitter->emission_buffer == nullptr) { //no emission buffer, allocate emission buffer _particles_allocate_emission_buffer(sub_emitter); @@ -4593,11 +4593,11 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt uint32_t collision_3d_textures_used = 0; for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) { - ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(E->get()); + ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(E->get()); if (!pci || !pci->active) { continue; } - ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision); + ParticlesCollision *pc = particles_collision_owner.get_or_null(pci->collision); ERR_CONTINUE(!pc); Transform3D to_collider = pci->transform; @@ -4745,7 +4745,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt for (uint32_t i = 0; i < ParticlesFrameParams::MAX_3D_TEXTURES; i++) { RID rd_tex; if (i < collision_3d_textures_used) { - Texture *t = texture_owner.getornull(collision_3d_textures[i]); + Texture *t = texture_owner.get_or_null(collision_3d_textures[i]); if (t && t->type == Texture::TYPE_3D) { rd_tex = t->rd_texture; } @@ -4790,7 +4790,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt p_particles->force_sub_emit = false; //reset - Particles *sub_emitter = particles_owner.getornull(p_particles->sub_emitter); + Particles *sub_emitter = particles_owner.get_or_null(p_particles->sub_emitter); if (sub_emitter && sub_emitter->emission_storage_buffer.is_valid()) { // print_line("updating subemitter buffer"); @@ -4870,7 +4870,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt } void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND(!particles); if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) { @@ -5228,7 +5228,7 @@ void RendererStorageRD::update_particles() { bool RendererStorageRD::particles_is_inactive(RID p_particles) const { ERR_FAIL_COND_V_MSG(RSG::threaded, false, "This function should never be used with threaded rendering, as it stalls the renderer."); - const Particles *particles = particles_owner.getornull(p_particles); + const Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, false); return !particles->emitting && particles->inactive; } @@ -5298,36 +5298,36 @@ void RendererStorageRD::ParticlesShaderData::set_default_texture_param(const Str void RendererStorageRD::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } - if (E->get().texture_order >= 0) { - order[E->get().texture_order + 100000] = E->key(); + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; } else { - order[E->get().order] = E->key(); + order[E.value.order] = E.key; } } - for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); - pi.name = E->get(); + for (const KeyValue<int, StringName> &E : order) { + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; p_param_list->push_back(pi); } } void RendererStorageRD::ParticlesShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } RendererStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E->get()); - p.info.name = E->key(); //supply name - p.index = E->get().instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.hint); p_param_list->push_back(p); } } @@ -5406,7 +5406,7 @@ void RendererStorageRD::particles_collision_initialize(RID p_rid) { } RID RendererStorageRD::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, RID()); ERR_FAIL_COND_V(particles_collision->type != RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE, RID()); @@ -5441,7 +5441,7 @@ RID RendererStorageRD::particles_collision_get_heightfield_framebuffer(RID p_par } void RendererStorageRD::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); if (p_type == particles_collision->type) { @@ -5457,13 +5457,13 @@ void RendererStorageRD::particles_collision_set_collision_type(RID p_particles_c } void RendererStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->cull_mask = p_cull_mask; } void RendererStorageRD::particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->radius = p_radius; @@ -5471,7 +5471,7 @@ void RendererStorageRD::particles_collision_set_sphere_radius(RID p_particles_co } void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->extents = p_extents; @@ -5479,41 +5479,41 @@ void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_coll } void RendererStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->attractor_strength = p_strength; } void RendererStorageRD::particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->attractor_directionality = p_directionality; } void RendererStorageRD::particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->attractor_attenuation = p_curve; } void RendererStorageRD::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->field_texture = p_texture; } void RendererStorageRD::particles_collision_height_field_update(RID p_particles_collision) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND(!particles_collision); ERR_FAIL_INDEX(p_resolution, RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX); @@ -5530,7 +5530,7 @@ void RendererStorageRD::particles_collision_set_height_field_resolution(RID p_pa } AABB RendererStorageRD::particles_collision_get_aabb(RID p_particles_collision) const { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, AABB()); switch (particles_collision->type) { @@ -5553,13 +5553,13 @@ AABB RendererStorageRD::particles_collision_get_aabb(RID p_particles_collision) } Vector3 RendererStorageRD::particles_collision_get_extents(RID p_particles_collision) const { - const ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + const ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, Vector3()); return particles_collision->extents; } bool RendererStorageRD::particles_collision_is_heightfield(RID p_particles_collision) const { - const ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision); + const ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision); ERR_FAIL_COND_V(!particles_collision, false); return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE; } @@ -5570,12 +5570,12 @@ RID RendererStorageRD::particles_collision_instance_create(RID p_collision) { return particles_collision_instance_owner.make_rid(pci); } void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) { - ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance); + ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(p_collision_instance); ERR_FAIL_COND(!pci); pci->transform = p_transform; } void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) { - ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance); + ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(p_collision_instance); ERR_FAIL_COND(!pci); pci->active = p_active; } @@ -5589,25 +5589,25 @@ void RendererStorageRD::visibility_notifier_initialize(RID p_notifier) { visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier()); } void RendererStorageRD::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) { - VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier); + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); ERR_FAIL_COND(!vn); vn->aabb = p_aabb; vn->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) { - VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier); + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); ERR_FAIL_COND(!vn); vn->enter_callback = p_enter_callbable; vn->exit_callback = p_exit_callable; } AABB RendererStorageRD::visibility_notifier_get_aabb(RID p_notifier) const { - const VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier); + const VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); ERR_FAIL_COND_V(!vn, AABB()); return vn->aabb; } void RendererStorageRD::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) { - VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier); + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier); ERR_FAIL_COND(!vn); if (p_enter) { @@ -5651,7 +5651,7 @@ void RendererStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { } void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_COND(p_bones < 0); @@ -5694,14 +5694,14 @@ void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool } int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND_V(!skeleton, 0); return skeleton->size; } void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_INDEX(p_bone, skeleton->size); @@ -5726,7 +5726,7 @@ void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, } Transform3D RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform3D()); ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform3D()); @@ -5753,7 +5753,7 @@ Transform3D RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p } void RendererStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_INDEX(p_bone, skeleton->size); @@ -5774,7 +5774,7 @@ void RendererStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bon } Transform2D RendererStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform2D()); ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform2D()); @@ -5794,7 +5794,7 @@ Transform2D RendererStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, in } void RendererStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND(!skeleton->use_2d); @@ -5873,14 +5873,14 @@ void RendererStorageRD::spot_light_initialize(RID p_light) { } void RendererStorageRD::light_set_color(RID p_light, const Color &p_color) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->color = p_color; } void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX); @@ -5915,7 +5915,7 @@ void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, flo } void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->shadow = p_enabled; @@ -5924,13 +5924,13 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) { } void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->shadow_color = p_color; } void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); if (light->projector == p_texture) { @@ -5952,14 +5952,14 @@ void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) { } void RendererStorageRD::light_set_negative(RID p_light, bool p_enable) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->negative = p_enable; } void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->cull_mask = p_mask; @@ -5969,7 +5969,7 @@ void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { } void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->reverse_cull = p_enabled; @@ -5979,7 +5979,7 @@ void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_ena } void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->bake_mode = p_bake_mode; @@ -5989,7 +5989,7 @@ void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bak } void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->max_sdfgi_cascade = p_cascade; @@ -5999,7 +5999,7 @@ void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_casc } void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->omni_shadow_mode = p_mode; @@ -6009,14 +6009,14 @@ void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniSha } RS::LightOmniShadowMode RendererStorageRD::light_omni_get_shadow_mode(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE); return light->omni_shadow_mode; } void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->directional_shadow_mode = p_mode; @@ -6025,7 +6025,7 @@ void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Light } void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->directional_blend_splits = p_enable; @@ -6034,56 +6034,56 @@ void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_e } bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, false); return light->directional_blend_splits; } void RendererStorageRD::light_directional_set_sky_only(RID p_light, bool p_sky_only) { - Light *light = light_owner.getornull(p_light); + Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); light->directional_sky_only = p_sky_only; } bool RendererStorageRD::light_directional_is_sky_only(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, false); return light->directional_sky_only; } RS::LightDirectionalShadowMode RendererStorageRD::light_directional_get_shadow_mode(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL); return light->directional_shadow_mode; } uint32_t RendererStorageRD::light_get_max_sdfgi_cascade(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, 0); return light->max_sdfgi_cascade; } RS::LightBakeMode RendererStorageRD::light_get_bake_mode(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_BAKE_DISABLED); return light->bake_mode; } uint64_t RendererStorageRD::light_get_version(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, 0); return light->version; } AABB RendererStorageRD::light_get_aabb(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, AABB()); switch (light->type) { @@ -6114,7 +6114,7 @@ void RendererStorageRD::reflection_probe_initialize(RID p_reflection_probe) { } void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->update_mode = p_mode; @@ -6122,35 +6122,35 @@ void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Reflec } void RendererStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->intensity = p_intensity; } void RendererStorageRD::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->ambient_mode = p_mode; } void RendererStorageRD::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->ambient_color = p_color; } void RendererStorageRD::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->ambient_color_energy = p_energy; } void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->max_distance = p_distance; @@ -6159,7 +6159,7 @@ void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_d } void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); if (reflection_probe->extents == p_extents) { @@ -6170,7 +6170,7 @@ void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 } void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->origin_offset = p_offset; @@ -6178,7 +6178,7 @@ void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Ve } void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->interior = p_enable; @@ -6186,14 +6186,14 @@ void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_ena } void RendererStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->box_projection = p_enable; } void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->enable_shadows = p_enable; @@ -6201,7 +6201,7 @@ void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_ } void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->cull_mask = p_layers; @@ -6209,7 +6209,7 @@ void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_l } void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); ERR_FAIL_COND(p_resolution < 32); @@ -6217,7 +6217,7 @@ void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resol } void RendererStorageRD::reflection_probe_set_lod_threshold(RID p_probe, float p_ratio) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->lod_threshold = p_ratio; @@ -6226,7 +6226,7 @@ void RendererStorageRD::reflection_probe_set_lod_threshold(RID p_probe, float p_ } AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, AABB()); AABB aabb; @@ -6237,96 +6237,96 @@ AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const { } RS::ReflectionProbeUpdateMode RendererStorageRD::reflection_probe_get_update_mode(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS); return reflection_probe->update_mode; } uint32_t RendererStorageRD::reflection_probe_get_cull_mask(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->cull_mask; } Vector3 RendererStorageRD::reflection_probe_get_extents(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); return reflection_probe->extents; } Vector3 RendererStorageRD::reflection_probe_get_origin_offset(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); return reflection_probe->origin_offset; } bool RendererStorageRD::reflection_probe_renders_shadows(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->enable_shadows; } float RendererStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->max_distance; } float RendererStorageRD::reflection_probe_get_lod_threshold(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->lod_threshold; } int RendererStorageRD::reflection_probe_get_resolution(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->resolution; } float RendererStorageRD::reflection_probe_get_intensity(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->intensity; } bool RendererStorageRD::reflection_probe_is_interior(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->interior; } bool RendererStorageRD::reflection_probe_is_box_projection(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->box_projection; } RS::ReflectionProbeAmbientMode RendererStorageRD::reflection_probe_get_ambient_mode(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_AMBIENT_DISABLED); return reflection_probe->ambient_mode; } Color RendererStorageRD::reflection_probe_get_ambient_color(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, Color()); return reflection_probe->ambient_color; } float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); + const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->ambient_color_energy; @@ -6340,14 +6340,14 @@ void RendererStorageRD::decal_initialize(RID p_decal) { } void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->extents = p_extents; decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX); @@ -6371,32 +6371,32 @@ void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, } void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->emission_energy = p_energy; } void RendererStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->albedo_mix = p_mix; } void RendererStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->modulate = p_modulate; } void RendererStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->cull_mask = p_layers; decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB); } void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->distance_fade = p_enabled; decal->distance_fade_begin = p_begin; @@ -6404,20 +6404,20 @@ void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, flo } void RendererStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->upper_fade = p_above; decal->lower_fade = p_below; } void RendererStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->normal_fade = p_fade; } AABB RendererStorageRD::decal_get_aabb(RID p_decal) const { - Decal *decal = decal_owner.getornull(p_decal); + Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND_V(!decal, AABB()); return AABB(-decal->extents, decal->extents * 2.0); @@ -6431,7 +6431,7 @@ void RendererStorageRD::voxel_gi_initialize(RID p_voxel_gi) { } void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); if (voxel_gi->octree_buffer.is_valid()) { @@ -6556,20 +6556,20 @@ void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D } AABB RendererStorageRD::voxel_gi_get_bounds(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, AABB()); return voxel_gi->bounds; } Vector3i RendererStorageRD::voxel_gi_get_octree_size(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, Vector3i()); return voxel_gi->octree_size; } Vector<uint8_t> RendererStorageRD::voxel_gi_get_octree_cells(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); if (voxel_gi->octree_buffer.is_valid()) { @@ -6579,7 +6579,7 @@ Vector<uint8_t> RendererStorageRD::voxel_gi_get_octree_cells(RID p_voxel_gi) con } Vector<uint8_t> RendererStorageRD::voxel_gi_get_data_cells(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); if (voxel_gi->data_buffer.is_valid()) { @@ -6589,7 +6589,7 @@ Vector<uint8_t> RendererStorageRD::voxel_gi_get_data_cells(RID p_voxel_gi) const } Vector<uint8_t> RendererStorageRD::voxel_gi_get_distance_field(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>()); if (voxel_gi->data_buffer.is_valid()) { @@ -6599,21 +6599,21 @@ Vector<uint8_t> RendererStorageRD::voxel_gi_get_distance_field(RID p_voxel_gi) c } Vector<int> RendererStorageRD::voxel_gi_get_level_counts(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, Vector<int>()); return voxel_gi->level_counts; } Transform3D RendererStorageRD::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, Transform3D()); return voxel_gi->to_cell_xform; } void RendererStorageRD::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->dynamic_range = p_range; @@ -6621,14 +6621,14 @@ void RendererStorageRD::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range } float RendererStorageRD::voxel_gi_get_dynamic_range(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->dynamic_range; } void RendererStorageRD::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->propagation = p_range; @@ -6636,72 +6636,72 @@ void RendererStorageRD::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) } float RendererStorageRD::voxel_gi_get_propagation(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->propagation; } void RendererStorageRD::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->energy = p_energy; } float RendererStorageRD::voxel_gi_get_energy(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->energy; } void RendererStorageRD::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->bias = p_bias; } float RendererStorageRD::voxel_gi_get_bias(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->bias; } void RendererStorageRD::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->normal_bias = p_normal_bias; } float RendererStorageRD::voxel_gi_get_normal_bias(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->normal_bias; } void RendererStorageRD::voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->anisotropy_strength = p_strength; } float RendererStorageRD::voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->anisotropy_strength; } void RendererStorageRD::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->interior = p_enable; } void RendererStorageRD::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); voxel_gi->use_two_bounces = p_enable; @@ -6709,43 +6709,43 @@ void RendererStorageRD::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enab } bool RendererStorageRD::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, false); return voxel_gi->use_two_bounces; } bool RendererStorageRD::voxel_gi_is_interior(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->interior; } uint32_t RendererStorageRD::voxel_gi_get_version(RID p_voxel_gi) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->version; } uint32_t RendererStorageRD::voxel_gi_get_data_version(RID p_voxel_gi) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, 0); return voxel_gi->data_version; } RID RendererStorageRD::voxel_gi_get_octree_buffer(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, RID()); return voxel_gi->octree_buffer; } RID RendererStorageRD::voxel_gi_get_data_buffer(RID p_voxel_gi) const { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, RID()); return voxel_gi->data_buffer; } RID RendererStorageRD::voxel_gi_get_sdf_texture(RID p_voxel_gi) { - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND_V(!voxel_gi, RID()); return voxel_gi->sdf_texture; @@ -6762,20 +6762,20 @@ void RendererStorageRD::lightmap_initialize(RID p_lightmap) { } void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!lm); lightmap_array_version++; //erase lightmap users if (lm->light_texture.is_valid()) { - Texture *t = texture_owner.getornull(lm->light_texture); + Texture *t = texture_owner.get_or_null(lm->light_texture); if (t) { t->lightmap_users.erase(p_lightmap); } } - Texture *t = texture_owner.getornull(p_light); + Texture *t = texture_owner.get_or_null(p_light); lm->light_texture = p_light; lm->uses_spherical_harmonics = p_uses_spherical_haromics; @@ -6810,19 +6810,19 @@ void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool } void RendererStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!lm); lm->bounds = p_bounds; } void RendererStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!lm); lm->interior = p_interior; } void RendererStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!lm); if (p_points.size()) { @@ -6838,26 +6838,26 @@ void RendererStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const Pa } PackedVector3Array RendererStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND_V(!lm, PackedVector3Array()); return lm->points; } PackedColorArray RendererStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND_V(!lm, PackedColorArray()); return lm->point_sh; } PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND_V(!lm, PackedInt32Array()); return lm->tetrahedra; } PackedInt32Array RendererStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND_V(!lm, PackedInt32Array()); return lm->bsp_tree; } @@ -6867,7 +6867,7 @@ void RendererStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) { } void RendererStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { - Lightmap *lm = lightmap_owner.getornull(p_lightmap); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!lm); for (int i = 0; i < 9; i++) { @@ -6917,13 +6917,13 @@ void RendererStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_p } bool RendererStorageRD::lightmap_is_interior(RID p_lightmap) const { - const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND_V(!lm, false); return lm->interior; } AABB RendererStorageRD::lightmap_get_aabb(RID p_lightmap) const { - const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND_V(!lm, AABB()); return lm->bounds; } @@ -6963,7 +6963,7 @@ void RendererStorageRD::_update_render_target(RenderTarget *rt) { //create a placeholder until updated rt->texture = texture_allocate(); texture_2d_placeholder_initialize(rt->texture); - Texture *tex = texture_owner.getornull(rt->texture); + Texture *tex = texture_owner.get_or_null(rt->texture); tex->is_render_target = true; } @@ -7010,7 +7010,7 @@ void RendererStorageRD::_update_render_target(RenderTarget *rt) { { //update texture - Texture *tex = texture_owner.getornull(rt->texture); + Texture *tex = texture_owner.get_or_null(rt->texture); //free existing textures if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) { @@ -7117,7 +7117,7 @@ void RendererStorageRD::render_target_set_position(RID p_render_target, int p_x, } void RendererStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); if (rt->size.x != p_width || rt->size.y != p_height || rt->view_count != p_view_count) { rt->size.x = p_width; @@ -7128,7 +7128,7 @@ void RendererStorageRD::render_target_set_size(RID p_render_target, int p_width, } RID RendererStorageRD::render_target_get_texture(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->texture; @@ -7138,53 +7138,53 @@ void RendererStorageRD::render_target_set_external_texture(RID p_render_target, } void RendererStorageRD::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->flags[p_flag] = p_value; _update_render_target(rt); } bool RendererStorageRD::render_target_was_used(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->was_used; } void RendererStorageRD::render_target_set_as_unused(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->was_used = false; } Size2 RendererStorageRD::render_target_get_size(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, Size2()); return rt->size; } RID RendererStorageRD::render_target_get_rd_framebuffer(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->framebuffer; } RID RendererStorageRD::render_target_get_rd_texture(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->color; } RID RendererStorageRD::render_target_get_rd_backbuffer(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->backbuffer; } RID RendererStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); if (!rt->backbuffer.is_valid()) { @@ -7195,32 +7195,32 @@ RID RendererStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_ } void RendererStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = true; rt->clear_color = p_clear_color; } bool RendererStorageRD::render_target_is_clear_requested(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->clear_requested; } Color RendererStorageRD::render_target_get_clear_request_color(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, Color()); return rt->clear_color; } void RendererStorageRD::render_target_disable_clear_request(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = false; } void RendererStorageRD::render_target_do_clear_request(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); if (!rt->clear_requested) { return; @@ -7233,7 +7233,7 @@ void RendererStorageRD::render_target_do_clear_request(RID p_render_target) { } void RendererStorageRD::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) { return; @@ -7275,28 +7275,28 @@ Rect2i RendererStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) co } Rect2i RendererStorageRD::render_target_get_sdf_rect(RID p_render_target) const { - const RenderTarget *rt = render_target_owner.getornull(p_render_target); + const RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, Rect2i()); return _render_target_get_sdf_rect(rt); } void RendererStorageRD::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->sdf_enabled = p_enabled; } bool RendererStorageRD::render_target_is_sdf_enabled(RID p_render_target) const { - const RenderTarget *rt = render_target_owner.getornull(p_render_target); + const RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->sdf_enabled; } RID RendererStorageRD::render_target_get_sdf_texture(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); if (rt->sdf_buffer_read.is_null()) { // no texture, create a dummy one for the 2D uniform set @@ -7431,7 +7431,7 @@ void RendererStorageRD::_render_target_clear_sdf(RenderTarget *rt) { } RID RendererStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); if (rt->sdf_buffer_write_fb.is_null()) { @@ -7441,7 +7441,7 @@ RID RendererStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) { return rt->sdf_buffer_write_fb; } void RendererStorageRD::render_target_sdf_process(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_null()); @@ -7516,7 +7516,7 @@ void RendererStorageRD::render_target_sdf_process(RID p_render_target) { } void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); if (!rt->backbuffer.is_valid()) { _create_render_target_backbuffer(rt); @@ -7556,7 +7556,7 @@ void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, c } void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); if (!rt->backbuffer.is_valid()) { _create_render_target_backbuffer(rt); @@ -7577,7 +7577,7 @@ void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, con } void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); if (!rt->backbuffer.is_valid()) { _create_render_target_backbuffer(rt); @@ -7609,66 +7609,66 @@ void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_targe } RID RendererStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->framebuffer_uniform_set; } RID RendererStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->backbuffer_uniform_set; } void RendererStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->framebuffer_uniform_set = p_uniform_set; } void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); rt->backbuffer_uniform_set = p_uniform_set; } void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) { if (mesh_owner.owns(p_base)) { - Mesh *mesh = mesh_owner.getornull(p_base); + Mesh *mesh = mesh_owner.get_or_null(p_base); p_instance->update_dependency(&mesh->dependency); } else if (multimesh_owner.owns(p_base)) { - MultiMesh *multimesh = multimesh_owner.getornull(p_base); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_base); p_instance->update_dependency(&multimesh->dependency); if (multimesh->mesh.is_valid()) { base_update_dependency(multimesh->mesh, p_instance); } } else if (reflection_probe_owner.owns(p_base)) { - ReflectionProbe *rp = reflection_probe_owner.getornull(p_base); + ReflectionProbe *rp = reflection_probe_owner.get_or_null(p_base); p_instance->update_dependency(&rp->dependency); } else if (decal_owner.owns(p_base)) { - Decal *decal = decal_owner.getornull(p_base); + Decal *decal = decal_owner.get_or_null(p_base); p_instance->update_dependency(&decal->dependency); } else if (voxel_gi_owner.owns(p_base)) { - VoxelGI *gip = voxel_gi_owner.getornull(p_base); + VoxelGI *gip = voxel_gi_owner.get_or_null(p_base); p_instance->update_dependency(&gip->dependency); } else if (lightmap_owner.owns(p_base)) { - Lightmap *lm = lightmap_owner.getornull(p_base); + Lightmap *lm = lightmap_owner.get_or_null(p_base); p_instance->update_dependency(&lm->dependency); } else if (light_owner.owns(p_base)) { - Light *l = light_owner.getornull(p_base); + Light *l = light_owner.get_or_null(p_base); p_instance->update_dependency(&l->dependency); } else if (particles_owner.owns(p_base)) { - Particles *p = particles_owner.getornull(p_base); + Particles *p = particles_owner.get_or_null(p_base); p_instance->update_dependency(&p->dependency); } else if (particles_collision_owner.owns(p_base)) { - ParticlesCollision *pc = particles_collision_owner.getornull(p_base); + ParticlesCollision *pc = particles_collision_owner.get_or_null(p_base); p_instance->update_dependency(&pc->dependency); } else if (visibility_notifier_owner.owns(p_base)) { - VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_base); + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_base); p_instance->update_dependency(&vn->dependency); } } void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND(!skeleton); p_instance->update_dependency(&skeleton->dependency); @@ -7774,7 +7774,7 @@ void RendererStorageRD::_update_decal_atlas() { while ((K = decal_atlas.textures.next(K))) { DecalAtlas::SortItem &si = itemsv.write[idx]; - Texture *src_tex = texture_owner.getornull(*K); + Texture *src_tex = texture_owner.get_or_null(*K); si.size.width = (src_tex->width / border) + 1; si.size.height = (src_tex->height / border) + 1; @@ -7923,7 +7923,7 @@ void RendererStorageRD::_update_decal_atlas() { const RID *K = nullptr; while ((K = decal_atlas.textures.next(K))) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); - Texture *src_tex = texture_owner.getornull(*K); + Texture *src_tex = texture_owner.get_or_null(*K); effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); } @@ -8339,7 +8339,7 @@ void RendererStorageRD::global_variable_set(const StringName &p_name, const Vari } else { //texture for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) { - Material *material = material_owner.getornull(E->get()); + Material *material = material_owner.get_or_null(E->get()); ERR_CONTINUE(!material); _material_queue_update(material, false, true); } @@ -8370,7 +8370,7 @@ void RendererStorageRD::global_variable_set_override(const StringName &p_name, c } else { //texture for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) { - Material *material = material_owner.getornull(E->get()); + Material *material = material_owner.get_or_null(E->get()); ERR_CONTINUE(!material); _material_queue_update(material, false, true); } @@ -8581,7 +8581,7 @@ void RendererStorageRD::_update_global_variables() { // only happens in the case of a buffer variable added or removed, // so not often. for (const RID &E : global_variables.materials_using_buffer) { - Material *material = material_owner.getornull(E); + Material *material = material_owner.get_or_null(E); ERR_CONTINUE(!material); //wtf _material_queue_update(material, true, false); @@ -8594,7 +8594,7 @@ void RendererStorageRD::_update_global_variables() { // only happens in the case of a buffer variable added or removed, // so not often. for (const RID &E : global_variables.materials_using_texture) { - Material *material = material_owner.getornull(E); + Material *material = material_owner.get_or_null(E); ERR_CONTINUE(!material); //wtf _material_queue_update(material, false, true); @@ -8639,7 +8639,7 @@ bool RendererStorageRD::has_os_feature(const String &p_feature) const { bool RendererStorageRD::free(RID p_rid) { if (texture_owner.owns(p_rid)) { - Texture *t = texture_owner.getornull(p_rid); + Texture *t = texture_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!t, false); ERR_FAIL_COND_V(t->is_render_target, false); @@ -8653,7 +8653,7 @@ bool RendererStorageRD::free(RID p_rid) { } if (t->is_proxy && t->proxy_to.is_valid()) { - Texture *proxy_to = texture_owner.getornull(t->proxy_to); + Texture *proxy_to = texture_owner.get_or_null(t->proxy_to); if (proxy_to) { proxy_to->proxies.erase(p_rid); } @@ -8665,7 +8665,7 @@ bool RendererStorageRD::free(RID p_rid) { } for (int i = 0; i < t->proxies.size(); i++) { - Texture *p = texture_owner.getornull(t->proxies[i]); + Texture *p = texture_owner.get_or_null(t->proxies[i]); ERR_CONTINUE(!p); p->proxy_to = RID(); p->rd_texture = RID(); @@ -8680,7 +8680,7 @@ bool RendererStorageRD::free(RID p_rid) { } else if (canvas_texture_owner.owns(p_rid)) { canvas_texture_owner.free(p_rid); } else if (shader_owner.owns(p_rid)) { - Shader *shader = shader_owner.getornull(p_rid); + Shader *shader = shader_owner.get_or_null(p_rid); //make material unreference this while (shader->owners.size()) { material_set_shader(shader->owners.front()->get()->self, RID()); @@ -8692,7 +8692,7 @@ bool RendererStorageRD::free(RID p_rid) { shader_owner.free(p_rid); } else if (material_owner.owns(p_rid)) { - Material *material = material_owner.getornull(p_rid); + Material *material = material_owner.get_or_null(p_rid); material_set_shader(p_rid, RID()); //clean up shader material->dependency.deleted_notify(p_rid); @@ -8700,7 +8700,7 @@ bool RendererStorageRD::free(RID p_rid) { } else if (mesh_owner.owns(p_rid)) { mesh_clear(p_rid); mesh_set_shadow_mesh(p_rid, RID()); - Mesh *mesh = mesh_owner.getornull(p_rid); + Mesh *mesh = mesh_owner.get_or_null(p_rid); mesh->dependency.deleted_notify(p_rid); if (mesh->instances.size()) { ERR_PRINT("deleting mesh with active instances"); @@ -8714,7 +8714,7 @@ bool RendererStorageRD::free(RID p_rid) { } mesh_owner.free(p_rid); } else if (mesh_instance_owner.owns(p_rid)) { - MeshInstance *mi = mesh_instance_owner.getornull(p_rid); + MeshInstance *mi = mesh_instance_owner.get_or_null(p_rid); _mesh_instance_clear(mi); mi->mesh->instances.erase(mi->I); mi->I = nullptr; @@ -8724,21 +8724,21 @@ bool RendererStorageRD::free(RID p_rid) { } else if (multimesh_owner.owns(p_rid)) { _update_dirty_multimeshes(); multimesh_allocate_data(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D); - MultiMesh *multimesh = multimesh_owner.getornull(p_rid); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_rid); multimesh->dependency.deleted_notify(p_rid); multimesh_owner.free(p_rid); } else if (skeleton_owner.owns(p_rid)) { _update_dirty_skeletons(); skeleton_allocate_data(p_rid, 0); - Skeleton *skeleton = skeleton_owner.getornull(p_rid); + Skeleton *skeleton = skeleton_owner.get_or_null(p_rid); skeleton->dependency.deleted_notify(p_rid); skeleton_owner.free(p_rid); } else if (reflection_probe_owner.owns(p_rid)) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid); + ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid); reflection_probe->dependency.deleted_notify(p_rid); reflection_probe_owner.free(p_rid); } else if (decal_owner.owns(p_rid)) { - Decal *decal = decal_owner.getornull(p_rid); + Decal *decal = decal_owner.get_or_null(p_rid); for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) { if (decal->textures[i].is_valid() && texture_owner.owns(decal->textures[i])) { texture_remove_from_decal_atlas(decal->textures[i]); @@ -8748,30 +8748,30 @@ bool RendererStorageRD::free(RID p_rid) { decal_owner.free(p_rid); } else if (voxel_gi_owner.owns(p_rid)) { voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate - VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_rid); + VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid); voxel_gi->dependency.deleted_notify(p_rid); voxel_gi_owner.free(p_rid); } else if (lightmap_owner.owns(p_rid)) { lightmap_set_textures(p_rid, RID(), false); - Lightmap *lightmap = lightmap_owner.getornull(p_rid); + Lightmap *lightmap = lightmap_owner.get_or_null(p_rid); lightmap->dependency.deleted_notify(p_rid); lightmap_owner.free(p_rid); } else if (light_owner.owns(p_rid)) { light_set_projector(p_rid, RID()); //clear projector // delete the texture - Light *light = light_owner.getornull(p_rid); + Light *light = light_owner.get_or_null(p_rid); light->dependency.deleted_notify(p_rid); light_owner.free(p_rid); } else if (particles_owner.owns(p_rid)) { update_particles(); - Particles *particles = particles_owner.getornull(p_rid); + Particles *particles = particles_owner.get_or_null(p_rid); particles->dependency.deleted_notify(p_rid); _particles_free_data(particles); particles_owner.free(p_rid); } else if (particles_collision_owner.owns(p_rid)) { - ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_rid); + ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_rid); if (particles_collision->heightfield_texture.is_valid()) { RD::get_singleton()->free(particles_collision->heightfield_texture); @@ -8779,18 +8779,18 @@ bool RendererStorageRD::free(RID p_rid) { particles_collision->dependency.deleted_notify(p_rid); particles_collision_owner.free(p_rid); } else if (visibility_notifier_owner.owns(p_rid)) { - VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_rid); + VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_rid); vn->dependency.deleted_notify(p_rid); visibility_notifier_owner.free(p_rid); } else if (particles_collision_instance_owner.owns(p_rid)) { particles_collision_instance_owner.free(p_rid); } else if (render_target_owner.owns(p_rid)) { - RenderTarget *rt = render_target_owner.getornull(p_rid); + RenderTarget *rt = render_target_owner.get_or_null(p_rid); _clear_render_target(rt); if (rt->texture.is_valid()) { - Texture *tex = texture_owner.getornull(rt->texture); + Texture *tex = texture_owner.get_or_null(rt->texture); tex->is_render_target = false; free(rt->texture); } diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 4950b7d5e5..d56afcc448 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -1350,7 +1350,7 @@ public: if (p_texture.is_null()) { return RID(); } - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); if (!tex) { return RID(); @@ -1362,7 +1362,7 @@ public: if (p_texture.is_null()) { return Size2i(); } - Texture *tex = texture_owner.getornull(p_texture); + Texture *tex = texture_owner.get_or_null(p_texture); if (!tex) { return Size2i(); @@ -1430,12 +1430,12 @@ public: void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function); _FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); return material->shader_id; } _FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) { - Material *material = material_owner.getornull(p_material); + Material *material = material_owner.get_or_null(p_material); if (!material || material->shader_type != p_shader_type) { return nullptr; } else { @@ -1488,7 +1488,7 @@ public: virtual void update_mesh_instances(); _FORCE_INLINE_ const RID *mesh_get_surface_count_and_materials(RID p_mesh, uint32_t &r_surface_count) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, nullptr); r_surface_count = mesh->surface_count; if (r_surface_count == 0) { @@ -1505,7 +1505,7 @@ public: } _FORCE_INLINE_ void *mesh_get_surface(RID p_mesh, uint32_t p_surface_index) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, nullptr); ERR_FAIL_UNSIGNED_INDEX_V(p_surface_index, mesh->surface_count, nullptr); @@ -1513,7 +1513,7 @@ public: } _FORCE_INLINE_ RID mesh_get_shadow_mesh(RID p_mesh) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND_V(!mesh, RID()); return mesh->shadow_mesh; @@ -1599,7 +1599,7 @@ public: } _FORCE_INLINE_ void mesh_instance_surface_get_vertex_arrays_and_format(RID p_mesh_instance, uint32_t p_surface_index, uint32_t p_input_mask, RID &r_vertex_array_rd, RD::VertexFormatID &r_vertex_format) { - MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance); + MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance); ERR_FAIL_COND(!mi); Mesh *mesh = mi->mesh; ERR_FAIL_UNSIGNED_INDEX(p_surface_index, mesh->surface_count); @@ -1640,7 +1640,7 @@ public: } _FORCE_INLINE_ uint32_t mesh_surface_get_render_pass_index(RID p_mesh, uint32_t p_surface_index, uint64_t p_render_pass, uint32_t *r_index) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); Mesh::Surface *s = mesh->surfaces[p_surface_index]; if (s->render_pass != p_render_pass) { @@ -1653,7 +1653,7 @@ public: } _FORCE_INLINE_ uint32_t mesh_surface_get_multimesh_render_pass_index(RID p_mesh, uint32_t p_surface_index, uint64_t p_render_pass, uint32_t *r_index) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); Mesh::Surface *s = mesh->surfaces[p_surface_index]; if (s->multimesh_render_pass != p_render_pass) { @@ -1666,7 +1666,7 @@ public: } _FORCE_INLINE_ uint32_t mesh_surface_get_particles_render_pass_index(RID p_mesh, uint32_t p_surface_index, uint64_t p_render_pass, uint32_t *r_index) { - Mesh *mesh = mesh_owner.getornull(p_mesh); + Mesh *mesh = mesh_owner.get_or_null(p_mesh); Mesh::Surface *s = mesh->surfaces[p_surface_index]; if (s->particles_render_pass != p_render_pass) { @@ -1708,22 +1708,22 @@ public: AABB multimesh_get_aabb(RID p_multimesh) const; _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); return multimesh->xform_format; } _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); return multimesh->uses_colors; } _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); return multimesh->uses_custom_data; } _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); if (multimesh->visible_instances >= 0) { return multimesh->visible_instances; } @@ -1731,7 +1731,7 @@ public: } _FORCE_INLINE_ RID multimesh_get_3d_uniform_set(RID p_multimesh, RID p_shader, uint32_t p_set) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); if (!multimesh->uniform_set_3d.is_valid()) { Vector<RD::Uniform> uniforms; RD::Uniform u; @@ -1746,7 +1746,7 @@ public: } _FORCE_INLINE_ RID multimesh_get_2d_uniform_set(RID p_multimesh, RID p_shader, uint32_t p_set) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); + MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh); if (!multimesh->uniform_set_2d.is_valid()) { Vector<RD::Uniform> uniforms; RD::Uniform u; @@ -1775,11 +1775,11 @@ public: Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const; _FORCE_INLINE_ bool skeleton_is_valid(RID p_skeleton) { - return skeleton_owner.getornull(p_skeleton) != nullptr; + return skeleton_owner.get_or_null(p_skeleton) != nullptr; } _FORCE_INLINE_ RID skeleton_get_3d_uniform_set(RID p_skeleton, RID p_shader, uint32_t p_set) const { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); + Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton); ERR_FAIL_COND_V(!skeleton, RID()); ERR_FAIL_COND_V(skeleton->size == 0, RID()); if (skeleton->use_2d) { @@ -1833,7 +1833,7 @@ public: RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light); _FORCE_INLINE_ RS::LightType light_get_type(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); return light->type; @@ -1841,70 +1841,70 @@ public: AABB light_get_aabb(RID p_light) const; _FORCE_INLINE_ float light_get_param(RID p_light, RS::LightParam p_param) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, 0); return light->param[p_param]; } _FORCE_INLINE_ RID light_get_projector(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RID()); return light->projector; } _FORCE_INLINE_ Color light_get_color(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, Color()); return light->color; } _FORCE_INLINE_ Color light_get_shadow_color(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, Color()); return light->shadow_color; } _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, 0); return light->cull_mask; } _FORCE_INLINE_ bool light_has_shadow(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); return light->shadow; } _FORCE_INLINE_ bool light_has_projector(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); return texture_owner.owns(light->projector); } _FORCE_INLINE_ bool light_is_negative(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); return light->negative; } _FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, 0.0); return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; } _FORCE_INLINE_ float light_get_shadow_volumetric_fog_fade(RID p_light) const { - const Light *light = light_owner.getornull(p_light); + const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, 0.0); return light->param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE]; @@ -1971,62 +1971,62 @@ public: virtual void decal_set_normal_fade(RID p_decal, float p_fade); _FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->extents; } _FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->textures[p_texture]; } _FORCE_INLINE_ Color decal_get_modulate(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->modulate; } _FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->emission_energy; } _FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->albedo_mix; } _FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->cull_mask; } _FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->upper_fade; } _FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->lower_fade; } _FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->normal_fade; } _FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->distance_fade; } _FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->distance_fade_begin; } _FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) { - const Decal *decal = decal_owner.getornull(p_decal); + const Decal *decal = decal_owner.get_or_null(p_decal); return decal->distance_fade_length; } @@ -2101,18 +2101,18 @@ public: return lightmap_probe_capture_update_speed; } _FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const { - const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND_V(!lm, RID()); return lm->light_texture; } _FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const { ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays - const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); return lm->array_index; } _FORCE_INLINE_ bool lightmap_uses_spherical_harmonics(RID p_lightmap) const { ERR_FAIL_COND_V(!using_lightmap_array, false); //only for arrays - const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + const Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); return lm->uses_spherical_harmonics; } _FORCE_INLINE_ uint64_t lightmap_array_get_version() const { @@ -2181,13 +2181,13 @@ public: virtual bool particles_is_inactive(RID p_particles) const; _FORCE_INLINE_ RS::ParticlesMode particles_get_mode(RID p_particles) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, RS::PARTICLES_MODE_2D); return particles->mode; } _FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles, uint32_t &r_trail_divisor) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, 0); if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) { @@ -2200,21 +2200,21 @@ public: } _FORCE_INLINE_ bool particles_has_collision(RID p_particles) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, 0); return particles->has_collision_cache; } _FORCE_INLINE_ uint32_t particles_is_using_local_coords(RID p_particles) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, false); return particles->use_local_coords; } _FORCE_INLINE_ RID particles_get_instance_buffer_uniform_set(RID p_particles, RID p_shader, uint32_t p_set) { - Particles *particles = particles_owner.getornull(p_particles); + Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_COND_V(!particles, RID()); if (particles->particles_transforms_buffer_uniform_set.is_null()) { _particles_update_buffers(particles); diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index b95d4b642c..cddb679eba 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -566,11 +566,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge int max_texture_uniforms = 0; int max_uniforms = 0; - for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { - if (SL::is_sampler_type(E->get().type)) { + for (const KeyValue<StringName, SL::ShaderNode::Uniform> &E : pnode->uniforms) { + if (SL::is_sampler_type(E.value.type)) { max_texture_uniforms++; } else { - if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { + if (E.value.scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; // Instances are indexed directly, don't need index uniforms. } @@ -590,8 +590,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge Vector<StringName> uniform_names; - for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { - uniform_names.push_back(E->key()); + for (const KeyValue<StringName, SL::ShaderNode::Uniform> &E : pnode->uniforms) { + uniform_names.push_back(E.key); } uniform_names.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced @@ -724,8 +724,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge Vector<StringName> varying_names; - for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { - varying_names.push_back(E->key()); + for (const KeyValue<StringName, SL::ShaderNode::Varying> &E : pnode->varyings) { + varying_names.push_back(E.key); } varying_names.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 82efa1318c..b9a8947fa2 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -174,8 +174,8 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c if (p_version->uniforms.size()) { builder.append("#define MATERIAL_UNIFORMS_USED\n"); } - for (Map<StringName, CharString>::Element *E = p_version->code_sections.front(); E; E = E->next()) { - builder.append(String("#define ") + String(E->key()) + "_CODE_USED\n"); + for (const KeyValue<StringName, CharString> &E : p_version->code_sections) { + builder.append(String("#define ") + String(E.key) + "_CODE_USED\n"); } } break; case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: { @@ -292,7 +292,7 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { } RS::ShaderNativeSourceCode ShaderRD::version_get_native_source_code(RID p_version) { - Version *version = version_owner.getornull(p_version); + Version *version = version_owner.get_or_null(p_version); RS::ShaderNativeSourceCode source_code; ERR_FAIL_COND_V(!version, source_code); @@ -355,8 +355,8 @@ String ShaderRD::_version_get_sha1(Version *p_version) const { hash_build.append(p_version->compute_globals.get_data()); Vector<StringName> code_sections; - for (Map<StringName, CharString>::Element *E = p_version->code_sections.front(); E; E = E->next()) { - code_sections.push_back(E->key()); + for (const KeyValue<StringName, CharString> &E : p_version->code_sections) { + code_sections.push_back(E.key); } code_sections.sort_custom<StringName::AlphCompare>(); @@ -524,14 +524,14 @@ void ShaderRD::_compile_version(Version *p_version) { void ShaderRD::version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines) { ERR_FAIL_COND(is_compute); - Version *version = version_owner.getornull(p_version); + Version *version = version_owner.get_or_null(p_version); ERR_FAIL_COND(!version); version->vertex_globals = p_vertex_globals.utf8(); version->fragment_globals = p_fragment_globals.utf8(); version->uniforms = p_uniforms.utf8(); version->code_sections.clear(); - for (Map<String, String>::Element *E = p_code.front(); E; E = E->next()) { - version->code_sections[StringName(E->key().to_upper())] = E->get().utf8(); + for (const KeyValue<String, String> &E : p_code) { + version->code_sections[StringName(E.key.to_upper())] = E.value.utf8(); } version->custom_defines.clear(); @@ -549,15 +549,15 @@ void ShaderRD::version_set_code(RID p_version, const Map<String, String> &p_code void ShaderRD::version_set_compute_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines) { ERR_FAIL_COND(!is_compute); - Version *version = version_owner.getornull(p_version); + Version *version = version_owner.get_or_null(p_version); ERR_FAIL_COND(!version); version->compute_globals = p_compute_globals.utf8(); version->uniforms = p_uniforms.utf8(); version->code_sections.clear(); - for (Map<String, String>::Element *E = p_code.front(); E; E = E->next()) { - version->code_sections[StringName(E->key().to_upper())] = E->get().utf8(); + for (const KeyValue<String, String> &E : p_code) { + version->code_sections[StringName(E.key.to_upper())] = E.value.utf8(); } version->custom_defines.clear(); @@ -573,7 +573,7 @@ void ShaderRD::version_set_compute_code(RID p_version, const Map<String, String> } bool ShaderRD::version_is_valid(RID p_version) { - Version *version = version_owner.getornull(p_version); + Version *version = version_owner.get_or_null(p_version); ERR_FAIL_COND_V(!version, false); if (version->dirty) { @@ -585,7 +585,7 @@ bool ShaderRD::version_is_valid(RID p_version) { bool ShaderRD::version_free(RID p_version) { if (version_owner.owns(p_version)) { - Version *version = version_owner.getornull(p_version); + Version *version = version_owner.get_or_null(p_version); _clear_version(version); version_owner.free(p_version); } else { diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index 529328f0ed..984b168659 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -141,7 +141,7 @@ public: ERR_FAIL_INDEX_V(p_variant, variant_defines.size(), RID()); ERR_FAIL_COND_V(!variants_enabled[p_variant], RID()); - Version *version = version_owner.getornull(p_version); + Version *version = version_owner.get_or_null(p_version); ERR_FAIL_COND_V(!version, RID()); if (version->dirty) { diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 8cb56fbc83..f0fb31a457 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -524,7 +524,7 @@ vec4 fog_process(vec3 vertex) { } } - float fog_amount = 1.0 - exp(min(0.0, vertex.z * scene_data.fog_density)); + float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); if (abs(scene_data.fog_height_density) > 0.001) { float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index c3c4139450..750ec5f00a 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -550,7 +550,7 @@ vec4 fog_process(vec3 vertex) { } } - float fog_amount = 1.0 - exp(min(0.0, vertex.z * scene_data.fog_density)); + float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density)); if (abs(scene_data.fog_height_density) > 0.001) { float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index a4e4715292..558516ac7c 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -47,7 +47,7 @@ void RendererSceneCull::camera_initialize(RID p_rid) { } void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::PERSPECTIVE; camera->fov = p_fovy_degrees; @@ -56,7 +56,7 @@ void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degree } void RendererSceneCull::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::ORTHOGONAL; camera->size = p_size; @@ -65,7 +65,7 @@ void RendererSceneCull::camera_set_orthogonal(RID p_camera, float p_size, float } void RendererSceneCull::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::FRUSTUM; camera->size = p_size; @@ -75,32 +75,32 @@ void RendererSceneCull::camera_set_frustum(RID p_camera, float p_size, Vector2 p } void RendererSceneCull::camera_set_transform(RID p_camera, const Transform3D &p_transform) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->transform = p_transform.orthonormalized(); } void RendererSceneCull::camera_set_cull_mask(RID p_camera, uint32_t p_layers) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->visible_layers = p_layers; } void RendererSceneCull::camera_set_environment(RID p_camera, RID p_env) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->env = p_env; } void RendererSceneCull::camera_set_camera_effects(RID p_camera, RID p_fx) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->effects = p_fx; } void RendererSceneCull::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); camera->vaspect = p_enable; } @@ -354,7 +354,7 @@ RID RendererSceneCull::scenario_allocate() { void RendererSceneCull::scenario_initialize(RID p_rid) { scenario_owner.initialize_rid(p_rid); - Scenario *scenario = scenario_owner.getornull(p_rid); + Scenario *scenario = scenario_owner.get_or_null(p_rid); scenario->self = p_rid; scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create(); @@ -373,25 +373,25 @@ void RendererSceneCull::scenario_initialize(RID p_rid) { } void RendererSceneCull::scenario_set_environment(RID p_scenario, RID p_environment) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND(!scenario); scenario->environment = p_environment; } void RendererSceneCull::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND(!scenario); scenario->camera_effects = p_camera_effects; } void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_environment) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND(!scenario); scenario->fallback_environment = p_environment; } void RendererSceneCull::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND(!scenario); scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count); } @@ -401,13 +401,13 @@ bool RendererSceneCull::is_scenario(RID p_scenario) const { } RID RendererSceneCull::scenario_get_environment(RID p_scenario) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND_V(!scenario, RID()); return scenario->environment; } void RendererSceneCull::scenario_remove_viewport_visibility_mask(RID p_scenario, RID p_viewport) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND(!scenario); if (!scenario->viewport_visibility_masks.has(p_viewport)) { return; @@ -419,7 +419,7 @@ void RendererSceneCull::scenario_remove_viewport_visibility_mask(RID p_scenario, } void RendererSceneCull::scenario_add_viewport_visibility_mask(RID p_scenario, RID p_viewport) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND(!scenario); ERR_FAIL_COND(scenario->viewport_visibility_masks.has(p_viewport)); @@ -459,7 +459,7 @@ RID RendererSceneCull::instance_allocate() { } void RendererSceneCull::instance_initialize(RID p_rid) { instance_owner.initialize_rid(p_rid); - Instance *instance = instance_owner.getornull(p_rid); + Instance *instance = instance_owner.get_or_null(p_rid); instance->self = p_rid; } @@ -493,7 +493,7 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) { } void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); Scenario *scenario = instance->scenario; @@ -710,7 +710,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { } void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); if (instance->scenario) { @@ -772,7 +772,7 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) { } if (p_scenario.is_valid()) { - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND(!scenario); instance->scenario = scenario; @@ -805,7 +805,7 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) { } void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); instance->layer_mask = p_mask; @@ -820,7 +820,7 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) } void RendererSceneCull::instance_set_transform(RID p_instance, const Transform3D &p_transform) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); if (instance->transform == p_transform) { @@ -845,14 +845,14 @@ void RendererSceneCull::instance_set_transform(RID p_instance, const Transform3D } void RendererSceneCull::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); instance->object_id = p_id; } void RendererSceneCull::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); if (instance->update_item.in_list()) { @@ -865,7 +865,7 @@ void RendererSceneCull::instance_set_blend_shape_weight(RID p_instance, int p_sh } void RendererSceneCull::instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); if (instance->base_type == RS::INSTANCE_MESH) { @@ -881,7 +881,7 @@ void RendererSceneCull::instance_set_surface_override_material(RID p_instance, i } void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); if (instance->visible == p_visible) { @@ -926,7 +926,7 @@ inline bool is_geometry_instance(RenderingServer::InstanceType p_type) { } void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); ERR_FAIL_COND(!is_geometry_instance(instance->base_type)); @@ -951,7 +951,7 @@ void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { } void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); if (instance->skeleton == p_skeleton) { @@ -976,7 +976,7 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) } void RendererSceneCull::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); instance->extra_margin = p_margin; @@ -985,7 +985,7 @@ void RendererSceneCull::instance_set_extra_visibility_margin(RID p_instance, rea Vector<ObjectID> RendererSceneCull::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { Vector<ObjectID> instances; - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND_V(!scenario, instances); const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling @@ -1009,7 +1009,7 @@ Vector<ObjectID> RendererSceneCull::instances_cull_aabb(const AABB &p_aabb, RID Vector<ObjectID> RendererSceneCull::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { Vector<ObjectID> instances; - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND_V(!scenario, instances); const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling @@ -1032,7 +1032,7 @@ Vector<ObjectID> RendererSceneCull::instances_cull_ray(const Vector3 &p_from, co Vector<ObjectID> RendererSceneCull::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const { Vector<ObjectID> instances; - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_COND_V(!scenario, instances); const_cast<RendererSceneCull *>(this)->update_dirty_instances(); // check dirty instances before culling @@ -1056,7 +1056,7 @@ Vector<ObjectID> RendererSceneCull::instances_cull_convex(const Vector<Plane> &p } void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); //ERR_FAIL_COND(((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK)); @@ -1131,7 +1131,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF } void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); instance->cast_shadows = p_shadow_casting_setting; @@ -1161,7 +1161,7 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc } void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, RID p_material) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); instance->material_override = p_material; @@ -1174,7 +1174,7 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, } void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); instance->visibility_range_begin = p_min; @@ -1194,7 +1194,7 @@ void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, f } void RendererSceneCull::instance_set_visibility_parent(RID p_instance, RID p_parent_instance) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); Instance *old_parent = instance->visibility_parent; @@ -1207,7 +1207,7 @@ void RendererSceneCull::instance_set_visibility_parent(RID p_instance, RID p_par instance->visibility_parent = nullptr; } - Instance *parent = instance_owner.getornull(p_parent_instance); + Instance *parent = instance_owner.get_or_null(p_parent_instance); ERR_FAIL_COND(p_parent_instance.is_valid() && !parent); if (parent) { @@ -1312,7 +1312,7 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins } void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); if (instance->lightmap) { @@ -1321,7 +1321,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig instance->lightmap = nullptr; } - Instance *lightmap_instance = instance_owner.getornull(p_lightmap); + Instance *lightmap_instance = instance_owner.get_or_null(p_lightmap); instance->lightmap = lightmap_instance; instance->lightmap_uv_scale = p_lightmap_uv_scale; @@ -1342,7 +1342,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig } void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); instance->lod_bias = p_lod_bias; @@ -1354,7 +1354,7 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l } void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { - Instance *instance = instance_owner.getornull(p_instance); + Instance *instance = instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); @@ -1377,7 +1377,7 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c } Variant RendererSceneCull::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance); + const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!instance, Variant()); if (instance->instance_shader_parameters.has(p_parameter)) { @@ -1387,7 +1387,7 @@ Variant RendererSceneCull::instance_geometry_get_shader_parameter(RID p_instance } Variant RendererSceneCull::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance); + const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND_V(!instance, Variant()); if (instance->instance_shader_parameters.has(p_parameter)) { @@ -1397,14 +1397,14 @@ Variant RendererSceneCull::instance_geometry_get_shader_parameter_default_value( } void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const { - const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.getornull(p_instance); + const Instance *instance = const_cast<RendererSceneCull *>(this)->instance_owner.get_or_null(p_instance); ERR_FAIL_COND(!instance); const_cast<RendererSceneCull *>(this)->update_dirty_instances(); Vector<StringName> names; - for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) { - names.push_back(E->key()); + for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : instance->instance_shader_parameters) { + names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); for (int i = 0; i < names.size(); i++) { @@ -2354,7 +2354,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info) { #ifndef _3D_DISABLED - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); ERR_FAIL_COND(!camera); RendererSceneRender::CameraData camera_data; @@ -2747,9 +2747,9 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows, RendererScene::RenderInfo *r_render_info) { - Instance *render_reflection_probe = instance_owner.getornull(p_reflection_probe); //if null, not rendering to it + Instance *render_reflection_probe = instance_owner.get_or_null(p_reflection_probe); //if null, not rendering to it - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); render_pass++; @@ -3103,12 +3103,12 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c } RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { - Camera *camera = camera_owner.getornull(p_camera); + Camera *camera = camera_owner.get_or_null(p_camera); if (camera && scene_render->is_environment(camera->env)) { return camera->env; } - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); if (!scenario) { return RID(); } @@ -3125,7 +3125,7 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { #ifndef _3D_DISABLED - Scenario *scenario = scenario_owner.getornull(p_scenario); + Scenario *scenario = scenario_owner.get_or_null(p_scenario); RID environment; if (scenario->environment.is_valid()) { @@ -3688,9 +3688,9 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self); scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset); - for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) { - if (E->get().value.get_type() != Variant::NIL) { - RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value); + for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_parameters) { + if (E.value.value.get_type() != Variant::NIL) { + RSG::storage->global_variables_instance_update(p_instance->self, E.value.index, E.value.value); } } } else { @@ -3750,7 +3750,7 @@ bool RendererSceneCull::free(RID p_rid) { camera_owner.free(p_rid); } else if (scenario_owner.owns(p_rid)) { - Scenario *scenario = scenario_owner.getornull(p_rid); + Scenario *scenario = scenario_owner.get_or_null(p_rid); while (scenario->instances.first()) { instance_set_scenario(scenario->instances.first()->self()->self, RID()); @@ -3771,7 +3771,7 @@ bool RendererSceneCull::free(RID p_rid) { update_dirty_instances(); - Instance *instance = instance_owner.getornull(p_rid); + Instance *instance = instance_owner.get_or_null(p_rid); instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0); instance_set_scenario(p_rid, RID()); diff --git a/servers/rendering/renderer_storage.cpp b/servers/rendering/renderer_storage.cpp index a402ecc668..aa005fac0a 100644 --- a/servers/rendering/renderer_storage.cpp +++ b/servers/rendering/renderer_storage.cpp @@ -33,21 +33,21 @@ RendererStorage *RendererStorage::base_singleton = nullptr; void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p_notification) { - for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { - if (E->key()->changed_callback) { - E->key()->changed_callback(p_notification, E->key()); + for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) { + if (E.key->changed_callback) { + E.key->changed_callback(p_notification, E.key); } } } void RendererStorage::Dependency::deleted_notify(const RID &p_rid) { - for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { - if (E->key()->deleted_callback) { - E->key()->deleted_callback(p_rid, E->key()); + for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) { + if (E.key->deleted_callback) { + E.key->deleted_callback(p_rid, E.key); } } - for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { - E->key()->dependencies.erase(this); + for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) { + E.key->dependencies.erase(this); } instances.clear(); } @@ -56,8 +56,8 @@ RendererStorage::Dependency::~Dependency() { #ifdef DEBUG_ENABLED if (instances.size()) { WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing."); - for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { - E->key()->dependencies.erase(this); + for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) { + E.key->dependencies.erase(this); } } #endif diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 8af2049ab3..74f18b1da5 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -210,9 +210,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::LightOccluderInstance *occluders = nullptr; //make list of occluders - for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); - Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) { @@ -242,10 +242,10 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { int directional_light_count = 0; RENDER_TIMESTAMP("Cull Canvas Lights"); - for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); + for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); - Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); //find lights in canvas @@ -307,7 +307,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { } } - canvas_map[Viewport::CanvasKey(E->key(), E->get().layer, E->get().sublayer)] = &E->get(); + canvas_map[Viewport::CanvasKey(E.key, E.value.layer, E.value.sublayer)] = &E.value; } if (lights_with_shadow) { @@ -319,9 +319,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RENDER_TIMESTAMP("Cull Occluders"); //make list of occluders - for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); - Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) { @@ -400,9 +400,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { //make list of occluders int occ_cullded = 0; - for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get().canvas); - Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); + for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); + Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { if (!F->get()->enabled) { @@ -439,17 +439,17 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { scenario_draw_canvas_bg = false; } - for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) { - RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E->get()->canvas); + for (const KeyValue<Viewport::CanvasKey, Viewport::CanvasData *> &E : canvas_map) { + RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value->canvas); - Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); + Transform2D xform = _canvas_get_transform(p_viewport, canvas, E.value, clip_rect.size); RendererCanvasRender::Light *canvas_lights = nullptr; RendererCanvasRender::Light *canvas_directional_lights = nullptr; RendererCanvasRender::Light *ptr = lights; while (ptr) { - if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) { + if (E.value->layer >= ptr->layer_min && E.value->layer <= ptr->layer_max) { ptr->next_ptr = canvas_lights; canvas_lights = ptr; } @@ -458,7 +458,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { ptr = directional_lights; while (ptr) { - if (E->get()->layer >= ptr->layer_min && E->get()->layer <= ptr->layer_max) { + if (E.value->layer >= ptr->layer_min && E.value->layer <= ptr->layer_max) { ptr->next_ptr = canvas_directional_lights; canvas_directional_lights = ptr; } @@ -471,7 +471,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { } i++; - if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) { + if (scenario_draw_canvas_bg && E.key.get_layer() >= scenario_canvas_max_layer) { if (!can_draw_3d) { RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); } else { @@ -554,7 +554,7 @@ void RendererViewport::draw_viewports() { } if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE) { - Viewport *parent = viewport_owner.getornull(vp->parent); + Viewport *parent = viewport_owner.get_or_null(vp->parent); if (parent && parent->last_pass == draw_viewports_pass) { visible = true; } @@ -660,8 +660,8 @@ void RendererViewport::draw_viewports() { //this needs to be called to make screen swapping more efficient RSG::rasterizer->prepare_for_blitting_render_targets(); - for (Map<int, Vector<BlitToScreen>>::Element *E = blit_to_screen_list.front(); E; E = E->next()) { - RSG::rasterizer->blit_render_targets_to_screen(E->key(), E->get().ptr(), E->get().size()); + for (const KeyValue<int, Vector<BlitToScreen>> &E : blit_to_screen_list) { + RSG::rasterizer->blit_render_targets_to_screen(E.key, E.value.ptr(), E.value.size()); } } @@ -671,7 +671,7 @@ RID RendererViewport::viewport_allocate() { void RendererViewport::viewport_initialize(RID p_rid) { viewport_owner.initialize_rid(p_rid); - Viewport *viewport = viewport_owner.getornull(p_rid); + Viewport *viewport = viewport_owner.get_or_null(p_rid); viewport->self = p_rid; viewport->render_target = RSG::storage->render_target_create(); viewport->shadow_atlas = RSG::scene->shadow_atlas_create(); @@ -679,7 +679,7 @@ void RendererViewport::viewport_initialize(RID p_rid) { } void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (viewport->use_xr == p_use_xr) { @@ -691,7 +691,7 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { } void RendererViewport::viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (viewport->scale_3d == p_scale_3d) { @@ -720,7 +720,7 @@ uint32_t RendererViewport::Viewport::get_view_count() { void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { ERR_FAIL_COND(p_width < 0 && p_height < 0); - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->size = Size2(p_width, p_height); @@ -732,7 +732,7 @@ void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_heig } void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (p_active) { @@ -745,21 +745,21 @@ void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) { } void RendererViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->parent = p_parent_viewport; } void RendererViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->clear_mode = p_clear_mode; } void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (p_screen != DisplayServer::INVALID_WINDOW_ID) { @@ -785,7 +785,7 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_ } void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (p_enable == viewport->viewport_render_direct_to_screen) { @@ -809,21 +809,21 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool } void RendererViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->update_mode = p_mode; } RID RendererViewport::viewport_get_texture(RID p_viewport) const { - const Viewport *viewport = viewport_owner.getornull(p_viewport); + const Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND_V(!viewport, RID()); return RSG::storage->render_target_get_texture(viewport->render_target); } RID RendererViewport::viewport_get_occluder_debug_texture(RID p_viewport) const { - const Viewport *viewport = viewport_owner.getornull(p_viewport); + const Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND_V(!viewport, RID()); if (viewport->use_occlusion_culling && viewport->debug_draw == RenderingServer::VIEWPORT_DEBUG_DRAW_OCCLUDERS) { @@ -833,35 +833,35 @@ RID RendererViewport::viewport_get_occluder_debug_texture(RID p_viewport) const } void RendererViewport::viewport_set_disable_2d(RID p_viewport, bool p_disable) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->disable_2d = p_disable; } void RendererViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->disable_environment = p_disable; } void RendererViewport::viewport_set_disable_3d(RID p_viewport, bool p_disable) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->disable_3d = p_disable; } void RendererViewport::viewport_attach_camera(RID p_viewport, RID p_camera) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->camera = p_camera; } void RendererViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (viewport->scenario.is_valid()) { @@ -875,11 +875,11 @@ void RendererViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { } void RendererViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); ERR_FAIL_COND(viewport->canvas_map.has(p_canvas)); - RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas); + RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.get_or_null(p_canvas); ERR_FAIL_COND(!canvas); canvas->viewports.insert(p_viewport); @@ -890,10 +890,10 @@ void RendererViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { } void RendererViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); - RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.getornull(p_canvas); + RendererCanvasCull::Canvas *canvas = RSG::canvas->canvas_owner.get_or_null(p_canvas); ERR_FAIL_COND(!canvas); viewport->canvas_map.erase(p_canvas); @@ -901,7 +901,7 @@ void RendererViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) { } void RendererViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas)); @@ -909,7 +909,7 @@ void RendererViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canva } void RendererViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_TRANSPARENT, p_enabled); @@ -917,14 +917,14 @@ void RendererViewport::viewport_set_transparent_background(RID p_viewport, bool } void RendererViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->global_transform = p_transform; } void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas)); @@ -933,7 +933,7 @@ void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas } void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->shadow_atlas_size = p_size; @@ -943,14 +943,14 @@ void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size } void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); RSG::scene->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv); } void RendererViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (viewport->msaa == p_msaa) { @@ -961,7 +961,7 @@ void RendererViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa } void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (viewport->screen_space_aa == p_mode) { @@ -972,7 +972,7 @@ void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::Viewport } void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (viewport->use_debanding == p_use_debanding) { @@ -983,7 +983,7 @@ void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_deb } void RendererViewport::viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); if (viewport->use_occlusion_culling == p_use_occlusion_culling) { @@ -1018,7 +1018,7 @@ void RendererViewport::viewport_set_occlusion_culling_build_quality(RS::Viewport } void RendererViewport::viewport_set_lod_threshold(RID p_viewport, float p_pixels) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->lod_threshold = p_pixels; @@ -1027,7 +1027,7 @@ void RendererViewport::viewport_set_lod_threshold(RID p_viewport, float p_pixels int RendererViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfoType p_type, RS::ViewportRenderInfo p_info) { ERR_FAIL_INDEX_V(p_info, RS::VIEWPORT_RENDER_INFO_MAX, -1); - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); if (!viewport) { return 0; //there should be a lock here.. } @@ -1036,62 +1036,62 @@ int RendererViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRende } void RendererViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->debug_draw = p_draw; } void RendererViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->measure_render_time = p_enable; } float RendererViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND_V(!viewport, 0); return double(viewport->time_cpu_end - viewport->time_cpu_begin) / 1000.0; } float RendererViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND_V(!viewport, 0); return double((viewport->time_gpu_end - viewport->time_gpu_begin) / 1000) / 1000.0; } void RendererViewport::viewport_set_snap_2d_transforms_to_pixel(RID p_viewport, bool p_enabled) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->snap_2d_transforms_to_pixel = p_enabled; } void RendererViewport::viewport_set_snap_2d_vertices_to_pixel(RID p_viewport, bool p_enabled) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->snap_2d_vertices_to_pixel = p_enabled; } void RendererViewport::viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter) { ERR_FAIL_COND_MSG(p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, "Viewport does not accept DEFAULT as texture filter (it's the topmost choice already).)"); - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->texture_filter = p_filter; } void RendererViewport::viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat) { ERR_FAIL_COND_MSG(p_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, "Viewport does not accept DEFAULT as texture repeat (it's the topmost choice already).)"); - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); viewport->texture_repeat = p_repeat; } void RendererViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { - Viewport *viewport = viewport_owner.getornull(p_viewport); + Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); RSG::storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale); @@ -1099,7 +1099,7 @@ void RendererViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::V bool RendererViewport::free(RID p_rid) { if (viewport_owner.owns(p_rid)) { - Viewport *viewport = viewport_owner.getornull(p_rid); + Viewport *viewport = viewport_owner.get_or_null(p_rid); RSG::storage->free(viewport->render_target); RSG::scene->free(viewport->shadow_atlas); @@ -1132,7 +1132,7 @@ void RendererViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, return; } - Viewport *viewport = viewport_owner.getornull(*vp); + Viewport *viewport = viewport_owner.get_or_null(*vp); if (!viewport) { return; } diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp index fa3f2f3895..a21f28989b 100644 --- a/servers/rendering/rendering_device_binds.cpp +++ b/servers/rendering/rendering_device_binds.cpp @@ -171,7 +171,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String /* STEP 2, Compile the versions, add to shader file */ - for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) { + for (const KeyValue<StringName, String> &E : version_texts) { Ref<RDShaderSPIRV> bytecode; bytecode.instantiate(); @@ -180,7 +180,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String if (code == String()) { continue; } - code = code.replace("VERSION_DEFINES", E->get()); + code = code.replace("VERSION_DEFINES", E.value); String error; Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_spirv_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false); bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv); @@ -195,7 +195,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String bytecode->set_stage_compile_error(RD::ShaderStage(i), error); } - set_bytecode(bytecode, E->key()); + set_bytecode(bytecode, E.key); } return errors_found ? ERR_PARSE_ERROR : OK; diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index ccc3e2fb39..da614877c4 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -351,8 +351,8 @@ public: Vector<StringName> get_version_list() const { Vector<StringName> vnames; - for (Map<StringName, Ref<RDShaderSPIRV>>::Element *E = versions.front(); E; E = E->next()) { - vnames.push_back(E->key()); + for (const KeyValue<StringName, Ref<RDShaderSPIRV>> &E : versions) { + vnames.push_back(E.key); } vnames.sort_custom<StringName::AlphCompare>(); return vnames; @@ -371,9 +371,9 @@ public: if (base_error != "") { ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error); } else { - for (Map<StringName, Ref<RDShaderSPIRV>>::Element *E = versions.front(); E; E = E->next()) { + for (KeyValue<StringName, Ref<RDShaderSPIRV>> &E : versions) { for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { - String error = E->get()->get_stage_compile_error(RD::ShaderStage(i)); + String error = E.value->get_stage_compile_error(RD::ShaderStage(i)); if (error != String()) { static const char *stage_str[RD::SHADER_STAGE_MAX] = { "vertex", @@ -383,7 +383,7 @@ public: "compute" }; - ERR_PRINT("Error parsing shader '" + p_file + "', version '" + String(E->key()) + "', stage '" + stage_str[i] + "':\n\n" + error); + ERR_PRINT("Error parsing shader '" + p_file + "', version '" + String(E.key) + "', stage '" + stage_str[i] + "':\n\n" + error); } } } diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index bed6ade1f6..62390f9d4d 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -45,6 +45,9 @@ int RenderingServerDefault::changes = 0; /* FREE */ void RenderingServerDefault::_free(RID p_rid) { + if (unlikely(p_rid.is_null())) { + return; + } if (RSG::storage->free(p_rid)) { return; } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index d6f8fe85c9..f960d4af5f 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -3546,9 +3546,9 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam arg->tex_argument_check = true; arg->tex_argument_filter = p_filter; arg->tex_argument_repeat = p_repeat; - for (Map<StringName, Set<int>>::Element *E = arg->tex_argument_connect.front(); E; E = E->next()) { - for (Set<int>::Element *F = E->get().front(); F; F = F->next()) { - if (!_propagate_function_call_sampler_uniform_settings(E->key(), F->get(), p_filter, p_repeat)) { + for (KeyValue<StringName, Set<int>> &E : arg->tex_argument_connect) { + for (Set<int>::Element *F = E.value.front(); F; F = F->next()) { + if (!_propagate_function_call_sampler_uniform_settings(E.key, F->get(), p_filter, p_repeat)) { return false; } } @@ -3580,9 +3580,9 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa arg->tex_builtin_check = true; arg->tex_builtin = p_builtin; - for (Map<StringName, Set<int>>::Element *E = arg->tex_argument_connect.front(); E; E = E->next()) { - for (Set<int>::Element *F = E->get().front(); F; F = F->next()) { - if (!_propagate_function_call_sampler_builtin_reference(E->key(), F->get(), p_builtin)) { + for (KeyValue<StringName, Set<int>> &E : arg->tex_argument_connect) { + for (Set<int>::Element *F = E.value.front(); F; F = F->next()) { + if (!_propagate_function_call_sampler_builtin_reference(E.key, F->get(), p_builtin)) { return false; } } @@ -7712,8 +7712,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } if (p_functions.has("global")) { // Adds global variables: 'TIME' - for (Map<StringName, BuiltInInfo>::Element *E = p_functions["global"].built_ins.front(); E; E = E->next()) { - builtins.built_ins.insert(E->key(), E->value()); + for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["global"].built_ins) { + builtins.built_ins.insert(E.key, E.value); } } @@ -7985,8 +7985,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) { - for (Map<StringName, ShaderLanguage::FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) { - if (E->get().built_ins.has(p_name)) { + for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : p_functions) { + if (E.value.built_ins.has(p_name)) { return true; } } @@ -8126,19 +8126,19 @@ String ShaderLanguage::get_shader_type(const String &p_code) { #ifdef DEBUG_ENABLED void ShaderLanguage::_check_warning_accums() { - for (Map<ShaderWarning::Code, Map<StringName, Map<StringName, Usage>> *>::Element *E = warnings_check_map2.front(); E; E = E->next()) { - for (Map<StringName, Map<StringName, Usage>>::Element *T = (*E->get()).front(); T; T = T->next()) { - for (const Map<StringName, Usage>::Element *U = T->get().front(); U; U = U->next()) { - if (!U->get().used) { - _add_warning(E->key(), U->get().decl_line, U->key()); + for (const KeyValue<ShaderWarning::Code, Map<StringName, Map<StringName, Usage>> *> &E : warnings_check_map2) { + for (Map<StringName, Map<StringName, Usage>>::Element *T = (*E.value).front(); T; T = T->next()) { + for (const KeyValue<StringName, Usage> &U : T->get()) { + if (!U.value.used) { + _add_warning(E.key, U.value.decl_line, U.key); } } } } - for (Map<ShaderWarning::Code, Map<StringName, Usage> *>::Element *E = warnings_check_map.front(); E; E = E->next()) { - for (const Map<StringName, Usage>::Element *U = (*E->get()).front(); U; U = U->next()) { + for (const KeyValue<ShaderWarning::Code, Map<StringName, Usage> *> &E : warnings_check_map) { + for (const Map<StringName, Usage>::Element *U = (*E.value).front(); U; U = U->next()) { if (!U->get().used) { - _add_warning(E->key(), U->get().decl_line, U->key()); + _add_warning(E.key, U->get().decl_line, U->key()); } } } @@ -8221,8 +8221,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct return OK; } break; case COMPLETION_MAIN_FUNCTION: { - for (const Map<StringName, FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) { - ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_FUNCTION); + for (const KeyValue<StringName, FunctionInfo> &E : p_functions) { + ScriptCodeCompletionOption option(E.key, ScriptCodeCompletionOption::KIND_FUNCTION); r_options->push_back(option); } @@ -8238,9 +8238,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct if (completion_class == TAG_GLOBAL) { while (block) { if (comp_ident) { - for (const Map<StringName, BlockNode::Variable>::Element *E = block->variables.front(); E; E = E->next()) { - if (E->get().line < completion_line) { - matches.insert(E->key(), ScriptCodeCompletionOption::KIND_VARIABLE); + for (const KeyValue<StringName, BlockNode::Variable> &E : block->variables) { + if (E.value.line < completion_line) { + matches.insert(E.key, ScriptCodeCompletionOption::KIND_VARIABLE); } } } @@ -8258,30 +8258,30 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct if (comp_ident) { if (p_functions.has("global")) { - for (Map<StringName, BuiltInInfo>::Element *E = p_functions["global"].built_ins.front(); E; E = E->next()) { + for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["global"].built_ins) { ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER; - if (E->get().constant) { + if (E.value.constant) { kind = ScriptCodeCompletionOption::KIND_CONSTANT; } - matches.insert(E->key(), kind); + matches.insert(E.key, kind); } } if (skip_function != StringName() && p_functions.has(skip_function)) { - for (Map<StringName, BuiltInInfo>::Element *E = p_functions[skip_function].built_ins.front(); E; E = E->next()) { + for (const KeyValue<StringName, BuiltInInfo> &E : p_functions[skip_function].built_ins) { ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER; - if (E->get().constant) { + if (E.value.constant) { kind = ScriptCodeCompletionOption::KIND_CONSTANT; } - matches.insert(E->key(), kind); + matches.insert(E.key, kind); } } - for (const Map<StringName, ShaderNode::Varying>::Element *E = shader->varyings.front(); E; E = E->next()) { - matches.insert(E->key(), ScriptCodeCompletionOption::KIND_VARIABLE); + for (const KeyValue<StringName, ShaderNode::Varying> &E : shader->varyings) { + matches.insert(E.key, ScriptCodeCompletionOption::KIND_VARIABLE); } - for (const Map<StringName, ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) { - matches.insert(E->key(), ScriptCodeCompletionOption::KIND_MEMBER); + for (const KeyValue<StringName, ShaderNode::Uniform> &E : shader->uniforms) { + matches.insert(E.key, ScriptCodeCompletionOption::KIND_MEMBER); } } @@ -8296,8 +8296,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct bool low_end = RenderingServer::get_singleton()->is_low_end(); if (stages && stages->has(skip_function)) { - for (const Map<StringName, StageFunctionInfo>::Element *E = (*stages)[skip_function].stage_functions.front(); E; E = E->next()) { - matches.insert(String(E->key()), ScriptCodeCompletionOption::KIND_FUNCTION); + for (const KeyValue<StringName, StageFunctionInfo> &E : (*stages)[skip_function].stage_functions) { + matches.insert(String(E.key), ScriptCodeCompletionOption::KIND_FUNCTION); } } @@ -8326,9 +8326,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } } - for (Map<String, ScriptCodeCompletionOption::Kind>::Element *E = matches.front(); E; E = E->next()) { - ScriptCodeCompletionOption option(E->key(), E->value()); - if (E->value() == ScriptCodeCompletionOption::KIND_FUNCTION) { + for (const KeyValue<String, ScriptCodeCompletionOption::Kind> &E : matches) { + ScriptCodeCompletionOption option(E.key, E.value); + if (E.value == ScriptCodeCompletionOption::KIND_FUNCTION) { option.insert_text += "("; } r_options->push_back(option); @@ -8420,14 +8420,14 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct bool low_end = RenderingServer::get_singleton()->is_low_end(); if (stages && stages->has(block_function)) { - for (const Map<StringName, StageFunctionInfo>::Element *E = (*stages)[block_function].stage_functions.front(); E; E = E->next()) { - if (completion_function == E->key()) { - calltip += get_datatype_name(E->get().return_type); + for (const KeyValue<StringName, StageFunctionInfo> &E : (*stages)[block_function].stage_functions) { + if (completion_function == E.key) { + calltip += get_datatype_name(E.value.return_type); calltip += " "; - calltip += E->key(); + calltip += E.key; calltip += "("; - for (int i = 0; i < E->get().arguments.size(); i++) { + for (int i = 0; i < E.value.arguments.size(); i++) { if (i > 0) { calltip += ", "; } else { @@ -8438,16 +8438,16 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct calltip += char32_t(0xFFFF); } - calltip += get_datatype_name(E->get().arguments[i].type); + calltip += get_datatype_name(E.value.arguments[i].type); calltip += " "; - calltip += E->get().arguments[i].name; + calltip += E.value.arguments[i].name; if (i == completion_argument) { calltip += char32_t(0xFFFF); } } - if (E->get().arguments.size()) { + if (E.value.arguments.size()) { calltip += " "; } calltip += ")"; diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp index 0c1d6408c9..0b8476478c 100644 --- a/servers/rendering/shader_warnings.cpp +++ b/servers/rendering/shader_warnings.cpp @@ -119,10 +119,10 @@ ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, b init_code_to_flags_map(); } - for (Map<Code, bool>::Element *E = p_map.front(); E; E = E->next()) { - if (E->get()) { - ERR_FAIL_COND_V(!code_to_flags_map->has((int)E->key()), ShaderWarning::NONE_FLAG); - result |= (*code_to_flags_map)[(int)E->key()]; + for (const KeyValue<Code, bool> &E : p_map) { + if (E.value) { + ERR_FAIL_COND_V(!code_to_flags_map->has((int)E.key), ShaderWarning::NONE_FLAG); + result |= (*code_to_flags_map)[(int)E.key]; } } return (CodeFlags)result; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 1b10e4dcbe..58e99f0e91 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2539,6 +2539,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &RenderingServer::canvas_item_add_rect); ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &RenderingServer::canvas_item_add_circle); ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect", "item", "rect", "texture", "tile", "modulate", "transpose"), &RenderingServer::canvas_item_add_texture_rect, DEFVAL(false), DEFVAL(Color(1, 1, 1)), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("canvas_item_add_msdf_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "outline_size", "px_range"), &RenderingServer::canvas_item_add_msdf_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "transpose", "clip_uv"), &RenderingServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true)); ClassDB::bind_method(D_METHOD("canvas_item_add_nine_patch", "item", "rect", "source", "texture", "topleft", "bottomright", "x_axis_mode", "y_axis_mode", "draw_center", "modulate"), &RenderingServer::canvas_item_add_nine_patch, DEFVAL(NINE_PATCH_STRETCH), DEFVAL(NINE_PATCH_STRETCH), DEFVAL(true), DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("canvas_item_add_primitive", "item", "points", "colors", "uvs", "texture", "width"), &RenderingServer::canvas_item_add_primitive, DEFVAL(1.0)); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 1b04a6e5e2..579f8abbe6 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -295,7 +295,7 @@ public: AABB aabb; struct LOD { - float edge_length; + float edge_length = 0.0f; Vector<uint8_t> index_data; }; Vector<LOD> lods; diff --git a/servers/text/SCsub b/servers/text/SCsub new file mode 100644 index 0000000000..86681f9c74 --- /dev/null +++ b/servers/text/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp new file mode 100644 index 0000000000..a44fee7c95 --- /dev/null +++ b/servers/text/text_server_extension.cpp @@ -0,0 +1,1281 @@ +/*************************************************************************/ +/* text_server_extension.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "text_server_extension.h" + +void TextServerExtension::_bind_methods() { + GDVIRTUAL_BIND(_has_feature, "feature"); + GDVIRTUAL_BIND(_get_name); + GDVIRTUAL_BIND(_get_features); + + GDVIRTUAL_BIND(_free, "rid"); + GDVIRTUAL_BIND(_has, "rid"); + GDVIRTUAL_BIND(_load_support_data, "filename"); + + GDVIRTUAL_BIND(_get_support_data_filename); + GDVIRTUAL_BIND(_get_support_data_info); + GDVIRTUAL_BIND(_save_support_data, "filename"); + + GDVIRTUAL_BIND(_is_locale_right_to_left, "locale"); + + GDVIRTUAL_BIND(_name_to_tag, "name"); + GDVIRTUAL_BIND(_tag_to_name, "tag"); + + /* Font interface */ + + GDVIRTUAL_BIND(_create_font); + + GDVIRTUAL_BIND(_font_set_data, "font_rid", "data"); + GDVIRTUAL_BIND(_font_set_data_ptr, "font_rid", "data_ptr", "data_size"); + + GDVIRTUAL_BIND(_font_set_antialiased, "font_rid", "antialiased"); + GDVIRTUAL_BIND(_font_is_antialiased, "font_rid"); + + GDVIRTUAL_BIND(_font_set_multichannel_signed_distance_field, "font_rid", "msdf"); + GDVIRTUAL_BIND(_font_is_multichannel_signed_distance_field, "font_rid"); + + GDVIRTUAL_BIND(_font_set_msdf_pixel_range, "font_rid", "msdf_pixel_range"); + GDVIRTUAL_BIND(_font_get_msdf_pixel_range, "font_rid"); + + GDVIRTUAL_BIND(_font_set_msdf_size, "font_rid", "msdf_size"); + GDVIRTUAL_BIND(_font_get_msdf_size, "font_rid"); + + GDVIRTUAL_BIND(_font_set_fixed_size, "font_rid", "fixed_size"); + GDVIRTUAL_BIND(_font_get_fixed_size, "font_rid"); + + GDVIRTUAL_BIND(_font_set_force_autohinter, "font_rid", "force_autohinter"); + GDVIRTUAL_BIND(_font_is_force_autohinter, "font_rid"); + + GDVIRTUAL_BIND(_font_set_hinting, "font_rid", "hinting"); + GDVIRTUAL_BIND(_font_get_hinting, "font_rid"); + + GDVIRTUAL_BIND(_font_set_variation_coordinates, "font_rid", "variation_coordinates"); + GDVIRTUAL_BIND(_font_get_variation_coordinates, "font_rid"); + + GDVIRTUAL_BIND(_font_set_oversampling, "font_rid", "oversampling"); + GDVIRTUAL_BIND(_font_get_oversampling, "font_rid"); + + GDVIRTUAL_BIND(_font_get_size_cache_list, "font_rid"); + GDVIRTUAL_BIND(_font_clear_size_cache, "font_rid"); + GDVIRTUAL_BIND(_font_remove_size_cache, "font_rid", "size"); + + GDVIRTUAL_BIND(_font_set_ascent, "font_rid", "size", "ascent"); + GDVIRTUAL_BIND(_font_get_ascent, "font_rid", "size"); + + GDVIRTUAL_BIND(_font_set_descent, "font_rid", "size", "descent"); + GDVIRTUAL_BIND(_font_get_descent, "font_rid", "size"); + + GDVIRTUAL_BIND(_font_set_underline_position, "font_rid", "size", "underline_position"); + GDVIRTUAL_BIND(_font_get_underline_position, "font_rid", "size"); + + GDVIRTUAL_BIND(_font_set_underline_thickness, "font_rid", "size", "underline_thickness"); + GDVIRTUAL_BIND(_font_get_underline_thickness, "font_rid", "size"); + + GDVIRTUAL_BIND(_font_set_scale, "font_rid", "size", "scale"); + GDVIRTUAL_BIND(_font_get_scale, "font_rid", "size"); + + GDVIRTUAL_BIND(_font_set_spacing, "font_rid", "size", "spacing", "value"); + GDVIRTUAL_BIND(_font_get_spacing, "font_rid", "size", "spacing"); + + GDVIRTUAL_BIND(_font_get_texture_count, "font_rid", "size"); + GDVIRTUAL_BIND(_font_clear_textures, "font_rid", "size"); + GDVIRTUAL_BIND(_font_remove_texture, "font_rid", "size", "texture_index"); + + GDVIRTUAL_BIND(_font_set_texture_image, "font_rid", "size", "texture_index", "image"); + GDVIRTUAL_BIND(_font_get_texture_image, "font_rid", "size", "texture_index"); + + GDVIRTUAL_BIND(_font_set_texture_offsets, "font_rid", "size", "texture_index", "offset"); + GDVIRTUAL_BIND(_font_get_texture_offsets, "font_rid", "size", "texture_index"); + + GDVIRTUAL_BIND(_font_get_glyph_list, "font_rid", "size"); + GDVIRTUAL_BIND(_font_clear_glyphs, "font_rid", "size"); + GDVIRTUAL_BIND(_font_remove_glyph, "font_rid", "size", "glyph"); + + GDVIRTUAL_BIND(_font_get_glyph_advance, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(_font_set_glyph_advance, "font_rid", "size", "glyph", "advance"); + + GDVIRTUAL_BIND(_font_get_glyph_offset, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(_font_set_glyph_offset, "font_rid", "size", "glyph", "offset"); + + GDVIRTUAL_BIND(_font_get_glyph_size, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(_font_set_glyph_size, "font_rid", "size", "glyph", "gl_size"); + + GDVIRTUAL_BIND(_font_get_glyph_uv_rect, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(_font_set_glyph_uv_rect, "font_rid", "size", "glyph", "uv_rect"); + + GDVIRTUAL_BIND(_font_get_glyph_texture_idx, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(_font_set_glyph_texture_idx, "font_rid", "size", "glyph", "texture_idx"); + + GDVIRTUAL_BIND(_font_get_glyph_contours, "font_rid", "size", "index"); + + GDVIRTUAL_BIND(_font_get_kerning_list, "font_rid", "size"); + GDVIRTUAL_BIND(_font_clear_kerning_map, "font_rid", "size"); + GDVIRTUAL_BIND(_font_remove_kerning, "font_rid", "size", "glyph_pair"); + + GDVIRTUAL_BIND(_font_set_kerning, "font_rid", "size", "glyph_pair", "kerning"); + GDVIRTUAL_BIND(_font_get_kerning, "font_rid", "size", "glyph_pair"); + + GDVIRTUAL_BIND(_font_get_glyph_index, "font_rid", "size", "char", "variation_selector"); + + GDVIRTUAL_BIND(_font_has_char, "font_rid", "char"); + GDVIRTUAL_BIND(_font_get_supported_chars, "font_rid"); + + GDVIRTUAL_BIND(_font_render_range, "font_rid", "size", "start", "end"); + GDVIRTUAL_BIND(_font_render_glyph, "font_rid", "size", "index"); + + GDVIRTUAL_BIND(_font_draw_glyph, "font_rid", "canvas", "size", "pos", "index", "color"); + GDVIRTUAL_BIND(_font_draw_glyph_outline, "font_rid", "canvas", "size", "outline_size", "pos", "index", "color"); + + GDVIRTUAL_BIND(_font_is_language_supported, "font_rid", "language"); + GDVIRTUAL_BIND(_font_set_language_support_override, "font_rid", "language", "supported"); + GDVIRTUAL_BIND(_font_get_language_support_override, "font_rid", "language"); + GDVIRTUAL_BIND(_font_remove_language_support_override, "font_rid", "language"); + GDVIRTUAL_BIND(_font_get_language_support_overrides, "font_rid"); + + GDVIRTUAL_BIND(_font_is_script_supported, "font_rid", "script"); + GDVIRTUAL_BIND(_font_set_script_support_override, "font_rid", "script", "supported"); + GDVIRTUAL_BIND(_font_get_script_support_override, "font_rid", "script"); + GDVIRTUAL_BIND(_font_remove_script_support_override, "font_rid", "script"); + GDVIRTUAL_BIND(_font_get_script_support_overrides, "font_rid"); + + GDVIRTUAL_BIND(_font_supported_feature_list, "font_rid"); + GDVIRTUAL_BIND(_font_supported_variation_list, "font_rid"); + + GDVIRTUAL_BIND(_font_get_global_oversampling); + GDVIRTUAL_BIND(_font_set_global_oversampling, "oversampling"); + + GDVIRTUAL_BIND(_get_hex_code_box_size, "size", "index"); + GDVIRTUAL_BIND(_draw_hex_code_box, "canvas", "size", "pos", "index", "color"); + + /* Shaped text buffer interface */ + + GDVIRTUAL_BIND(_create_shaped_text, "direction", "orientation"); + + GDVIRTUAL_BIND(_shaped_text_clear, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_set_direction, "shaped", "direction"); + GDVIRTUAL_BIND(_shaped_text_get_direction, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_set_bidi_override, "shaped", "override"); + + GDVIRTUAL_BIND(_shaped_text_set_orientation, "shaped", "orientation"); + GDVIRTUAL_BIND(_shaped_text_get_orientation, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_set_preserve_invalid, "shaped", "enabled"); + GDVIRTUAL_BIND(_shaped_text_get_preserve_invalid, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_set_preserve_control, "shaped", "enabled"); + GDVIRTUAL_BIND(_shaped_text_get_preserve_control, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language"); + GDVIRTUAL_BIND(_shaped_text_add_object, "shaped", "key", "size", "inline_align", "length"); + GDVIRTUAL_BIND(_shaped_text_resize_object, "shaped", "key", "size", "inline_align"); + + GDVIRTUAL_BIND(_shaped_text_substr, "shaped", "start", "length"); + GDVIRTUAL_BIND(_shaped_text_get_parent, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_fit_to_width, "shaped", "width", "jst_flags"); + GDVIRTUAL_BIND(_shaped_text_tab_align, "shaped", "tab_stops"); + + GDVIRTUAL_BIND(_shaped_text_shape, "shaped"); + GDVIRTUAL_BIND(_shaped_text_update_breaks, "shaped"); + GDVIRTUAL_BIND(_shaped_text_update_justification_ops, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_is_ready, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_get_glyphs, "shaped", "r_glyphs"); + GDVIRTUAL_BIND(_shaped_text_sort_logical, "shaped", "r_glyphs"); + GDVIRTUAL_BIND(_shaped_text_get_glyph_count, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_get_range, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_get_line_breaks_adv, "shaped", "width", "start", "once", "break_flags"); + GDVIRTUAL_BIND(_shaped_text_get_line_breaks, "shaped", "width", "start", "break_flags"); + GDVIRTUAL_BIND(_shaped_text_get_word_breaks, "shaped", "grapheme_flags"); + + GDVIRTUAL_BIND(_shaped_text_get_trim_pos, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_ellipsis_pos, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyph_count, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyphs, "shaped", "r_glyphs"); + + GDVIRTUAL_BIND(_shaped_text_overrun_trim_to_width, "shaped", "width", "trim_flags"); + + GDVIRTUAL_BIND(_shaped_text_get_objects, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_object_rect, "shaped", "key"); + + GDVIRTUAL_BIND(_shaped_text_get_size, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_ascent, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_descent, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_width, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_underline_position, "shaped"); + GDVIRTUAL_BIND(_shaped_text_get_underline_thickness, "shaped"); + + GDVIRTUAL_BIND(_shaped_text_get_dominant_direction_in_range, "shaped", "start", "end"); + + GDVIRTUAL_BIND(_shaped_text_get_carets, "shaped", "position", "caret"); + GDVIRTUAL_BIND(_shaped_text_get_selection, "shaped", "start", "end"); + + GDVIRTUAL_BIND(_shaped_text_hit_test_grapheme, "shaped", "coord"); + GDVIRTUAL_BIND(_shaped_text_hit_test_position, "shaped", "coord"); + + GDVIRTUAL_BIND(_shaped_text_draw, "shaped", "canvas", "pos", "clip_l", "clip_r", "color"); + GDVIRTUAL_BIND(_shaped_text_draw_outline, "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color"); + + GDVIRTUAL_BIND(_shaped_text_next_grapheme_pos, "shaped", "pos"); + GDVIRTUAL_BIND(_shaped_text_prev_grapheme_pos, "shaped", "pos"); + + GDVIRTUAL_BIND(_format_number, "string", "language"); + GDVIRTUAL_BIND(_parse_number, "string", "language"); + GDVIRTUAL_BIND(_percent_sign, "language"); +} + +bool TextServerExtension::has_feature(Feature p_feature) const { + bool ret; + if (GDVIRTUAL_CALL(_has_feature, p_feature, ret)) { + return ret; + } + return false; +} + +String TextServerExtension::get_name() const { + String ret; + if (GDVIRTUAL_CALL(_get_name, ret)) { + return ret; + } + return "Unknown"; +} + +uint32_t TextServerExtension::get_features() const { + uint32_t ret; + if (GDVIRTUAL_CALL(_get_features, ret)) { + return ret; + } + return 0; +} + +void TextServerExtension::free(RID p_rid) { + GDVIRTUAL_CALL(_free, p_rid); +} + +bool TextServerExtension::has(RID p_rid) { + bool ret; + if (GDVIRTUAL_CALL(_has, p_rid, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::load_support_data(const String &p_filename) { + bool ret; + if (GDVIRTUAL_CALL(_load_support_data, p_filename, ret)) { + return ret; + } + return false; +} + +String TextServerExtension::get_support_data_filename() const { + String ret; + if (GDVIRTUAL_CALL(_get_support_data_filename, ret)) { + return ret; + } + return String(); +} + +String TextServerExtension::get_support_data_info() const { + String ret; + if (GDVIRTUAL_CALL(_get_support_data_info, ret)) { + return ret; + } + return String(); +} + +bool TextServerExtension::save_support_data(const String &p_filename) const { + bool ret; + if (GDVIRTUAL_CALL(_save_support_data, p_filename, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::is_locale_right_to_left(const String &p_locale) const { + bool ret; + if (GDVIRTUAL_CALL(_is_locale_right_to_left, p_locale, ret)) { + return ret; + } + return false; +} + +int32_t TextServerExtension::name_to_tag(const String &p_name) const { + int32_t ret; + if (GDVIRTUAL_CALL(_name_to_tag, p_name, ret)) { + return ret; + } + return 0; +} + +String TextServerExtension::tag_to_name(int32_t p_tag) const { + String ret; + if (GDVIRTUAL_CALL(_tag_to_name, p_tag, ret)) { + return ret; + } + return ""; +} + +/*************************************************************************/ +/* Font */ +/*************************************************************************/ + +RID TextServerExtension::create_font() { + RID ret; + if (GDVIRTUAL_CALL(_create_font, ret)) { + return ret; + } + return RID(); +} + +void TextServerExtension::font_set_data(RID p_font_rid, const PackedByteArray &p_data) { + GDVIRTUAL_CALL(_font_set_data, p_font_rid, p_data); +} + +void TextServerExtension::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) { + GDVIRTUAL_CALL(_font_set_data_ptr, p_font_rid, p_data_ptr, p_data_size); +} + +void TextServerExtension::font_set_antialiased(RID p_font_rid, bool p_antialiased) { + GDVIRTUAL_CALL(_font_set_antialiased, p_font_rid, p_antialiased); +} + +bool TextServerExtension::font_is_antialiased(RID p_font_rid) const { + bool ret; + if (GDVIRTUAL_CALL(_font_is_antialiased, p_font_rid, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) { + GDVIRTUAL_CALL(_font_set_multichannel_signed_distance_field, p_font_rid, p_msdf); +} + +bool TextServerExtension::font_is_multichannel_signed_distance_field(RID p_font_rid) const { + bool ret; + if (GDVIRTUAL_CALL(_font_is_multichannel_signed_distance_field, p_font_rid, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) { + GDVIRTUAL_CALL(_font_set_msdf_pixel_range, p_font_rid, p_msdf_pixel_range); +} + +int TextServerExtension::font_get_msdf_pixel_range(RID p_font_rid) const { + int ret; + if (GDVIRTUAL_CALL(_font_get_msdf_pixel_range, p_font_rid, ret)) { + return ret; + } + return 0; +} + +void TextServerExtension::font_set_msdf_size(RID p_font_rid, int p_msdf_size) { + GDVIRTUAL_CALL(_font_set_msdf_size, p_font_rid, p_msdf_size); +} + +int TextServerExtension::font_get_msdf_size(RID p_font_rid) const { + int ret; + if (GDVIRTUAL_CALL(_font_get_msdf_size, p_font_rid, ret)) { + return ret; + } + return 0; +} + +void TextServerExtension::font_set_fixed_size(RID p_font_rid, int p_fixed_size) { + GDVIRTUAL_CALL(_font_set_fixed_size, p_font_rid, p_fixed_size); +} + +int TextServerExtension::font_get_fixed_size(RID p_font_rid) const { + int ret; + if (GDVIRTUAL_CALL(_font_get_fixed_size, p_font_rid, ret)) { + return ret; + } + return 0; +} + +void TextServerExtension::font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) { + GDVIRTUAL_CALL(_font_set_force_autohinter, p_font_rid, p_force_autohinter); +} + +bool TextServerExtension::font_is_force_autohinter(RID p_font_rid) const { + bool ret; + if (GDVIRTUAL_CALL(_font_is_force_autohinter, p_font_rid, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) { + GDVIRTUAL_CALL(_font_set_hinting, p_font_rid, p_hinting); +} + +TextServer::Hinting TextServerExtension::font_get_hinting(RID p_font_rid) const { + int ret; + if (GDVIRTUAL_CALL(_font_get_hinting, p_font_rid, ret)) { + return (TextServer::Hinting)ret; + } + return TextServer::Hinting::HINTING_NONE; +} + +void TextServerExtension::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { + GDVIRTUAL_CALL(_font_set_variation_coordinates, p_font_rid, p_variation_coordinates); +} + +Dictionary TextServerExtension::font_get_variation_coordinates(RID p_font_rid) const { + Dictionary ret; + if (GDVIRTUAL_CALL(_font_get_variation_coordinates, p_font_rid, ret)) { + return ret; + } + return Dictionary(); +} + +void TextServerExtension::font_set_oversampling(RID p_font_rid, float p_oversampling) { + GDVIRTUAL_CALL(_font_set_oversampling, p_font_rid, p_oversampling); +} + +float TextServerExtension::font_get_oversampling(RID p_font_rid) const { + float ret; + if (GDVIRTUAL_CALL(_font_get_oversampling, p_font_rid, ret)) { + return ret; + } + return 0.f; +} + +Array TextServerExtension::font_get_size_cache_list(RID p_font_rid) const { + Array ret; + if (GDVIRTUAL_CALL(_font_get_size_cache_list, p_font_rid, ret)) { + return ret; + } + return Array(); +} + +void TextServerExtension::font_clear_size_cache(RID p_font_rid) { + GDVIRTUAL_CALL(_font_clear_size_cache, p_font_rid); +} + +void TextServerExtension::font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) { + GDVIRTUAL_CALL(_font_remove_size_cache, p_font_rid, p_size); +} + +void TextServerExtension::font_set_ascent(RID p_font_rid, int p_size, float p_ascent) { + GDVIRTUAL_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent); +} + +float TextServerExtension::font_get_ascent(RID p_font_rid, int p_size) const { + float ret; + if (GDVIRTUAL_CALL(_font_get_ascent, p_font_rid, p_size, ret)) { + return ret; + } + return 0.f; +} + +void TextServerExtension::font_set_descent(RID p_font_rid, int p_size, float p_descent) { + GDVIRTUAL_CALL(_font_set_descent, p_font_rid, p_size, p_descent); +} + +float TextServerExtension::font_get_descent(RID p_font_rid, int p_size) const { + float ret; + if (GDVIRTUAL_CALL(_font_get_descent, p_font_rid, p_size, ret)) { + return ret; + } + return 0.f; +} + +void TextServerExtension::font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) { + GDVIRTUAL_CALL(_font_set_underline_position, p_font_rid, p_size, p_underline_position); +} + +float TextServerExtension::font_get_underline_position(RID p_font_rid, int p_size) const { + float ret; + if (GDVIRTUAL_CALL(_font_get_underline_position, p_font_rid, p_size, ret)) { + return ret; + } + return 0.f; +} + +void TextServerExtension::font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) { + GDVIRTUAL_CALL(_font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness); +} + +float TextServerExtension::font_get_underline_thickness(RID p_font_rid, int p_size) const { + float ret; + if (GDVIRTUAL_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret)) { + return ret; + } + return 0.f; +} + +void TextServerExtension::font_set_scale(RID p_font_rid, int p_size, float p_scale) { + GDVIRTUAL_CALL(_font_set_scale, p_font_rid, p_size, p_scale); +} + +float TextServerExtension::font_get_scale(RID p_font_rid, int p_size) const { + float ret; + if (GDVIRTUAL_CALL(_font_get_scale, p_font_rid, p_size, ret)) { + return ret; + } + return 0.f; +} + +void TextServerExtension::font_set_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing, int p_value) { + GDVIRTUAL_CALL(_font_set_spacing, p_font_rid, p_size, p_spacing, p_value); +} + +int TextServerExtension::font_get_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing) const { + int ret; + if (GDVIRTUAL_CALL(_font_get_spacing, p_font_rid, p_size, p_spacing, ret)) { + return ret; + } + return 0; +} + +int TextServerExtension::font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const { + int ret; + if (GDVIRTUAL_CALL(_font_get_texture_count, p_font_rid, p_size, ret)) { + return ret; + } + return 0; +} + +void TextServerExtension::font_clear_textures(RID p_font_rid, const Vector2i &p_size) { + GDVIRTUAL_CALL(_font_clear_textures, p_font_rid, p_size); +} + +void TextServerExtension::font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) { + GDVIRTUAL_CALL(_font_remove_texture, p_font_rid, p_size, p_texture_index); +} + +void TextServerExtension::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { + GDVIRTUAL_CALL(_font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image); +} + +Ref<Image> TextServerExtension::font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { + Ref<Image> ret; + if (GDVIRTUAL_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret)) { + return ret; + } + return Ref<Image>(); +} + +void TextServerExtension::font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) { + GDVIRTUAL_CALL(_font_set_texture_offsets, p_font_rid, p_size, p_texture_index, p_offset); +} + +PackedInt32Array TextServerExtension::font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { + PackedInt32Array ret; + if (GDVIRTUAL_CALL(_font_get_texture_offsets, p_font_rid, p_size, p_texture_index, ret)) { + return ret; + } + return PackedInt32Array(); +} + +Array TextServerExtension::font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const { + Array ret; + if (GDVIRTUAL_CALL(_font_get_glyph_list, p_font_rid, p_size, ret)) { + return ret; + } + return Array(); +} + +void TextServerExtension::font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) { + GDVIRTUAL_CALL(_font_clear_glyphs, p_font_rid, p_size); +} + +void TextServerExtension::font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) { + GDVIRTUAL_CALL(_font_remove_glyph, p_font_rid, p_size, p_glyph); +} + +Vector2 TextServerExtension::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const { + Vector2 ret; + if (GDVIRTUAL_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret)) { + return ret; + } + return Vector2(); +} + +void TextServerExtension::font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) { + GDVIRTUAL_CALL(_font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance); +} + +Vector2 TextServerExtension::font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { + Vector2 ret; + if (GDVIRTUAL_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret)) { + return ret; + } + return Vector2(); +} + +void TextServerExtension::font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) { + GDVIRTUAL_CALL(_font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset); +} + +Vector2 TextServerExtension::font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { + Vector2 ret; + if (GDVIRTUAL_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret)) { + return ret; + } + return Vector2(); +} + +void TextServerExtension::font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) { + GDVIRTUAL_CALL(_font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size); +} + +Rect2 TextServerExtension::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { + Rect2 ret; + if (GDVIRTUAL_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret)) { + return ret; + } + return Rect2(); +} + +void TextServerExtension::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) { + GDVIRTUAL_CALL(_font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect); +} + +int TextServerExtension::font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { + int ret; + if (GDVIRTUAL_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret)) { + return ret; + } + return 0; +} + +void TextServerExtension::font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) { + GDVIRTUAL_CALL(_font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx); +} + +Dictionary TextServerExtension::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index) const { + Dictionary ret; + if (GDVIRTUAL_CALL(_font_get_glyph_contours, p_font_rid, p_size, p_index, ret)) { + return ret; + } + return Dictionary(); +} + +Array TextServerExtension::font_get_kerning_list(RID p_font_rid, int p_size) const { + Array ret; + if (GDVIRTUAL_CALL(_font_get_kerning_list, p_font_rid, p_size, ret)) { + return ret; + } + return Array(); +} + +void TextServerExtension::font_clear_kerning_map(RID p_font_rid, int p_size) { + GDVIRTUAL_CALL(_font_clear_kerning_map, p_font_rid, p_size); +} + +void TextServerExtension::font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) { + GDVIRTUAL_CALL(_font_remove_kerning, p_font_rid, p_size, p_glyph_pair); +} + +void TextServerExtension::font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) { + GDVIRTUAL_CALL(_font_set_kerning, p_font_rid, p_size, p_glyph_pair, p_kerning); +} + +Vector2 TextServerExtension::font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const { + Vector2 ret; + if (GDVIRTUAL_CALL(_font_get_kerning, p_font_rid, p_size, p_glyph_pair, ret)) { + return ret; + } + return Vector2(); +} + +int32_t TextServerExtension::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const { + int32_t ret; + if (GDVIRTUAL_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret)) { + return ret; + } + return 0; +} + +bool TextServerExtension::font_has_char(RID p_font_rid, char32_t p_char) const { + bool ret; + if (GDVIRTUAL_CALL(_font_has_char, p_font_rid, p_char, ret)) { + return ret; + } + return false; +} + +String TextServerExtension::font_get_supported_chars(RID p_font_rid) const { + String ret; + if (GDVIRTUAL_CALL(_font_get_supported_chars, p_font_rid, ret)) { + return ret; + } + return String(); +} + +void TextServerExtension::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) { + GDVIRTUAL_CALL(_font_render_range, p_font_rid, p_size, p_start, p_end); +} + +void TextServerExtension::font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) { + GDVIRTUAL_CALL(_font_render_glyph, p_font_rid, p_size, p_index); +} + +void TextServerExtension::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { + GDVIRTUAL_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color); +} + +void TextServerExtension::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { + GDVIRTUAL_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color); +} + +bool TextServerExtension::font_is_language_supported(RID p_font_rid, const String &p_language) const { + bool ret; + if (GDVIRTUAL_CALL(_font_is_language_supported, p_font_rid, p_language, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) { + GDVIRTUAL_CALL(_font_set_language_support_override, p_font_rid, p_language, p_supported); +} + +bool TextServerExtension::font_get_language_support_override(RID p_font_rid, const String &p_language) { + bool ret; + if (GDVIRTUAL_CALL(_font_get_language_support_override, p_font_rid, p_language, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::font_remove_language_support_override(RID p_font_rid, const String &p_language) { + GDVIRTUAL_CALL(_font_remove_language_support_override, p_font_rid, p_language); +} + +Vector<String> TextServerExtension::font_get_language_support_overrides(RID p_font_rid) { + Vector<String> ret; + if (GDVIRTUAL_CALL(_font_get_language_support_overrides, p_font_rid, ret)) { + return ret; + } + return Vector<String>(); +} + +bool TextServerExtension::font_is_script_supported(RID p_font_rid, const String &p_script) const { + bool ret; + if (GDVIRTUAL_CALL(_font_is_script_supported, p_font_rid, p_script, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) { + GDVIRTUAL_CALL(_font_set_script_support_override, p_font_rid, p_script, p_supported); +} + +bool TextServerExtension::font_get_script_support_override(RID p_font_rid, const String &p_script) { + bool ret; + if (GDVIRTUAL_CALL(_font_get_script_support_override, p_font_rid, p_script, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::font_remove_script_support_override(RID p_font_rid, const String &p_script) { + GDVIRTUAL_CALL(_font_remove_script_support_override, p_font_rid, p_script); +} + +Vector<String> TextServerExtension::font_get_script_support_overrides(RID p_font_rid) { + Vector<String> ret; + if (GDVIRTUAL_CALL(_font_get_script_support_overrides, p_font_rid, ret)) { + return ret; + } + return Vector<String>(); +} + +Dictionary TextServerExtension::font_supported_feature_list(RID p_font_rid) const { + Dictionary ret; + if (GDVIRTUAL_CALL(_font_supported_feature_list, p_font_rid, ret)) { + return ret; + } + return Dictionary(); +} + +Dictionary TextServerExtension::font_supported_variation_list(RID p_font_rid) const { + Dictionary ret; + if (GDVIRTUAL_CALL(_font_supported_variation_list, p_font_rid, ret)) { + return ret; + } + return Dictionary(); +} + +float TextServerExtension::font_get_global_oversampling() const { + float ret; + if (GDVIRTUAL_CALL(_font_get_global_oversampling, ret)) { + return ret; + } + return 0.f; +} + +void TextServerExtension::font_set_global_oversampling(float p_oversampling) { + GDVIRTUAL_CALL(_font_set_global_oversampling, p_oversampling); +} + +Vector2 TextServerExtension::get_hex_code_box_size(int p_size, char32_t p_index) const { + Vector2 ret; + if (GDVIRTUAL_CALL(_get_hex_code_box_size, p_size, p_index, ret)) { + return ret; + } + return TextServer::get_hex_code_box_size(p_size, p_index); +} + +void TextServerExtension::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const { + if (!GDVIRTUAL_CALL(_draw_hex_code_box, p_canvas, p_size, p_pos, p_index, p_color)) { + TextServer::draw_hex_code_box(p_canvas, p_size, p_pos, p_index, p_color); + } +} + +/*************************************************************************/ +/* Shaped text buffer interface */ +/*************************************************************************/ + +RID TextServerExtension::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) { + RID ret; + if (GDVIRTUAL_CALL(_create_shaped_text, p_direction, p_orientation, ret)) { + return ret; + } + return RID(); +} + +void TextServerExtension::shaped_text_clear(RID p_shaped) { + GDVIRTUAL_CALL(_shaped_text_clear, p_shaped); +} + +void TextServerExtension::shaped_text_set_direction(RID p_shaped, TextServer::Direction p_direction) { + GDVIRTUAL_CALL(_shaped_text_set_direction, p_shaped, p_direction); +} + +TextServer::Direction TextServerExtension::shaped_text_get_direction(RID p_shaped) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_direction, p_shaped, ret)) { + return (TextServer::Direction)ret; + } + return TextServer::Direction::DIRECTION_AUTO; +} + +void TextServerExtension::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) { + GDVIRTUAL_CALL(_shaped_text_set_orientation, p_shaped, p_orientation); +} + +TextServer::Orientation TextServerExtension::shaped_text_get_orientation(RID p_shaped) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_orientation, p_shaped, ret)) { + return (TextServer::Orientation)ret; + } + return TextServer::Orientation::ORIENTATION_HORIZONTAL; +} + +void TextServerExtension::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) { + GDVIRTUAL_CALL(_shaped_text_set_bidi_override, p_shaped, p_override); +} + +void TextServerExtension::shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) { + GDVIRTUAL_CALL(_shaped_text_set_preserve_invalid, p_shaped, p_enabled); +} + +bool TextServerExtension::shaped_text_get_preserve_invalid(RID p_shaped) const { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_get_preserve_invalid, p_shaped, ret)) { + return ret; + } + return false; +} + +void TextServerExtension::shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) { + GDVIRTUAL_CALL(_shaped_text_set_preserve_control, p_shaped, p_enabled); +} + +bool TextServerExtension::shaped_text_get_preserve_control(RID p_shaped) const { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_get_preserve_control, p_shaped, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { + bool ret; + Array fonts; + for (int i = 0; i < p_fonts.size(); i++) { + fonts.push_back(p_fonts[i]); + } + if (GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, fonts, p_size, p_opentype_features, p_language, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, ret)) { + return ret; + } + return false; +} + +RID TextServerExtension::shaped_text_substr(RID p_shaped, int p_start, int p_length) const { + RID ret; + if (GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret)) { + return ret; + } + return RID(); +} + +RID TextServerExtension::shaped_text_get_parent(RID p_shaped) const { + RID ret; + if (GDVIRTUAL_CALL(_shaped_text_get_parent, p_shaped, ret)) { + return ret; + } + return RID(); +} + +float TextServerExtension::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t p_jst_flags) { + float ret; + if (GDVIRTUAL_CALL(_shaped_text_fit_to_width, p_shaped, p_width, p_jst_flags, ret)) { + return ret; + } + return 0.f; +} + +float TextServerExtension::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) { + float ret; + if (GDVIRTUAL_CALL(_shaped_text_tab_align, p_shaped, p_tab_stops, ret)) { + return ret; + } + return 0.f; +} + +bool TextServerExtension::shaped_text_shape(RID p_shaped) { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_shape, p_shaped, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::shaped_text_update_breaks(RID p_shaped) { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_update_breaks, p_shaped, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::shaped_text_update_justification_ops(RID p_shaped) { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_update_justification_ops, p_shaped, ret)) { + return ret; + } + return false; +} + +bool TextServerExtension::shaped_text_is_ready(RID p_shaped) const { + bool ret; + if (GDVIRTUAL_CALL(_shaped_text_is_ready, p_shaped, ret)) { + return ret; + } + return false; +} + +const Glyph *TextServerExtension::shaped_text_get_glyphs(RID p_shaped) const { + const Glyph *ret; + if (GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, &ret)) { + return ret; + } + return nullptr; +} + +const Glyph *TextServerExtension::shaped_text_sort_logical(RID p_shaped) { + const Glyph *ret; + if (GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, &ret)) { + return ret; + } + return nullptr; +} + +int TextServerExtension::shaped_text_get_glyph_count(RID p_shaped) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_glyph_count, p_shaped, ret)) { + return ret; + } + return 0; +} + +Vector2i TextServerExtension::shaped_text_get_range(RID p_shaped) const { + Vector2i ret; + if (GDVIRTUAL_CALL(_shaped_text_get_range, p_shaped, ret)) { + return ret; + } + return Vector2i(); +} + +PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint16_t p_break_flags) const { + PackedInt32Array ret; + if (GDVIRTUAL_CALL(_shaped_text_get_line_breaks_adv, p_shaped, p_width, p_start, p_once, p_break_flags, ret)) { + return ret; + } + return TextServer::shaped_text_get_line_breaks_adv(p_shaped, p_width, p_start, p_once, p_break_flags); +} + +PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start, uint16_t p_break_flags) const { + PackedInt32Array ret; + if (GDVIRTUAL_CALL(_shaped_text_get_line_breaks, p_shaped, p_width, p_start, p_break_flags, ret)) { + return ret; + } + return TextServer::shaped_text_get_line_breaks(p_shaped, p_width, p_start, p_break_flags); +} + +PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { + PackedInt32Array ret; + if (GDVIRTUAL_CALL(_shaped_text_get_word_breaks, p_shaped, p_grapheme_flags, ret)) { + return ret; + } + return TextServer::shaped_text_get_word_breaks(p_shaped, p_grapheme_flags); +} + +int TextServerExtension::shaped_text_get_trim_pos(RID p_shaped) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_trim_pos, p_shaped, ret)) { + return ret; + } + return -1; +} + +int TextServerExtension::shaped_text_get_ellipsis_pos(RID p_shaped) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret)) { + return ret; + } + return -1; +} + +const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(RID p_shaped) const { + const Glyph *ret; + if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, &ret)) { + return ret; + } + return nullptr; +} + +int TextServerExtension::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret)) { + return ret; + } + return -1; +} + +void TextServerExtension::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) { + GDVIRTUAL_CALL(_shaped_text_overrun_trim_to_width, p_shaped_line, p_width, p_trim_flags); +} + +Array TextServerExtension::shaped_text_get_objects(RID p_shaped) const { + Array ret; + if (GDVIRTUAL_CALL(_shaped_text_get_objects, p_shaped, ret)) { + return ret; + } + return Array(); +} + +Rect2 TextServerExtension::shaped_text_get_object_rect(RID p_shaped, Variant p_key) const { + Rect2 ret; + if (GDVIRTUAL_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret)) { + return ret; + } + return Rect2(); +} + +Size2 TextServerExtension::shaped_text_get_size(RID p_shaped) const { + Size2 ret; + if (GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret)) { + return ret; + } + return Size2(); +} + +float TextServerExtension::shaped_text_get_ascent(RID p_shaped) const { + float ret; + if (GDVIRTUAL_CALL(_shaped_text_get_ascent, p_shaped, ret)) { + return ret; + } + return 0.f; +} + +float TextServerExtension::shaped_text_get_descent(RID p_shaped) const { + float ret; + if (GDVIRTUAL_CALL(_shaped_text_get_descent, p_shaped, ret)) { + return ret; + } + return 0.f; +} + +float TextServerExtension::shaped_text_get_width(RID p_shaped) const { + float ret; + if (GDVIRTUAL_CALL(_shaped_text_get_width, p_shaped, ret)) { + return ret; + } + return 0.f; +} + +float TextServerExtension::shaped_text_get_underline_position(RID p_shaped) const { + float ret; + if (GDVIRTUAL_CALL(_shaped_text_get_underline_position, p_shaped, ret)) { + return ret; + } + return 0.f; +} + +float TextServerExtension::shaped_text_get_underline_thickness(RID p_shaped) const { + float ret; + if (GDVIRTUAL_CALL(_shaped_text_get_underline_thickness, p_shaped, ret)) { + return ret; + } + return 0.f; +} + +TextServer::Direction TextServerExtension::shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_get_dominant_direction_in_range, p_shaped, p_start, p_end, ret)) { + return (TextServer::Direction)ret; + } + return TextServer::shaped_text_get_dominant_direction_in_range(p_shaped, p_start, p_end); +} + +CaretInfo TextServerExtension::shaped_text_get_carets(RID p_shaped, int p_position) const { + CaretInfo ret; + if (GDVIRTUAL_CALL(_shaped_text_get_carets, p_shaped, p_position, &ret)) { + return ret; + } + return TextServer::shaped_text_get_carets(p_shaped, p_position); +} + +Vector<Vector2> TextServerExtension::shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const { + Vector<Vector2> ret; + if (GDVIRTUAL_CALL(_shaped_text_get_selection, p_shaped, p_start, p_end, ret)) { + return ret; + } + return TextServer::shaped_text_get_selection(p_shaped, p_start, p_end); +} + +int TextServerExtension::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_hit_test_grapheme, p_shaped, p_coords, ret)) { + return ret; + } + return TextServer::shaped_text_hit_test_grapheme(p_shaped, p_coords); +} + +int TextServerExtension::shaped_text_hit_test_position(RID p_shaped, float p_coords) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_hit_test_position, p_shaped, p_coords, ret)) { + return ret; + } + return TextServer::shaped_text_hit_test_position(p_shaped, p_coords); +} + +void TextServerExtension::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, const Color &p_color) const { + if (GDVIRTUAL_CALL(_shaped_text_draw, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color)) { + return; + } + TextServer::shaped_text_draw(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color); +} + +void TextServerExtension::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const { + if (GDVIRTUAL_CALL(_shaped_text_draw_outline, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color)) { + return; + } + shaped_text_draw_outline(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color); +} + +int TextServerExtension::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_next_grapheme_pos, p_shaped, p_pos, ret)) { + return ret; + } + return TextServer::shaped_text_next_grapheme_pos(p_shaped, p_pos); +} + +int TextServerExtension::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const { + int ret; + if (GDVIRTUAL_CALL(_shaped_text_prev_grapheme_pos, p_shaped, p_pos, ret)) { + return ret; + } + return TextServer::shaped_text_prev_grapheme_pos(p_shaped, p_pos); +} + +String TextServerExtension::format_number(const String &p_string, const String &p_language) const { + String ret; + if (GDVIRTUAL_CALL(_format_number, p_string, p_language, ret)) { + return ret; + } + return TextServer::format_number(p_string, p_language); +} + +String TextServerExtension::parse_number(const String &p_string, const String &p_language) const { + String ret; + if (GDVIRTUAL_CALL(_parse_number, p_string, p_language, ret)) { + return ret; + } + return TextServer::parse_number(p_string, p_language); +} + +String TextServerExtension::percent_sign(const String &p_language) const { + String ret; + if (GDVIRTUAL_CALL(_percent_sign, p_language, ret)) { + return ret; + } + return TextServer::percent_sign(p_language); +} + +TextServerExtension::TextServerExtension() { + //NOP +} + +TextServerExtension::~TextServerExtension() { + //NOP +} diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h new file mode 100644 index 0000000000..88a8c0cb0c --- /dev/null +++ b/servers/text/text_server_extension.h @@ -0,0 +1,426 @@ +/*************************************************************************/ +/* text_server_extension.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEXT_SERVER_EXTENSION_H +#define TEXT_SERVER_EXTENSION_H + +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" +#include "servers/text_server.h" + +class TextServerExtension : public TextServer { + GDCLASS(TextServerExtension, TextServer); + +protected: + _THREAD_SAFE_CLASS_ + + static void _bind_methods(); + +public: + virtual bool has_feature(Feature p_feature) const override; + virtual String get_name() const override; + virtual uint32_t get_features() const override; + GDVIRTUAL1RC(bool, _has_feature, Feature); + GDVIRTUAL0RC(String, _get_name); + GDVIRTUAL0RC(uint32_t, _get_features); + + virtual void free(RID p_rid) override; + virtual bool has(RID p_rid) override; + virtual bool load_support_data(const String &p_filename) override; + GDVIRTUAL1(_free, RID); + GDVIRTUAL1R(bool, _has, RID); + GDVIRTUAL1R(bool, _load_support_data, const String &); + + virtual String get_support_data_filename() const override; + virtual String get_support_data_info() const override; + virtual bool save_support_data(const String &p_filename) const override; + GDVIRTUAL0RC(String, _get_support_data_filename); + GDVIRTUAL0RC(String, _get_support_data_info); + GDVIRTUAL1RC(bool, _save_support_data, const String &); + + virtual bool is_locale_right_to_left(const String &p_locale) const override; + GDVIRTUAL1RC(bool, _is_locale_right_to_left, const String &); + + virtual int32_t name_to_tag(const String &p_name) const override; + virtual String tag_to_name(int32_t p_tag) const override; + GDVIRTUAL1RC(int32_t, _name_to_tag, const String &); + GDVIRTUAL1RC(String, _tag_to_name, int32_t); + + /* Font interface */ + virtual RID create_font() override; + GDVIRTUAL0R(RID, _create_font); + + virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override; + virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override; + GDVIRTUAL2(_font_set_data, RID, const PackedByteArray &); + GDVIRTUAL3(_font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, uint64_t); + + virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override; + virtual bool font_is_antialiased(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_antialiased, RID, bool); + GDVIRTUAL1RC(bool, _font_is_antialiased, RID); + + virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) override; + virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_multichannel_signed_distance_field, RID, bool); + GDVIRTUAL1RC(bool, _font_is_multichannel_signed_distance_field, RID); + + virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) override; + virtual int font_get_msdf_pixel_range(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_msdf_pixel_range, RID, int); + GDVIRTUAL1RC(int, _font_get_msdf_pixel_range, RID); + + virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) override; + virtual int font_get_msdf_size(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_msdf_size, RID, int); + GDVIRTUAL1RC(int, _font_get_msdf_size, RID); + + virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) override; + virtual int font_get_fixed_size(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_fixed_size, RID, int); + GDVIRTUAL1RC(int, _font_get_fixed_size, RID); + + virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) override; + virtual bool font_is_force_autohinter(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_force_autohinter, RID, bool); + GDVIRTUAL1RC(bool, _font_is_force_autohinter, RID); + + virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) override; + virtual Hinting font_get_hinting(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_hinting, RID, Hinting); + GDVIRTUAL1RC(/*Hinting*/ int, _font_get_hinting, RID); + + virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; + virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_variation_coordinates, RID, Dictionary); + GDVIRTUAL1RC(Dictionary, _font_get_variation_coordinates, RID); + + virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override; + virtual float font_get_oversampling(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_oversampling, RID, float); + GDVIRTUAL1RC(float, _font_get_oversampling, RID); + + virtual Array font_get_size_cache_list(RID p_font_rid) const override; + virtual void font_clear_size_cache(RID p_font_rid) override; + virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override; + GDVIRTUAL1RC(Array, _font_get_size_cache_list, RID); + GDVIRTUAL1(_font_clear_size_cache, RID); + GDVIRTUAL2(_font_remove_size_cache, RID, const Vector2i &); + + virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override; + virtual float font_get_ascent(RID p_font_rid, int p_size) const override; + GDVIRTUAL3(_font_set_ascent, RID, int, float); + GDVIRTUAL2RC(float, _font_get_ascent, RID, int); + + virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override; + virtual float font_get_descent(RID p_font_rid, int p_size) const override; + GDVIRTUAL3(_font_set_descent, RID, int, float); + GDVIRTUAL2RC(float, _font_get_descent, RID, int); + + virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override; + virtual float font_get_underline_position(RID p_font_rid, int p_size) const override; + GDVIRTUAL3(_font_set_underline_position, RID, int, float); + GDVIRTUAL2RC(float, _font_get_underline_position, RID, int); + + virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override; + virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override; + GDVIRTUAL3(_font_set_underline_thickness, RID, int, float); + GDVIRTUAL2RC(float, _font_get_underline_thickness, RID, int); + + virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override; + virtual float font_get_scale(RID p_font_rid, int p_size) const override; + GDVIRTUAL3(_font_set_scale, RID, int, float); + GDVIRTUAL2RC(float, _font_get_scale, RID, int); + + virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override; + virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override; + GDVIRTUAL4(_font_set_spacing, RID, int, SpacingType, int); + GDVIRTUAL3RC(int, _font_get_spacing, RID, int, SpacingType); + + virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const override; + virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) override; + virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) override; + GDVIRTUAL2RC(int, _font_get_texture_count, RID, const Vector2i &); + GDVIRTUAL2(_font_clear_textures, RID, const Vector2i &); + GDVIRTUAL3(_font_remove_texture, RID, const Vector2i &, int); + + virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) override; + virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override; + GDVIRTUAL4(_font_set_texture_image, RID, const Vector2i &, int, const Ref<Image> &); + GDVIRTUAL3RC(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int); + + virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) override; + virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override; + GDVIRTUAL4(_font_set_texture_offsets, RID, const Vector2i &, int, const PackedInt32Array &); + GDVIRTUAL3RC(PackedInt32Array, _font_get_texture_offsets, RID, const Vector2i &, int); + + virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const override; + virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) override; + virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) override; + GDVIRTUAL2RC(Array, _font_get_glyph_list, RID, const Vector2i &); + GDVIRTUAL2(_font_clear_glyphs, RID, const Vector2i &); + GDVIRTUAL3(_font_remove_glyph, RID, const Vector2i &, int32_t); + + virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const override; + virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) override; + GDVIRTUAL3RC(Vector2, _font_get_glyph_advance, RID, int, int32_t); + GDVIRTUAL4(_font_set_glyph_advance, RID, int, int32_t, const Vector2 &); + + virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; + virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) override; + GDVIRTUAL3RC(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int32_t); + GDVIRTUAL4(_font_set_glyph_offset, RID, const Vector2i &, int32_t, const Vector2 &); + + virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; + virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) override; + GDVIRTUAL3RC(Vector2, _font_get_glyph_size, RID, const Vector2i &, int32_t); + GDVIRTUAL4(_font_set_glyph_size, RID, const Vector2i &, int32_t, const Vector2 &); + + virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; + virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) override; + GDVIRTUAL3RC(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int32_t); + GDVIRTUAL4(_font_set_glyph_uv_rect, RID, const Vector2i &, int32_t, const Rect2 &); + + virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; + virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override; + GDVIRTUAL3RC(int, _font_get_glyph_texture_idx, RID, const Vector2i &, int32_t); + GDVIRTUAL4(_font_set_glyph_texture_idx, RID, const Vector2i &, int32_t, int); + + virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override; + GDVIRTUAL3RC(Dictionary, _font_get_glyph_contours, RID, int, int32_t); + + virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override; + virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override; + virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) override; + GDVIRTUAL2RC(Array, _font_get_kerning_list, RID, int); + GDVIRTUAL2(_font_clear_kerning_map, RID, int); + GDVIRTUAL3(_font_remove_kerning, RID, int, const Vector2i &); + + virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override; + virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const override; + GDVIRTUAL4(_font_set_kerning, RID, int, const Vector2i &, const Vector2 &); + GDVIRTUAL3RC(Vector2, _font_get_kerning, RID, int, const Vector2i &); + + virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector = 0) const override; + GDVIRTUAL4RC(int32_t, _font_get_glyph_index, RID, int, char32_t, char32_t); + + virtual bool font_has_char(RID p_font_rid, char32_t p_char) const override; + virtual String font_get_supported_chars(RID p_font_rid) const override; + GDVIRTUAL2RC(bool, _font_has_char, RID, char32_t); + GDVIRTUAL1RC(String, _font_get_supported_chars, RID); + + virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) override; + virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) override; + GDVIRTUAL4(_font_render_range, RID, const Vector2i &, char32_t, char32_t); + GDVIRTUAL3(_font_render_glyph, RID, const Vector2i &, int32_t); + + virtual void font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override; + virtual void font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override; + GDVIRTUAL6C(_font_draw_glyph, RID, RID, int, const Vector2 &, int32_t, const Color &); + GDVIRTUAL7C(_font_draw_glyph_outline, RID, RID, int, int, const Vector2 &, int32_t, const Color &); + + virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const override; + virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) override; + virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) override; + virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) override; + virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) override; + GDVIRTUAL2RC(bool, _font_is_language_supported, RID, const String &); + GDVIRTUAL3(_font_set_language_support_override, RID, const String &, bool); + GDVIRTUAL2R(bool, _font_get_language_support_override, RID, const String &); + GDVIRTUAL2(_font_remove_language_support_override, RID, const String &); + GDVIRTUAL1R(Vector<String>, _font_get_language_support_overrides, RID); + + virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const override; + virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) override; + virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) override; + virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override; + virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override; + GDVIRTUAL2RC(bool, _font_is_script_supported, RID, const String &); + GDVIRTUAL3(_font_set_script_support_override, RID, const String &, bool); + GDVIRTUAL2R(bool, _font_get_script_support_override, RID, const String &); + GDVIRTUAL2(_font_remove_script_support_override, RID, const String &); + GDVIRTUAL1R(Vector<String>, _font_get_script_support_overrides, RID); + + virtual Dictionary font_supported_feature_list(RID p_font_rid) const override; + virtual Dictionary font_supported_variation_list(RID p_font_rid) const override; + GDVIRTUAL1RC(Dictionary, _font_supported_feature_list, RID); + GDVIRTUAL1RC(Dictionary, _font_supported_variation_list, RID); + + virtual float font_get_global_oversampling() const override; + virtual void font_set_global_oversampling(float p_oversampling) override; + GDVIRTUAL0RC(float, _font_get_global_oversampling); + GDVIRTUAL1(_font_set_global_oversampling, float); + + virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const override; + virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const override; + GDVIRTUAL2RC(Vector2, _get_hex_code_box_size, int, char32_t); + GDVIRTUAL5C(_draw_hex_code_box, RID, int, const Vector2 &, char32_t, const Color &); + + /* Shaped text buffer interface */ + + virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; + GDVIRTUAL2R(RID, _create_shaped_text, Direction, Orientation); + + virtual void shaped_text_clear(RID p_shaped) override; + GDVIRTUAL1(_shaped_text_clear, RID); + + virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; + virtual Direction shaped_text_get_direction(RID p_shaped) const override; + GDVIRTUAL2(_shaped_text_set_direction, RID, Direction); + GDVIRTUAL1RC(/*Direction*/ int, _shaped_text_get_direction, RID); + + virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; + GDVIRTUAL2(_shaped_text_set_bidi_override, RID, const Array &); + + virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; + virtual Orientation shaped_text_get_orientation(RID p_shaped) const override; + GDVIRTUAL2(_shaped_text_set_orientation, RID, Orientation); + GDVIRTUAL1RC(/*Orientation*/ int, _shaped_text_get_orientation, RID); + + virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) override; + virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const override; + GDVIRTUAL2(_shaped_text_set_preserve_invalid, RID, bool); + GDVIRTUAL1RC(bool, _shaped_text_get_preserve_invalid, RID); + + virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override; + virtual bool shaped_text_get_preserve_control(RID p_shaped) const override; + GDVIRTUAL2(_shaped_text_set_preserve_control, RID, bool); + GDVIRTUAL1RC(bool, _shaped_text_get_preserve_control, RID); + + virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override; + virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override; + virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override; + GDVIRTUAL6R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &); + GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlign, int); + GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlign); + + virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override; + virtual RID shaped_text_get_parent(RID p_shaped) const override; + GDVIRTUAL3RC(RID, _shaped_text_substr, RID, int, int); + GDVIRTUAL1RC(RID, _shaped_text_get_parent, RID); + + virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; + virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override; + GDVIRTUAL3R(float, _shaped_text_fit_to_width, RID, float, uint16_t); + GDVIRTUAL2R(float, _shaped_text_tab_align, RID, const PackedFloat32Array &); + + virtual bool shaped_text_shape(RID p_shaped) override; + virtual bool shaped_text_update_breaks(RID p_shaped) override; + virtual bool shaped_text_update_justification_ops(RID p_shaped) override; + GDVIRTUAL1R(bool, _shaped_text_shape, RID); + GDVIRTUAL1R(bool, _shaped_text_update_breaks, RID); + GDVIRTUAL1R(bool, _shaped_text_update_justification_ops, RID); + + virtual bool shaped_text_is_ready(RID p_shaped) const override; + GDVIRTUAL1RC(bool, _shaped_text_is_ready, RID); + + virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override; + virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override; + virtual int shaped_text_get_glyph_count(RID p_shaped) const override; + GDVIRTUAL2C(_shaped_text_get_glyphs, RID, GDNativePtr<const Glyph *>); + GDVIRTUAL2(_shaped_text_sort_logical, RID, GDNativePtr<const Glyph *>); + GDVIRTUAL1RC(int, _shaped_text_get_glyph_count, RID); + + virtual Vector2i shaped_text_get_range(RID p_shaped) const override; + GDVIRTUAL1RC(Vector2i, _shaped_text_get_range, RID); + + virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; + virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; + virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override; + GDVIRTUAL5RC(PackedInt32Array, _shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int, bool, uint16_t); + GDVIRTUAL4RC(PackedInt32Array, _shaped_text_get_line_breaks, RID, float, int, uint16_t); + GDVIRTUAL2RC(PackedInt32Array, _shaped_text_get_word_breaks, RID, int); + + virtual int shaped_text_get_trim_pos(RID p_shaped) const override; + virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override; + virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override; + virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override; + GDVIRTUAL1RC(int, _shaped_text_get_trim_pos, RID); + GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_pos, RID); + GDVIRTUAL2C(_shaped_text_get_ellipsis_glyphs, RID, GDNativePtr<const Glyph *>); + GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_glyph_count, RID); + + virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override; + GDVIRTUAL3(_shaped_text_overrun_trim_to_width, RID, float, uint16_t); + + virtual Array shaped_text_get_objects(RID p_shaped) const override; + virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override; + GDVIRTUAL1RC(Array, _shaped_text_get_objects, RID); + GDVIRTUAL2RC(Rect2, _shaped_text_get_object_rect, RID, Variant); + + virtual Size2 shaped_text_get_size(RID p_shaped) const override; + virtual float shaped_text_get_ascent(RID p_shaped) const override; + virtual float shaped_text_get_descent(RID p_shaped) const override; + virtual float shaped_text_get_width(RID p_shaped) const override; + virtual float shaped_text_get_underline_position(RID p_shaped) const override; + virtual float shaped_text_get_underline_thickness(RID p_shaped) const override; + GDVIRTUAL1RC(Size2, _shaped_text_get_size, RID); + GDVIRTUAL1RC(float, _shaped_text_get_ascent, RID); + GDVIRTUAL1RC(float, _shaped_text_get_descent, RID); + GDVIRTUAL1RC(float, _shaped_text_get_width, RID); + GDVIRTUAL1RC(float, _shaped_text_get_underline_position, RID); + GDVIRTUAL1RC(float, _shaped_text_get_underline_thickness, RID); + + virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const override; + GDVIRTUAL3RC(int, _shaped_text_get_dominant_direction_in_range, RID, int, int); + + virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const override; + virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const override; + GDVIRTUAL3C(_shaped_text_get_carets, RID, int, GDNativePtr<CaretInfo>); + GDVIRTUAL3RC(Vector<Vector2>, _shaped_text_get_selection, RID, int, int); + + virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const override; + virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const override; + GDVIRTUAL2RC(int, _shaped_text_hit_test_grapheme, RID, float); + GDVIRTUAL2RC(int, _shaped_text_hit_test_position, RID, float); + + virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const override; + virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const override; + GDVIRTUAL6C(_shaped_text_draw, RID, RID, const Vector2 &, float, float, const Color &); + GDVIRTUAL7C(_shaped_text_draw_outline, RID, RID, const Vector2 &, float, float, int, const Color &); + + virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const override; + virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const override; + GDVIRTUAL2RC(int, _shaped_text_next_grapheme_pos, RID, int); + GDVIRTUAL2RC(int, _shaped_text_prev_grapheme_pos, RID, int); + + virtual String format_number(const String &p_string, const String &p_language = "") const override; + virtual String parse_number(const String &p_string, const String &p_language = "") const override; + virtual String percent_sign(const String &p_language = "") const override; + GDVIRTUAL2RC(String, _format_number, const String &, const String &); + GDVIRTUAL2RC(String, _parse_number, const String &, const String &); + GDVIRTUAL1RC(String, _percent_sign, const String &); + + TextServerExtension(); + ~TextServerExtension(); +}; + +#endif // TEXT_SERVER_EXTENSION_H diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 4886a6f582..a365fde64a 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -32,122 +32,108 @@ #include "scene/main/canvas_item.h" TextServerManager *TextServerManager::singleton = nullptr; -TextServer *TextServerManager::server = nullptr; -TextServerManager::TextServerCreate TextServerManager::server_create_functions[TextServerManager::MAX_SERVERS]; -int TextServerManager::server_create_count = 0; void TextServerManager::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_interface_count"), &TextServerManager::_get_interface_count); - ClassDB::bind_method(D_METHOD("get_interface_name", "index"), &TextServerManager::_get_interface_name); - ClassDB::bind_method(D_METHOD("get_interface_features", "index"), &TextServerManager::_get_interface_features); - ClassDB::bind_method(D_METHOD("get_interface", "index"), &TextServerManager::_get_interface); - ClassDB::bind_method(D_METHOD("get_interfaces"), &TextServerManager::_get_interfaces); - ClassDB::bind_method(D_METHOD("find_interface", "name"), &TextServerManager::_find_interface); - - ClassDB::bind_method(D_METHOD("set_primary_interface", "index"), &TextServerManager::_set_primary_interface); + ClassDB::bind_method(D_METHOD("add_interface", "interface"), &TextServerManager::add_interface); + ClassDB::bind_method(D_METHOD("get_interface_count"), &TextServerManager::get_interface_count); + ClassDB::bind_method(D_METHOD("remove_interface", "interface"), &TextServerManager::remove_interface); + ClassDB::bind_method(D_METHOD("get_interface", "idx"), &TextServerManager::get_interface); + ClassDB::bind_method(D_METHOD("get_interfaces"), &TextServerManager::get_interfaces); + ClassDB::bind_method(D_METHOD("find_interface", "name"), &TextServerManager::find_interface); + + ClassDB::bind_method(D_METHOD("set_primary_interface", "index"), &TextServerManager::set_primary_interface); ClassDB::bind_method(D_METHOD("get_primary_interface"), &TextServerManager::_get_primary_interface); -} -void TextServerManager::register_create_function(const String &p_name, uint32_t p_features, TextServerManager::CreateFunction p_function, void *p_user_data) { - ERR_FAIL_COND(server_create_count == MAX_SERVERS); - server_create_functions[server_create_count].name = p_name; - server_create_functions[server_create_count].create_function = p_function; - server_create_functions[server_create_count].user_data = p_user_data; - server_create_functions[server_create_count].features = p_features; - server_create_count++; + ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING_NAME, "interface_name"))); + ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING_NAME, "interface_name"))); } -int TextServerManager::get_interface_count() { - return server_create_count; -} +void TextServerManager::add_interface(const Ref<TextServer> &p_interface) { + ERR_FAIL_COND(p_interface.is_null()); -String TextServerManager::get_interface_name(int p_index) { - ERR_FAIL_INDEX_V(p_index, server_create_count, String()); - return server_create_functions[p_index].name; -} + for (int i = 0; i < interfaces.size(); i++) { + if (interfaces[i] == p_interface) { + ERR_PRINT("TextServer: Interface was already added."); + return; + }; + }; -uint32_t TextServerManager::get_interface_features(int p_index) { - ERR_FAIL_INDEX_V(p_index, server_create_count, 0); - return server_create_functions[p_index].features; + interfaces.push_back(p_interface); + print_verbose("TextServer: Added interface \"" + p_interface->get_name() + "\""); + emit_signal(SNAME("interface_added"), p_interface->get_name()); } -TextServer *TextServerManager::initialize(int p_index, Error &r_error) { - ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr); - if (server_create_functions[p_index].instance == nullptr) { - server_create_functions[p_index].instance = server_create_functions[p_index].create_function(r_error, server_create_functions[p_index].user_data); - if (server_create_functions[p_index].instance != nullptr) { - server_create_functions[p_index].instance->load_support_data(""); // Try loading default data. - } - } - if (server_create_functions[p_index].instance != nullptr) { - server = server_create_functions[p_index].instance; - if (OS::get_singleton()->get_main_loop()) { - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TEXT_SERVER_CHANGED); - } - } - return server_create_functions[p_index].instance; -} +void TextServerManager::remove_interface(const Ref<TextServer> &p_interface) { + ERR_FAIL_COND(p_interface.is_null()); + ERR_FAIL_COND_MSG(p_interface == primary_interface, "TextServer: Can't remove primary interface."); -TextServer *TextServerManager::get_primary_interface() { - return server; -} + int idx = -1; + for (int i = 0; i < interfaces.size(); i++) { + if (interfaces[i] == p_interface) { + idx = i; + break; + }; + }; -int TextServerManager::_get_interface_count() const { - return server_create_count; + ERR_FAIL_COND(idx == -1); + print_verbose("TextServer: Removed interface \"" + p_interface->get_name() + "\""); + emit_signal(SNAME("interface_removed"), p_interface->get_name()); + interfaces.remove(idx); } -String TextServerManager::_get_interface_name(int p_index) const { - return get_interface_name(p_index); +int TextServerManager::get_interface_count() const { + return interfaces.size(); } -uint32_t TextServerManager::_get_interface_features(int p_index) const { - return get_interface_features(p_index); +Ref<TextServer> TextServerManager::get_interface(int p_index) const { + ERR_FAIL_INDEX_V(p_index, interfaces.size(), nullptr); + return interfaces[p_index]; } -TextServer *TextServerManager::_get_interface(int p_index) const { - ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr); - if (server_create_functions[p_index].instance == nullptr) { - Error error; - server_create_functions[p_index].instance = server_create_functions[p_index].create_function(error, server_create_functions[p_index].user_data); - if (server_create_functions[p_index].instance != nullptr) { - server_create_functions[p_index].instance->load_support_data(""); // Try loading default data. - } - } - return server_create_functions[p_index].instance; -} +Ref<TextServer> TextServerManager::find_interface(const String &p_name) const { + int idx = -1; + for (int i = 0; i < interfaces.size(); i++) { + if (interfaces[i]->get_name() == p_name) { + idx = i; + break; + }; + }; -TextServer *TextServerManager::_find_interface(const String &p_name) const { - for (int i = 0; i < server_create_count; i++) { - if (server_create_functions[i].name == p_name) { - return _get_interface(i); - } - } - return nullptr; + ERR_FAIL_COND_V(idx == -1, nullptr); + return interfaces[idx]; } -Array TextServerManager::_get_interfaces() const { +Array TextServerManager::get_interfaces() const { Array ret; - for (int i = 0; i < server_create_count; i++) { + for (int i = 0; i < interfaces.size(); i++) { Dictionary iface_info; iface_info["id"] = i; - iface_info["name"] = server_create_functions[i].name; + iface_info["name"] = interfaces[i]->get_name(); ret.push_back(iface_info); }; return ret; -}; +} -bool TextServerManager::_set_primary_interface(int p_index) { - Error error; - TextServerManager::initialize(p_index, error); - return (error == OK); +Ref<TextServer> TextServerManager::_get_primary_interface() const { + return primary_interface; } -TextServer *TextServerManager::_get_primary_interface() const { - return server; +void TextServerManager::set_primary_interface(const Ref<TextServer> &p_primary_interface) { + if (p_primary_interface.is_null()) { + print_verbose("TextServer: Clearing primary interface"); + primary_interface.unref(); + } else { + primary_interface = p_primary_interface; + print_verbose("TextServer: Primary interface set to: \"" + primary_interface->get_name() + "\"."); + + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TEXT_SERVER_CHANGED); + } + } } TextServerManager::TextServerManager() { @@ -155,29 +141,29 @@ TextServerManager::TextServerManager() { } TextServerManager::~TextServerManager() { - singleton = nullptr; - for (int i = 0; i < server_create_count; i++) { - if (server_create_functions[i].instance != nullptr) { - memdelete(server_create_functions[i].instance); - server_create_functions[i].instance = nullptr; - } + if (primary_interface.is_valid()) { + primary_interface.unref(); } + while (interfaces.size() > 0) { + interfaces.remove(0); + } + singleton = nullptr; } /*************************************************************************/ -bool TextServer::Glyph::operator==(const Glyph &p_a) const { +bool Glyph::operator==(const Glyph &p_a) const { return (p_a.index == index) && (p_a.font_rid == font_rid) && (p_a.font_size == font_size) && (p_a.start == start); } -bool TextServer::Glyph::operator!=(const Glyph &p_a) const { +bool Glyph::operator!=(const Glyph &p_a) const { return (p_a.index != index) || (p_a.font_rid != font_rid) || (p_a.font_size != font_size) || (p_a.start != start); } -bool TextServer::Glyph::operator<(const Glyph &p_a) const { +bool Glyph::operator<(const Glyph &p_a) const { if (p_a.start == start) { if (p_a.count == count) { - if ((p_a.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) { + if ((p_a.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) { return true; } else { return false; @@ -188,10 +174,10 @@ bool TextServer::Glyph::operator<(const Glyph &p_a) const { return p_a.start < start; } -bool TextServer::Glyph::operator>(const Glyph &p_a) const { +bool Glyph::operator>(const Glyph &p_a) const { if (p_a.start == start) { if (p_a.count == count) { - if ((p_a.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) { + if ((p_a.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) { return false; } else { return true; @@ -205,8 +191,13 @@ bool TextServer::Glyph::operator>(const Glyph &p_a) const { void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("has_feature", "feature"), &TextServer::has_feature); ClassDB::bind_method(D_METHOD("get_name"), &TextServer::get_name); + ClassDB::bind_method(D_METHOD("get_features"), &TextServer::get_features); ClassDB::bind_method(D_METHOD("load_support_data", "filename"), &TextServer::load_support_data); + ClassDB::bind_method(D_METHOD("get_support_data_filename"), &TextServer::get_support_data_filename); + ClassDB::bind_method(D_METHOD("get_support_data_info"), &TextServer::get_support_data_info); + ClassDB::bind_method(D_METHOD("save_support_data", "filename"), &TextServer::save_support_data); + ClassDB::bind_method(D_METHOD("is_locale_right_to_left", "locale"), &TextServer::is_locale_right_to_left); ClassDB::bind_method(D_METHOD("name_to_tag", "name"), &TextServer::name_to_tag); @@ -219,7 +210,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("create_font"), &TextServer::create_font); - ClassDB::bind_method(D_METHOD("font_set_data", "data"), &TextServer::font_set_data); + ClassDB::bind_method(D_METHOD("font_set_data", "font_rid", "data"), &TextServer::font_set_data); ClassDB::bind_method(D_METHOD("font_set_antialiased", "font_rid", "antialiased"), &TextServer::font_set_antialiased); ClassDB::bind_method(D_METHOD("font_is_antialiased", "font_rid"), &TextServer::font_is_antialiased); @@ -299,7 +290,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_get_glyph_texture_idx", "font_rid", "size", "glyph"), &TextServer::font_get_glyph_texture_idx); ClassDB::bind_method(D_METHOD("font_set_glyph_texture_idx", "font_rid", "size", "glyph", "texture_idx"), &TextServer::font_set_glyph_texture_idx); - ClassDB::bind_method(D_METHOD("font_get_glyph_contours", "font", "size", "index"), &TextServer::_font_get_glyph_contours); + ClassDB::bind_method(D_METHOD("font_get_glyph_contours", "font", "size", "index"), &TextServer::font_get_glyph_contours); ClassDB::bind_method(D_METHOD("font_get_kerning_list", "font_rid", "size"), &TextServer::font_get_kerning_list); ClassDB::bind_method(D_METHOD("font_clear_kerning_map", "font_rid", "size"), &TextServer::font_clear_kerning_map); @@ -349,7 +340,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shaped_text_set_direction", "shaped", "direction"), &TextServer::shaped_text_set_direction, DEFVAL(DIRECTION_AUTO)); ClassDB::bind_method(D_METHOD("shaped_text_get_direction", "shaped"), &TextServer::shaped_text_get_direction); - ClassDB::bind_method(D_METHOD("shaped_text_set_bidi_override", "shaped", "override"), &TextServer::_shaped_text_set_bidi_override); + ClassDB::bind_method(D_METHOD("shaped_text_set_bidi_override", "shaped", "override"), &TextServer::shaped_text_set_bidi_override); ClassDB::bind_method(D_METHOD("shaped_text_set_orientation", "shaped", "orientation"), &TextServer::shaped_text_set_orientation, DEFVAL(ORIENTATION_HORIZONTAL)); ClassDB::bind_method(D_METHOD("shaped_text_get_orientation", "shaped"), &TextServer::shaped_text_get_orientation); @@ -372,12 +363,19 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shaped_text_shape", "shaped"), &TextServer::shaped_text_shape); ClassDB::bind_method(D_METHOD("shaped_text_is_ready", "shaped"), &TextServer::shaped_text_is_ready); - ClassDB::bind_method(D_METHOD("shaped_text_get_glyphs", "shaped"), &TextServer::_shaped_text_get_glyphs); + ClassDB::bind_method(D_METHOD("shaped_text_get_glyphs", "shaped"), &TextServer::_shaped_text_get_glyphs_wrapper); + ClassDB::bind_method(D_METHOD("shaped_text_sort_logical", "shaped"), &TextServer::_shaped_text_sort_logical_wrapper); + ClassDB::bind_method(D_METHOD("shaped_text_get_glyph_count", "shaped"), &TextServer::shaped_text_get_glyph_count); ClassDB::bind_method(D_METHOD("shaped_text_get_range", "shaped"), &TextServer::shaped_text_get_range); - ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks_adv", "shaped", "width", "start", "once", "break_flags"), &TextServer::_shaped_text_get_line_breaks_adv, DEFVAL(0), DEFVAL(true), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND)); - ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks", "shaped", "width", "start", "break_flags"), &TextServer::_shaped_text_get_line_breaks, DEFVAL(0), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND)); - ClassDB::bind_method(D_METHOD("shaped_text_get_word_breaks", "shaped"), &TextServer::_shaped_text_get_word_breaks); + ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks_adv", "shaped", "width", "start", "once", "break_flags"), &TextServer::shaped_text_get_line_breaks_adv, DEFVAL(0), DEFVAL(true), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks", "shaped", "width", "start", "break_flags"), &TextServer::shaped_text_get_line_breaks, DEFVAL(0), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND)); + ClassDB::bind_method(D_METHOD("shaped_text_get_word_breaks", "shaped", "grapheme_flags"), &TextServer::shaped_text_get_word_breaks); + + ClassDB::bind_method(D_METHOD("shaped_text_get_trim_pos", "shaped"), &TextServer::shaped_text_get_trim_pos); + ClassDB::bind_method(D_METHOD("shaped_text_get_ellipsis_pos", "shaped"), &TextServer::shaped_text_get_ellipsis_pos); + ClassDB::bind_method(D_METHOD("shaped_text_get_ellipsis_glyphs", "shaped"), &TextServer::_shaped_text_get_ellipsis_glyphs_wrapper); + ClassDB::bind_method(D_METHOD("shaped_text_get_ellipsis_glyph_count", "shaped"), &TextServer::shaped_text_get_ellipsis_glyph_count); ClassDB::bind_method(D_METHOD("shaped_text_overrun_trim_to_width", "shaped", "width", "overrun_trim_flags"), &TextServer::shaped_text_overrun_trim_to_width, DEFVAL(0), DEFVAL(OVERRUN_NO_TRIMMING)); @@ -391,8 +389,8 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shaped_text_get_underline_position", "shaped"), &TextServer::shaped_text_get_underline_position); ClassDB::bind_method(D_METHOD("shaped_text_get_underline_thickness", "shaped"), &TextServer::shaped_text_get_underline_thickness); - ClassDB::bind_method(D_METHOD("shaped_text_get_carets", "shaped", "position"), &TextServer::_shaped_text_get_carets); - ClassDB::bind_method(D_METHOD("shaped_text_get_selection", "shaped", "start", "end"), &TextServer::_shaped_text_get_selection); + ClassDB::bind_method(D_METHOD("shaped_text_get_carets", "shaped", "position"), &TextServer::_shaped_text_get_carets_wrapper); + ClassDB::bind_method(D_METHOD("shaped_text_get_selection", "shaped", "start", "end"), &TextServer::shaped_text_get_selection); ClassDB::bind_method(D_METHOD("shaped_text_hit_test_grapheme", "shaped", "coords"), &TextServer::shaped_text_hit_test_grapheme); ClassDB::bind_method(D_METHOD("shaped_text_hit_test_position", "shaped", "coords"), &TextServer::shaped_text_hit_test_position); @@ -403,7 +401,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shaped_text_draw", "shaped", "canvas", "pos", "clip_l", "clip_r", "color"), &TextServer::shaped_text_draw, DEFVAL(-1), DEFVAL(-1), DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("shaped_text_draw_outline", "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color"), &TextServer::shaped_text_draw_outline, DEFVAL(-1), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("shaped_text_get_dominant_direciton_in_range", "shaped", "start", "end"), &TextServer::shaped_text_get_dominant_direciton_in_range); + ClassDB::bind_method(D_METHOD("shaped_text_get_dominant_direction_in_range", "shaped", "start", "end"), &TextServer::shaped_text_get_dominant_direction_in_range); ClassDB::bind_method(D_METHOD("format_number", "number", "language"), &TextServer::format_number, DEFVAL("")); ClassDB::bind_method(D_METHOD("parse_number", "number", "language"), &TextServer::parse_number, DEFVAL("")); @@ -424,12 +422,14 @@ void TextServer::_bind_methods() { BIND_ENUM_CONSTANT(JUSTIFICATION_WORD_BOUND); BIND_ENUM_CONSTANT(JUSTIFICATION_TRIM_EDGE_SPACES); BIND_ENUM_CONSTANT(JUSTIFICATION_AFTER_LAST_TAB); + BIND_ENUM_CONSTANT(JUSTIFICATION_CONSTRAIN_ELLIPSIS); /* LineBreakFlag */ BIND_ENUM_CONSTANT(BREAK_NONE); BIND_ENUM_CONSTANT(BREAK_MANDATORY); BIND_ENUM_CONSTANT(BREAK_WORD_BOUND); BIND_ENUM_CONSTANT(BREAK_GRAPHEME_BOUND); + BIND_ENUM_CONSTANT(BREAK_WORD_BOUND_ADAPTIVE); /* TextOverrunFlag */ BIND_ENUM_CONSTANT(OVERRUN_NO_TRIMMING); @@ -437,8 +437,10 @@ void TextServer::_bind_methods() { BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ONLY); BIND_ENUM_CONSTANT(OVERRUN_ADD_ELLIPSIS); BIND_ENUM_CONSTANT(OVERRUN_ENFORCE_ELLIPSIS); + BIND_ENUM_CONSTANT(OVERRUN_JUSTIFICATION_AWARE); /* GraphemeFlag */ + BIND_ENUM_CONSTANT(GRAPHEME_IS_VALID); BIND_ENUM_CONSTANT(GRAPHEME_IS_RTL); BIND_ENUM_CONSTANT(GRAPHEME_IS_VIRTUAL); BIND_ENUM_CONSTANT(GRAPHEME_IS_SPACE); @@ -578,6 +580,9 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po int fnt = (p_size < 20) ? 0 : 1; ERR_FAIL_COND(hex_code_box_font_tex[fnt].is_null()); + if (p_index == 0) { + return; + } uint8_t a = p_index & 0x0F; uint8_t b = (p_index >> 4) & 0x0F; @@ -592,12 +597,12 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po real_t w = ((p_index <= 0xFF) ? 1 : ((p_index <= 0xFFFF) ? 2 : 3)) * hex_code_box_font_size[fnt].x; real_t h = 2 * hex_code_box_font_size[fnt].y; - pos.y -= Math::floor((h + 3 + hex_code_box_font_size[fnt].z) * 0.75); + pos.y -= Math::floor((h + 3 + hex_code_box_font_size[fnt].z)); RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, 0), Size2(1, h + 2 + 2 * hex_code_box_font_size[fnt].z)), p_color); RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(w + 2, 0), Size2(1, h + 2 + 2 * hex_code_box_font_size[fnt].z)), p_color); - RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, 0), Size2(w + 2, 1)), p_color); - RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, h + 2 + 2 * hex_code_box_font_size[fnt].z), Size2(w + 2, 1)), p_color); + RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, 0), Size2(w + 3, 1)), p_color); + RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, h + 2 + 2 * hex_code_box_font_size[fnt].z), Size2(w + 3, 1)), p_color); pos += Point2(2, 2); if (p_index <= 0xFF) { @@ -630,13 +635,12 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po } } -Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start, bool p_once, uint8_t /*TextBreakFlag*/ p_break_flags) const { - Vector<Vector2i> lines; +PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint16_t /*TextBreakFlag*/ p_break_flags) const { + PackedInt32Array lines; ERR_FAIL_COND_V(p_width.is_empty(), lines); const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped); - const Vector<Glyph> &logical = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); const Vector2i &range = shaped_text_get_range(p_shaped); real_t width = 0.f; @@ -644,8 +648,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const int last_safe_break = -1; int chunk = 0; - int l_size = logical.size(); - const Glyph *l_gl = logical.ptr(); + int l_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); for (int i = 0; i < l_size; i++) { if (l_gl[i].start < p_start) { @@ -653,7 +657,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const } if (l_gl[i].count > 0) { if ((p_width[chunk] > 0) && (width + l_gl[i].advance > p_width[chunk]) && (last_safe_break >= 0)) { - lines.push_back(Vector2i(line_start, l_gl[last_safe_break].end)); + lines.push_back(line_start); + lines.push_back(l_gl[last_safe_break].end); line_start = l_gl[last_safe_break].end; i = last_safe_break; last_safe_break = -1; @@ -669,7 +674,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const } if ((p_break_flags & BREAK_MANDATORY) == BREAK_MANDATORY) { if ((l_gl[i].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD) { - lines.push_back(Vector2i(line_start, l_gl[i].end)); + lines.push_back(line_start); + lines.push_back(l_gl[i].end); line_start = l_gl[i].end; last_safe_break = -1; width = 0; @@ -693,27 +699,31 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const } if (l_size > 0) { - lines.push_back(Vector2i(line_start, range.y)); + if (lines.size() == 0 || lines[lines.size() - 1] < range.y) { + lines.push_back(line_start); + lines.push_back(range.y); + } } else { - lines.push_back(Vector2i(0, 0)); + lines.push_back(0); + lines.push_back(0); } return lines; } -Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t /*TextBreakFlag*/ p_break_flags) const { - Vector<Vector2i> lines; +PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const { + PackedInt32Array lines; const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped); - const Vector<Glyph> &logical = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); const Vector2i &range = shaped_text_get_range(p_shaped); real_t width = 0.f; int line_start = MAX(p_start, range.x); int last_safe_break = -1; int word_count = 0; - int l_size = logical.size(); - const Glyph *l_gl = logical.ptr(); + + int l_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); for (int i = 0; i < l_size; i++) { if (l_gl[i].start < p_start) { @@ -721,7 +731,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_ } if (l_gl[i].count > 0) { if ((p_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > p_width) && (last_safe_break >= 0)) { - lines.push_back(Vector2i(line_start, l_gl[last_safe_break].end)); + lines.push_back(line_start); + lines.push_back(l_gl[last_safe_break].end); line_start = l_gl[last_safe_break].end; i = last_safe_break; last_safe_break = -1; @@ -731,7 +742,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_ } if ((p_break_flags & BREAK_MANDATORY) == BREAK_MANDATORY) { if ((l_gl[i].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD) { - lines.push_back(Vector2i(line_start, l_gl[i].end)); + lines.push_back(line_start); + lines.push_back(l_gl[i].end); line_start = l_gl[i].end; last_safe_break = -1; width = 0; @@ -755,51 +767,49 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_ } if (l_size > 0) { - if (lines.size() == 0 || lines[lines.size() - 1].y < range.y) { - lines.push_back(Vector2i(line_start, range.y)); + if (lines.size() == 0 || lines[lines.size() - 1] < range.y) { + lines.push_back(line_start); + lines.push_back(range.y); } } else { - lines.push_back(Vector2i(0, 0)); + lines.push_back(0); + lines.push_back(0); } return lines; } -Vector<Vector2i> TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { - Vector<Vector2i> words; +PackedInt32Array TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { + PackedInt32Array words; const_cast<TextServer *>(this)->shaped_text_update_justification_ops(p_shaped); - const Vector<Glyph> &logical = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); const Vector2i &range = shaped_text_get_range(p_shaped); int word_start = range.x; - int l_size = logical.size(); - const Glyph *l_gl = logical.ptr(); + int l_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped); for (int i = 0; i < l_size; i++) { if (l_gl[i].count > 0) { if ((l_gl[i].flags & p_grapheme_flags) != 0) { - words.push_back(Vector2i(word_start, l_gl[i].start)); + words.push_back(word_start); + words.push_back(l_gl[i].start); word_start = l_gl[i].end; } } } if (l_size > 0) { - words.push_back(Vector2i(word_start, range.y)); + words.push_back(word_start); + words.push_back(range.y); } return words; } -TextServer::TrimData TextServer::shaped_text_get_trim_data(RID p_shaped) const { - WARN_PRINT("Getting overrun data not supported by this TextServer."); - return TrimData(); -} - -void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_leading_caret, Direction &p_leading_dir, Rect2 &p_trailing_caret, Direction &p_trailing_dir) const { +CaretInfo TextServer::shaped_text_get_carets(RID p_shaped, int p_position) const { Vector<Rect2> carets; - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); + TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); const Vector2 &range = shaped_text_get_range(p_shaped); real_t ascent = shaped_text_get_ascent(p_shaped); @@ -807,11 +817,12 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l real_t height = (ascent + descent) / 2; real_t off = 0.0f; - p_leading_dir = DIRECTION_AUTO; - p_trailing_dir = DIRECTION_AUTO; + CaretInfo caret; + caret.l_dir = DIRECTION_AUTO; + caret.t_dir = DIRECTION_AUTO; - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); for (int i = 0; i < v_size; i++) { if (glyphs[i].count > 0) { @@ -827,13 +838,13 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l cr.position.y = -ascent; cr.position.x = off; if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) { - p_trailing_dir = DIRECTION_RTL; + caret.t_dir = DIRECTION_RTL; for (int j = 0; j < glyphs[i].count; j++) { cr.position.x += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.x -= glyphs[i + j].advance * glyphs[i + j].repeat; } } else { - p_trailing_dir = DIRECTION_LTR; + caret.t_dir = DIRECTION_LTR; for (int j = 0; j < glyphs[i].count; j++) { cr.size.x += glyphs[i + j].advance * glyphs[i + j].repeat; } @@ -847,19 +858,19 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l cr.position.x = -ascent; cr.position.y = off; if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) { - p_trailing_dir = DIRECTION_RTL; + caret.t_dir = DIRECTION_RTL; for (int j = 0; j < glyphs[i].count; j++) { cr.position.y += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.y -= glyphs[i + j].advance * glyphs[i + j].repeat; } } else { - p_trailing_dir = DIRECTION_LTR; + caret.t_dir = DIRECTION_LTR; for (int j = 0; j < glyphs[i].count; j++) { cr.size.y += glyphs[i + j].advance * glyphs[i + j].repeat; } } } - p_trailing_caret = cr; + caret.t_caret = cr; } // Caret after grapheme (bottom / right). if (p_position == glyphs[i].end && ((glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL)) { @@ -874,13 +885,13 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l } cr.position.x = off; if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) { - p_leading_dir = DIRECTION_LTR; + caret.l_dir = DIRECTION_LTR; for (int j = 0; j < glyphs[i].count; j++) { cr.position.x += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.x -= glyphs[i + j].advance * glyphs[i + j].repeat; } } else { - p_leading_dir = DIRECTION_RTL; + caret.l_dir = DIRECTION_RTL; for (int j = 0; j < glyphs[i].count; j++) { cr.size.x += glyphs[i + j].advance * glyphs[i + j].repeat; } @@ -896,19 +907,19 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l } cr.position.y = off; if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) { - p_leading_dir = DIRECTION_LTR; + caret.l_dir = DIRECTION_LTR; for (int j = 0; j < glyphs[i].count; j++) { cr.position.y += glyphs[i + j].advance * glyphs[i + j].repeat; cr.size.y -= glyphs[i + j].advance * glyphs[i + j].repeat; } } else { - p_leading_dir = DIRECTION_RTL; + caret.l_dir = DIRECTION_RTL; for (int j = 0; j < glyphs[i].count; j++) { cr.size.y += glyphs[i + j].advance * glyphs[i + j].repeat; } } } - p_leading_caret = cr; + caret.l_caret = cr; } // Caret inside grapheme (middle). if (p_position > glyphs[i].start && p_position < glyphs[i].end && (glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL) { @@ -937,17 +948,29 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l cr.position.y = off + char_adv * (p_position - glyphs[i].start); } } - p_trailing_caret = cr; - p_leading_caret = cr; + caret.t_caret = cr; + caret.l_caret = cr; } } off += glyphs[i].advance * glyphs[i].repeat; } + return caret; } -TextServer::Direction TextServer::shaped_text_get_dominant_direciton_in_range(RID p_shaped, int p_start, int p_end) const { - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); +Dictionary TextServer::_shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const { + Dictionary ret; + + CaretInfo caret = shaped_text_get_carets(p_shaped, p_position); + + ret["leading_rect"] = caret.l_caret; + ret["leading_direction"] = caret.l_dir; + ret["trailing_rect"] = caret.t_caret; + ret["trailing_direction"] = caret.t_dir; + + return ret; +} +TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const { if (p_start == p_end) { return DIRECTION_AUTO; } @@ -958,8 +981,8 @@ TextServer::Direction TextServer::shaped_text_get_dominant_direciton_in_range(RI int rtl = 0; int ltr = 0; - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); for (int i = 0; i < v_size; i++) { if ((glyphs[i].end > start) && (glyphs[i].start < end)) { @@ -983,7 +1006,6 @@ TextServer::Direction TextServer::shaped_text_get_dominant_direciton_in_range(RI Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const { Vector<Vector2> ranges; - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); if (p_start == p_end) { return ranges; @@ -992,8 +1014,8 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, int start = MIN(p_start, p_end); int end = MAX(p_start, p_end); - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); real_t off = 0.0f; for (int i = 0; i < v_size; i++) { @@ -1076,13 +1098,11 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, } int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) const { - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); - // Exact grapheme hit test, return -1 if missed. real_t off = 0.0f; - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); for (int i = 0; i < v_size; i++) { for (int j = 0; j < glyphs[i].repeat; j++) { @@ -1096,10 +1116,8 @@ int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) con } int TextServer::shaped_text_hit_test_position(RID p_shaped, real_t p_coords) const { - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); - - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); // Cursor placement hit test. @@ -1165,10 +1183,9 @@ int TextServer::shaped_text_hit_test_position(RID p_shaped, real_t p_coords) con return 0; } -int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) { - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); +int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const { + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); for (int i = 0; i < v_size; i++) { if (p_pos >= glyphs[i].start && p_pos < glyphs[i].end) { return glyphs[i].end; @@ -1177,10 +1194,9 @@ int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) { return p_pos; } -int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) { - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); +int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const { + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); for (int i = 0; i < v_size; i++) { if (p_pos > glyphs[i].start && p_pos <= glyphs[i].end) { return glyphs[i].start; @@ -1191,26 +1207,30 @@ int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) { } void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, const Color &p_color) const { - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); bool hex_codes = shaped_text_get_preserve_control(p_shaped) || shaped_text_get_preserve_invalid(p_shaped); bool rtl = shaped_text_get_direction(p_shaped) == DIRECTION_RTL; - TrimData trim_data = shaped_text_get_trim_data(p_shaped); - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); + int ellipsis_pos = shaped_text_get_ellipsis_pos(p_shaped); + int trim_pos = shaped_text_get_trim_pos(p_shaped); + + const Glyph *ellipsis_glyphs = shaped_text_get_ellipsis_glyphs(p_shaped); + int ellipsis_gl_size = shaped_text_get_ellipsis_glyph_count(p_shaped); + + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); Vector2 ofs = p_pos; // Draw RTL ellipsis string when needed. - if (rtl && trim_data.ellipsis_pos >= 0) { - for (int i = trim_data.ellipsis_glyph_buf.size() - 1; i >= 0; i--) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) { - font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color); + if (rtl && ellipsis_pos >= 0) { + for (int i = ellipsis_gl_size - 1; i >= 0; i--) { + for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) { + font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color); if (orientation == ORIENTATION_HORIZONTAL) { - ofs.x += trim_data.ellipsis_glyph_buf[i].advance; + ofs.x += ellipsis_glyphs[i].advance; } else { - ofs.y += trim_data.ellipsis_glyph_buf[i].advance; + ofs.y += ellipsis_glyphs[i].advance; } } } @@ -1244,13 +1264,13 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p } } } - if (trim_data.trim_pos >= 0) { + if (trim_pos >= 0) { if (rtl) { - if (i < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (i < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { continue; } } else { - if (i >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (i >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { break; } } @@ -1269,14 +1289,14 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p } } // Draw LTR ellipsis string when needed. - if (!rtl && trim_data.ellipsis_pos >= 0) { - for (int i = 0; i < trim_data.ellipsis_glyph_buf.size(); i++) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) { - font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color); + if (!rtl && ellipsis_pos >= 0) { + for (int i = 0; i < ellipsis_gl_size; i++) { + for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) { + font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color); if (orientation == ORIENTATION_HORIZONTAL) { - ofs.x += trim_data.ellipsis_glyph_buf[i].advance; + ofs.x += ellipsis_glyphs[i].advance; } else { - ofs.y += trim_data.ellipsis_glyph_buf[i].advance; + ofs.y += ellipsis_glyphs[i].advance; } } } @@ -1284,24 +1304,28 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p } void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, int p_outline_size, const Color &p_color) const { - const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped); TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); bool rtl = (shaped_text_get_direction(p_shaped) == DIRECTION_RTL); - TrimData trim_data = shaped_text_get_trim_data(p_shaped); - int v_size = visual.size(); - const Glyph *glyphs = visual.ptr(); + int ellipsis_pos = shaped_text_get_ellipsis_pos(p_shaped); + int trim_pos = shaped_text_get_trim_pos(p_shaped); + + const Glyph *ellipsis_glyphs = shaped_text_get_ellipsis_glyphs(p_shaped); + int ellipsis_gl_size = shaped_text_get_ellipsis_glyph_count(p_shaped); + + int v_size = shaped_text_get_glyph_count(p_shaped); + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); Vector2 ofs = p_pos; // Draw RTL ellipsis string when needed. - if (rtl && trim_data.ellipsis_pos >= 0) { - for (int i = trim_data.ellipsis_glyph_buf.size() - 1; i >= 0; i--) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) { - font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color); + if (rtl && ellipsis_pos >= 0) { + for (int i = ellipsis_gl_size - 1; i >= 0; i--) { + for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) { + font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color); if (orientation == ORIENTATION_HORIZONTAL) { - ofs.x += trim_data.ellipsis_glyph_buf[i].advance; + ofs.x += ellipsis_glyphs[i].advance; } else { - ofs.y += trim_data.ellipsis_glyph_buf[i].advance; + ofs.y += ellipsis_glyphs[i].advance; } } } @@ -1335,13 +1359,13 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect } } } - if (trim_data.trim_pos >= 0) { + if (trim_pos >= 0) { if (rtl) { - if (i < trim_data.trim_pos) { + if (i < trim_pos) { continue; } } else { - if (i >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { + if (i >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { break; } } @@ -1357,48 +1381,26 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect } } // Draw LTR ellipsis string when needed. - if (!rtl && trim_data.ellipsis_pos >= 0) { - for (int i = 0; i < trim_data.ellipsis_glyph_buf.size(); i++) { - for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) { - font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color); + if (!rtl && ellipsis_pos >= 0) { + for (int i = 0; i < ellipsis_gl_size; i++) { + for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) { + font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color); if (orientation == ORIENTATION_HORIZONTAL) { - ofs.x += trim_data.ellipsis_glyph_buf[i].advance; + ofs.x += ellipsis_glyphs[i].advance; } else { - ofs.y += trim_data.ellipsis_glyph_buf[i].advance; + ofs.y += ellipsis_glyphs[i].advance; } } } } } -Dictionary TextServer::_font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const { - Vector<Vector3> points; - Vector<int32_t> contours; - bool orientation; - bool ok = font_get_glyph_contours(p_font, p_size, p_index, points, contours, orientation); - Dictionary out; - - if (ok) { - out["points"] = points; - out["contours"] = contours; - out["orientation"] = orientation; - } - return out; -} - -void TextServer::_shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) { - Vector<Vector2i> overrides; - for (int i = 0; i < p_override.size(); i++) { - overrides.push_back(p_override[i]); - } - shaped_text_set_bidi_override(p_shaped, overrides); -} - -Array TextServer::_shaped_text_get_glyphs(RID p_shaped) const { +Array TextServer::_shaped_text_get_glyphs_wrapper(RID p_shaped) const { Array ret; - Vector<Glyph> glyphs = shaped_text_get_glyphs(p_shaped); - for (int i = 0; i < glyphs.size(); i++) { + const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); + int gl_size = shaped_text_get_glyph_count(p_shaped); + for (int i = 0; i < gl_size; i++) { Dictionary glyph; glyph["start"] = glyphs[i].start; @@ -1418,60 +1420,51 @@ Array TextServer::_shaped_text_get_glyphs(RID p_shaped) const { return ret; } -Array TextServer::_shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint8_t p_break_flags) const { +Array TextServer::_shaped_text_sort_logical_wrapper(RID p_shaped) { Array ret; - Vector<Vector2i> lines = shaped_text_get_line_breaks_adv(p_shaped, p_width, p_start, p_once, p_break_flags); - for (int i = 0; i < lines.size(); i++) { - ret.push_back(lines[i]); - } - - return ret; -} + const Glyph *glyphs = shaped_text_sort_logical(p_shaped); + int gl_size = shaped_text_get_glyph_count(p_shaped); + for (int i = 0; i < gl_size; i++) { + Dictionary glyph; -Array TextServer::_shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t p_break_flags) const { - Array ret; + glyph["start"] = glyphs[i].start; + glyph["end"] = glyphs[i].end; + glyph["repeat"] = glyphs[i].repeat; + glyph["count"] = glyphs[i].count; + glyph["flags"] = glyphs[i].flags; + glyph["offset"] = Vector2(glyphs[i].x_off, glyphs[i].y_off); + glyph["advance"] = glyphs[i].advance; + glyph["font_rid"] = glyphs[i].font_rid; + glyph["font_size"] = glyphs[i].font_size; + glyph["index"] = glyphs[i].index; - Vector<Vector2i> lines = shaped_text_get_line_breaks(p_shaped, p_width, p_start, p_break_flags); - for (int i = 0; i < lines.size(); i++) { - ret.push_back(lines[i]); + ret.push_back(glyph); } return ret; } -Array TextServer::_shaped_text_get_word_breaks(RID p_shaped) const { +Array TextServer::_shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const { Array ret; - Vector<Vector2i> words = shaped_text_get_word_breaks(p_shaped); - for (int i = 0; i < words.size(); i++) { - ret.push_back(words[i]); - } - - return ret; -} - -Dictionary TextServer::_shaped_text_get_carets(RID p_shaped, int p_position) const { - Dictionary ret; - - Rect2 l_caret, t_caret; - Direction l_dir, t_dir; - shaped_text_get_carets(p_shaped, p_position, l_caret, l_dir, t_caret, t_dir); - - ret["leading_rect"] = l_caret; - ret["leading_direction"] = l_dir; - ret["trailing_rect"] = t_caret; - ret["trailing_direction"] = t_dir; - - return ret; -} + const Glyph *glyphs = shaped_text_get_ellipsis_glyphs(p_shaped); + int gl_size = shaped_text_get_ellipsis_glyph_count(p_shaped); + for (int i = 0; i < gl_size; i++) { + Dictionary glyph; -Array TextServer::_shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const { - Array ret; + glyph["start"] = glyphs[i].start; + glyph["end"] = glyphs[i].end; + glyph["repeat"] = glyphs[i].repeat; + glyph["count"] = glyphs[i].count; + glyph["flags"] = glyphs[i].flags; + glyph["offset"] = Vector2(glyphs[i].x_off, glyphs[i].y_off); + glyph["advance"] = glyphs[i].advance; + glyph["font_rid"] = glyphs[i].font_rid; + glyph["font_size"] = glyphs[i].font_size; + glyph["index"] = glyphs[i].index; - Vector<Vector2> ranges = shaped_text_get_selection(p_shaped, p_start, p_end); - for (int i = 0; i < ranges.size(); i++) { - ret.push_back(ranges[i]); + ret.push_back(glyph); } return ret; diff --git a/servers/text_server.h b/servers/text_server.h index 90ad9b493b..da62ff8ef4 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -34,13 +34,17 @@ #include "core/object/ref_counted.h" #include "core/os/os.h" #include "core/templates/rid.h" +#include "core/variant/native_ptr.h" #include "core/variant/variant.h" #include "scene/resources/texture.h" class CanvasTexture; -class TextServer : public Object { - GDCLASS(TextServer, Object); +struct Glyph; +struct CaretInfo; + +class TextServer : public RefCounted { + GDCLASS(TextServer, RefCounted); public: enum Direction { @@ -63,12 +67,12 @@ public: JUSTIFICATION_CONSTRAIN_ELLIPSIS = 1 << 4, }; - enum LineBreakFlag { + enum LineBreakFlag { // LineBreakFlag can be passed in the same value as the JustificationFlag, do not use the same values. BREAK_NONE = 0, - BREAK_MANDATORY = 1 << 4, - BREAK_WORD_BOUND = 1 << 5, - BREAK_GRAPHEME_BOUND = 1 << 6, - BREAK_WORD_BOUND_ADAPTIVE = 1 << 5 | 1 << 7, + BREAK_MANDATORY = 1 << 5, + BREAK_WORD_BOUND = 1 << 6, + BREAK_GRAPHEME_BOUND = 1 << 7, + BREAK_WORD_BOUND_ADAPTIVE = 1 << 6 | 1 << 8, }; enum TextOverrunFlag { @@ -124,50 +128,11 @@ public: SPACING_BOTTOM, }; - struct Glyph { - int start = -1; // Start offset in the source string. - int end = -1; // End offset in the source string. - - uint8_t count = 0; // Number of glyphs in the grapheme, set in the first glyph only. - uint8_t repeat = 1; // Draw multiple times in the row. - uint16_t flags = 0; // Grapheme flags (valid, rtl, virtual), set in the first glyph only. - - real_t x_off = 0.f; // Offset from the origin of the glyph on baseline. - real_t y_off = 0.f; - real_t advance = 0.f; // Advance to the next glyph along baseline(x for horizontal layout, y for vertical). - - RID font_rid; // Font resource. - int font_size = 0; // Font size; - int32_t index = 0; // Glyph index (font specific) or UTF-32 codepoint (for the invalid glyphs). - - bool operator==(const Glyph &p_a) const; - bool operator!=(const Glyph &p_a) const; - - bool operator<(const Glyph &p_a) const; - bool operator>(const Glyph &p_a) const; - }; - - struct GlyphCompare { // For line breaking reordering. - _FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const { - if (l.start == r.start) { - if (l.count == r.count) { - if ((l.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) { - return false; - } else { - return true; - } - } - return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant. - } else { - return l.start < r.start; - } - } - }; - +protected: struct TrimData { int trim_pos = -1; int ellipsis_pos = -1; - Vector<TextServer::Glyph> ellipsis_glyph_buf; + Vector<Glyph> ellipsis_glyph_buf; }; struct ShapedTextData { @@ -215,22 +180,21 @@ public: bool preserve_invalid = true; // Draw hex code box instead of missing characters. bool preserve_control = false; // Draw control characters. - real_t ascent = 0.f; // Ascent for horizontal layout, 1/2 of width for vertical. - real_t descent = 0.f; // Descent for horizontal layout, 1/2 of width for vertical. - real_t width = 0.f; // Width for horizontal layout, height for vertical. - real_t width_trimmed = 0.f; + float ascent = 0.f; // Ascent for horizontal layout, 1/2 of width for vertical. + float descent = 0.f; // Descent for horizontal layout, 1/2 of width for vertical. + float width = 0.f; // Width for horizontal layout, height for vertical. + float width_trimmed = 0.f; - real_t upos = 0.f; - real_t uthk = 0.f; + float upos = 0.f; + float uthk = 0.f; TrimData overrun_trim_data; bool fit_width_minimum_reached = false; - Vector<TextServer::Glyph> glyphs; - Vector<TextServer::Glyph> glyphs_logical; + Vector<Glyph> glyphs; + Vector<Glyph> glyphs_logical; }; -protected: static void _bind_methods(); static Vector3 hex_code_box_font_size[2]; @@ -240,20 +204,19 @@ public: static void initialize_hex_code_box_fonts(); static void finish_hex_code_box_fonts(); - virtual bool has_feature(Feature p_feature) = 0; + virtual bool has_feature(Feature p_feature) const = 0; virtual String get_name() const = 0; + virtual uint32_t get_features() const = 0; virtual void free(RID p_rid) = 0; virtual bool has(RID p_rid) = 0; virtual bool load_support_data(const String &p_filename) = 0; -#ifdef TOOLS_ENABLED - virtual String get_support_data_filename() = 0; - virtual String get_support_data_info() = 0; - virtual bool save_support_data(const String &p_filename) = 0; -#endif + virtual String get_support_data_filename() const = 0; + virtual String get_support_data_info() const = 0; + virtual bool save_support_data(const String &p_filename) const = 0; - virtual bool is_locale_right_to_left(const String &p_locale) = 0; + virtual bool is_locale_right_to_left(const String &p_locale) const = 0; virtual int32_t name_to_tag(const String &p_name) const { return 0; }; virtual String tag_to_name(int32_t p_tag) const { return ""; }; @@ -282,33 +245,33 @@ public: virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) = 0; virtual bool font_is_force_autohinter(RID p_font_rid) const = 0; - virtual void font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) = 0; - virtual TextServer::Hinting font_get_hinting(RID p_font_rid) const = 0; + virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) = 0; + virtual Hinting font_get_hinting(RID p_font_rid) const = 0; virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) = 0; virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const = 0; - virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) = 0; - virtual real_t font_get_oversampling(RID p_font_rid) const = 0; + virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) = 0; + virtual float font_get_oversampling(RID p_font_rid) const = 0; virtual Array font_get_size_cache_list(RID p_font_rid) const = 0; virtual void font_clear_size_cache(RID p_font_rid) = 0; virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) = 0; - virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) = 0; - virtual real_t font_get_ascent(RID p_font_rid, int p_size) const = 0; + virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) = 0; + virtual float font_get_ascent(RID p_font_rid, int p_size) const = 0; - virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) = 0; - virtual real_t font_get_descent(RID p_font_rid, int p_size) const = 0; + virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) = 0; + virtual float font_get_descent(RID p_font_rid, int p_size) const = 0; - virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) = 0; - virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const = 0; + virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) = 0; + virtual float font_get_underline_position(RID p_font_rid, int p_size) const = 0; - virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) = 0; - virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const = 0; + virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) = 0; + virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const = 0; - virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) = 0; - virtual real_t font_get_scale(RID p_font_rid, int p_size) const = 0; + virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) = 0; + virtual float font_get_scale(RID p_font_rid, int p_size) const = 0; virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) = 0; virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const = 0; @@ -342,7 +305,7 @@ public: virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0; virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) = 0; - virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const = 0; + virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const = 0; virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const = 0; virtual void font_clear_kerning_map(RID p_font_rid, int p_size) = 0; @@ -377,11 +340,11 @@ public: virtual Dictionary font_supported_feature_list(RID p_font_rid) const = 0; virtual Dictionary font_supported_variation_list(RID p_font_rid) const = 0; - virtual real_t font_get_global_oversampling() const = 0; - virtual void font_set_global_oversampling(real_t p_oversampling) = 0; + virtual float font_get_global_oversampling() const = 0; + virtual void font_set_global_oversampling(float p_oversampling) = 0; - Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const; - void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const; + virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const; + virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const; /* Shaped text buffer interface */ @@ -392,7 +355,7 @@ public: virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) = 0; virtual Direction shaped_text_get_direction(RID p_shaped) const = 0; - virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) = 0; + virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) = 0; virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0; virtual Orientation shaped_text_get_orientation(RID p_shaped) const = 0; @@ -410,8 +373,8 @@ public: virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range. virtual RID shaped_text_get_parent(RID p_shaped) const = 0; - virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0; - virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) = 0; + virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0; + virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) = 0; virtual bool shaped_text_shape(RID p_shaped) = 0; virtual bool shaped_text_update_breaks(RID p_shaped) = 0; @@ -419,66 +382,109 @@ public: virtual bool shaped_text_is_ready(RID p_shaped) const = 0; - virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const = 0; + virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const = 0; + Array _shaped_text_get_glyphs_wrapper(RID p_shaped) const; + virtual const Glyph *shaped_text_sort_logical(RID p_shaped) = 0; + Array _shaped_text_sort_logical_wrapper(RID p_shaped); + virtual int shaped_text_get_glyph_count(RID p_shaped) const = 0; virtual Vector2i shaped_text_get_range(RID p_shaped) const = 0; - virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) = 0; + virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; + virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; + virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const; - virtual Vector<Vector2i> shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start = 0, bool p_once = true, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; - virtual Vector<Vector2i> shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start = 0, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; - virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const; + virtual int shaped_text_get_trim_pos(RID p_shaped) const = 0; + virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const = 0; + virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const = 0; + Array _shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const; + virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const = 0; + + virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) = 0; - virtual TrimData shaped_text_get_trim_data(RID p_shaped) const; - virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) = 0; virtual Array shaped_text_get_objects(RID p_shaped) const = 0; virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const = 0; virtual Size2 shaped_text_get_size(RID p_shaped) const = 0; - virtual real_t shaped_text_get_ascent(RID p_shaped) const = 0; - virtual real_t shaped_text_get_descent(RID p_shaped) const = 0; - virtual real_t shaped_text_get_width(RID p_shaped) const = 0; - virtual real_t shaped_text_get_underline_position(RID p_shaped) const = 0; - virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const = 0; + virtual float shaped_text_get_ascent(RID p_shaped) const = 0; + virtual float shaped_text_get_descent(RID p_shaped) const = 0; + virtual float shaped_text_get_width(RID p_shaped) const = 0; + virtual float shaped_text_get_underline_position(RID p_shaped) const = 0; + virtual float shaped_text_get_underline_thickness(RID p_shaped) const = 0; + + virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const; - virtual Direction shaped_text_get_dominant_direciton_in_range(RID p_shaped, int p_start, int p_end) const; + virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const; + Dictionary _shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const; - virtual void shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_leading_caret, Direction &p_leading_dir, Rect2 &p_trailing_caret, Direction &p_trailing_dir) const; virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const; - virtual int shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) const; // Return grapheme index. - virtual int shaped_text_hit_test_position(RID p_shaped, real_t p_coords) const; // Return caret/selection position. + virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const; // Return grapheme index. + virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const; // Return caret/selection position. - virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos); - virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos); + virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const; + virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const; // The pen position is always placed on the baseline and moveing left to right. - virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l = -1.f, real_t p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const; - virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l = -1.f, real_t p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const; + virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const; + virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const; // Number conversion. virtual String format_number(const String &p_string, const String &p_language = "") const { return p_string; }; virtual String parse_number(const String &p_string, const String &p_language = "") const { return p_string; }; virtual String percent_sign(const String &p_language = "") const { return "%"; }; - /* GDScript wrappers */ - RID _create_font_memory(const PackedByteArray &p_data, int p_base_size = 16); + TextServer(); + ~TextServer(); +}; + +/*************************************************************************/ - Dictionary _font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const; +struct Glyph { + int start = -1; // Start offset in the source string. + int end = -1; // End offset in the source string. - Array _shaped_text_get_glyphs(RID p_shaped) const; - Dictionary _shaped_text_get_carets(RID p_shaped, int p_position) const; + uint8_t count = 0; // Number of glyphs in the grapheme, set in the first glyph only. + uint8_t repeat = 1; // Draw multiple times in the row. + uint16_t flags = 0; // Grapheme flags (valid, rtl, virtual), set in the first glyph only. - void _shaped_text_set_bidi_override(RID p_shaped, const Array &p_override); + float x_off = 0.f; // Offset from the origin of the glyph on baseline. + float y_off = 0.f; + float advance = 0.f; // Advance to the next glyph along baseline(x for horizontal layout, y for vertical). - Array _shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint8_t p_break_flags) const; - Array _shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t p_break_flags) const; - Array _shaped_text_get_word_breaks(RID p_shaped) const; + RID font_rid; // Font resource. + int font_size = 0; // Font size; + int32_t index = 0; // Glyph index (font specific) or UTF-32 codepoint (for the invalid glyphs). - Array _shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const; + bool operator==(const Glyph &p_a) const; + bool operator!=(const Glyph &p_a) const; - TextServer(); - ~TextServer(); + bool operator<(const Glyph &p_a) const; + bool operator>(const Glyph &p_a) const; +}; + +struct CaretInfo { + Rect2 l_caret; + Rect2 t_caret; + TextServer::Direction l_dir; + TextServer::Direction t_dir; +}; + +struct GlyphCompare { // For line breaking reordering. + _FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const { + if (l.start == r.start) { + if (l.count == r.count) { + if ((l.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) { + return false; + } else { + return true; + } + } + return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant. + } else { + return l.start < r.start; + } + } }; /*************************************************************************/ @@ -486,52 +492,32 @@ public: class TextServerManager : public Object { GDCLASS(TextServerManager, Object); -public: - typedef TextServer *(*CreateFunction)(Error &r_error, void *p_user_data); - protected: static void _bind_methods(); private: static TextServerManager *singleton; - static TextServer *server; - enum { - MAX_SERVERS = 64 - }; - struct TextServerCreate { - String name; - CreateFunction create_function = nullptr; - uint32_t features = 0; - TextServer *instance = nullptr; - void *user_data = nullptr; - }; - - static TextServerCreate server_create_functions[MAX_SERVERS]; - static int server_create_count; + Ref<TextServer> primary_interface; + Vector<Ref<TextServer>> interfaces; public: _FORCE_INLINE_ static TextServerManager *get_singleton() { return singleton; } - static void register_create_function(const String &p_name, uint32_t p_features, CreateFunction p_function, void *p_user_data); - static int get_interface_count(); - static String get_interface_name(int p_index); - static uint32_t get_interface_features(int p_index); - static TextServer *initialize(int p_index, Error &r_error); - static TextServer *get_primary_interface(); - - /* GDScript wrappers */ - int _get_interface_count() const; - String _get_interface_name(int p_index) const; - uint32_t _get_interface_features(int p_index) const; - TextServer *_get_interface(int p_index) const; - Array _get_interfaces() const; - TextServer *_find_interface(const String &p_name) const; + void add_interface(const Ref<TextServer> &p_interface); + void remove_interface(const Ref<TextServer> &p_interface); + int get_interface_count() const; + Ref<TextServer> get_interface(int p_index) const; + Ref<TextServer> find_interface(const String &p_name) const; + Array get_interfaces() const; - bool _set_primary_interface(int p_index); - TextServer *_get_primary_interface() const; + _FORCE_INLINE_ Ref<TextServer> get_primary_interface() const { + return primary_interface; + } + Ref<TextServer> _get_primary_interface() const; + void set_primary_interface(const Ref<TextServer> &p_primary_interface); TextServerManager(); ~TextServerManager(); @@ -539,7 +525,7 @@ public: /*************************************************************************/ -#define TS TextServerManager::get_primary_interface() +#define TS TextServerManager::get_singleton()->get_primary_interface() VARIANT_ENUM_CAST(TextServer::Direction); VARIANT_ENUM_CAST(TextServer::Orientation); @@ -552,4 +538,8 @@ VARIANT_ENUM_CAST(TextServer::Feature); VARIANT_ENUM_CAST(TextServer::ContourPointTag); VARIANT_ENUM_CAST(TextServer::SpacingType); +GDVIRTUAL_NATIVE_PTR(Glyph); +GDVIRTUAL_NATIVE_PTR(Glyph *); +GDVIRTUAL_NATIVE_PTR(CaretInfo); + #endif // TEXT_SERVER_H diff --git a/tests/test_code_edit.h b/tests/test_code_edit.h index fc8cec60af..0e31a976bf 100644 --- a/tests/test_code_edit.h +++ b/tests/test_code_edit.h @@ -3063,6 +3063,53 @@ TEST_CASE("[SceneTree][CodeEdit] line length guidelines") { memdelete(code_edit); } +TEST_CASE("[SceneTree][CodeEdit] Backspace delete") { + CodeEdit *code_edit = memnew(CodeEdit); + SceneTree::get_singleton()->get_root()->add_child(code_edit); + + /* Backspace with selection on first line. */ + code_edit->set_text(""); + code_edit->insert_text_at_caret("test backspace"); + code_edit->select(0, 0, 0, 5); + code_edit->backspace(); + CHECK(code_edit->get_line(0) == "backspace"); + + /* Backspace with selection on first line and caret at the beginning of file. */ + code_edit->set_text(""); + code_edit->insert_text_at_caret("test backspace"); + code_edit->select(0, 0, 0, 5); + code_edit->set_caret_column(0); + code_edit->backspace(); + CHECK(code_edit->get_line(0) == "backspace"); + + /* Move caret up to the previous line on backspace if carret is at the first column. */ + code_edit->set_text(""); + code_edit->insert_text_at_caret("line 1\nline 2"); + code_edit->set_caret_line(1); + code_edit->set_caret_column(0); + code_edit->backspace(); + CHECK(code_edit->get_line(0) == "line 1line 2"); + CHECK(code_edit->get_caret_line() == 0); + CHECK(code_edit->get_caret_column() == 6); + + /* Backspace delete all text if all text is selected. */ + code_edit->set_text(""); + code_edit->insert_text_at_caret("line 1\nline 2\nline 3"); + code_edit->select_all(); + code_edit->backspace(); + CHECK(code_edit->get_text() == ""); + + /* Backspace at the beginning without selection has no effect. */ + code_edit->set_text(""); + code_edit->insert_text_at_caret("line 1\nline 2\nline 3"); + code_edit->set_caret_line(0); + code_edit->set_caret_column(0); + code_edit->backspace(); + CHECK(code_edit->get_text() == "line 1\nline 2\nline 3"); + + memdelete(code_edit); +} + } // namespace TestCodeEdit #endif // TEST_CODE_EDIT_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index e4aa4c38ff..341fb1af61 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -174,10 +174,8 @@ struct GodotTestCaseListener : public doctest::IReporter { memnew(MessageQueue); GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); - memnew(TextServerManager); - Error err = OK; - TextServerManager::initialize(0, err); + Error err = OK; OS::get_singleton()->set_has_server_feature_callback(nullptr); for (int i = 0; i < DisplayServer::get_create_function_count(); i++) { if (String("headless") == DisplayServer::get_create_function_name(i)) { @@ -224,10 +222,6 @@ struct GodotTestCaseListener : public doctest::IReporter { clear_default_theme(); - if (TextServerManager::get_singleton()) { - memdelete(TextServerManager::get_singleton()); - } - if (navigation_3d_server) { memdelete(navigation_3d_server); navigation_3d_server = nullptr; diff --git a/tests/test_math.cpp b/tests/test_math.cpp index a44040dfe2..72272382ce 100644 --- a/tests/test_math.cpp +++ b/tests/test_math.cpp @@ -296,8 +296,8 @@ public: if (tk == TK_IDENTIFIER) { String name = value; if (use_next_class || p_known_class_name == name) { - for (Map<int, String>::Element *E = namespace_stack.front(); E; E = E->next()) { - class_name += E->get() + "."; + for (const KeyValue<int, String> &E : namespace_stack) { + class_name += E.value + "."; } class_name += String(value); break; diff --git a/tests/test_shader_lang.cpp b/tests/test_shader_lang.cpp index ad763b344e..6d58eb63cc 100644 --- a/tests/test_shader_lang.cpp +++ b/tests/test_shader_lang.cpp @@ -120,14 +120,14 @@ static String dump_node_code(SL::Node *p_node, int p_level) { case SL::Node::TYPE_SHADER: { SL::ShaderNode *pnode = (SL::ShaderNode *)p_node; - for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { + for (const KeyValue<StringName, SL::ShaderNode::Uniform> &E : pnode->uniforms) { String ucode = "uniform "; - ucode += _prestr(E->get().precision); - ucode += _typestr(E->get().type); - ucode += " " + String(E->key()); + ucode += _prestr(E.value.precision); + ucode += _typestr(E.value.type); + ucode += " " + String(E.key); - if (E->get().default_value.size()) { - ucode += " = " + get_constant_text(E->get().type, E->get().default_value); + if (E.value.default_value.size()) { + ucode += " = " + get_constant_text(E.value.type, E.value.default_value); } static const char *hint_name[SL::ShaderNode::Uniform::HINT_MAX] = { @@ -140,18 +140,18 @@ static String dump_node_code(SL::Node *p_node, int p_level) { "white" }; - if (E->get().hint) { - ucode += " : " + String(hint_name[E->get().hint]); + if (E.value.hint) { + ucode += " : " + String(hint_name[E.value.hint]); } code += ucode + "\n"; } - for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { + for (const KeyValue<StringName, SL::ShaderNode::Varying> &E : pnode->varyings) { String vcode = "varying "; - vcode += _prestr(E->get().precision); - vcode += _typestr(E->get().type); - vcode += " " + String(E->key()); + vcode += _prestr(E.value.precision); + vcode += _typestr(E.value.type); + vcode += " " + String(E.key); code += vcode + "\n"; } @@ -183,8 +183,8 @@ static String dump_node_code(SL::Node *p_node, int p_level) { //variables code += _mktab(p_level - 1) + "{\n"; - for (Map<StringName, SL::BlockNode::Variable>::Element *E = bnode->variables.front(); E; E = E->next()) { - code += _mktab(p_level) + _prestr(E->get().precision) + _typestr(E->get().type) + " " + E->key() + ";\n"; + for (const KeyValue<StringName, SL::BlockNode::Variable> &E : bnode->variables) { + code += _mktab(p_level) + _prestr(E.value.precision) + _typestr(E.value.type) + " " + E.key + ";\n"; } for (int i = 0; i < bnode->statements.size(); i++) { diff --git a/tests/test_text_server.h b/tests/test_text_server.h index b8ed4f89d0..af3df7bc79 100644 --- a/tests/test_text_server.h +++ b/tests/test_text_server.h @@ -41,19 +41,10 @@ namespace TestTextServer { TEST_SUITE("[[TextServer]") { TEST_CASE("[TextServer] Init, font loading and shaping") { - TextServerManager *tsman = memnew(TextServerManager); - Error err = OK; - - SUBCASE("[TextServer] Init") { - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - TextServer *ts = TextServerManager::initialize(i, err); - TEST_FAIL_COND((err != OK || ts == nullptr), "Text server ", TextServerManager::get_interface_name(i), " init failed."); - } - } - SUBCASE("[TextServer] Loading fonts") { - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - TextServer *ts = TextServerManager::initialize(i, err); + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); + TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); RID font = ts->create_font(); ts->font_set_data_ptr(font, _font_NotoSans_Regular, _font_NotoSans_Regular_size); @@ -63,8 +54,9 @@ TEST_SUITE("[[TextServer]") { } SUBCASE("[TextServer] Text layout: Font fallback") { - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - TextServer *ts = TextServerManager::initialize(i, err); + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); + TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); RID font1 = ts->create_font(); ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size); @@ -83,9 +75,10 @@ TEST_SUITE("[[TextServer]") { bool ok = ts->shaped_text_add_string(ctx, test, font, 16); TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); - Vector<TextServer::Glyph> glyphs = ts->shaped_text_get_glyphs(ctx); - TEST_FAIL_COND(glyphs.size() == 0, "Shaping failed"); - for (int j = 0; j < glyphs.size(); j++) { + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + for (int j = 0; j < gl_size; j++) { if (glyphs[j].start < 6) { TEST_FAIL_COND(glyphs[j].font_rid != font[1], "Incorrect font selected."); } @@ -110,8 +103,9 @@ TEST_SUITE("[[TextServer]") { } SUBCASE("[TextServer] Text layout: BiDi") { - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - TextServer *ts = TextServerManager::initialize(i, err); + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); + TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); if (!ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) { continue; @@ -134,9 +128,10 @@ TEST_SUITE("[[TextServer]") { bool ok = ts->shaped_text_add_string(ctx, test, font, 16); TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); - Vector<TextServer::Glyph> glyphs = ts->shaped_text_get_glyphs(ctx); - TEST_FAIL_COND(glyphs.size() == 0, "Shaping failed"); - for (int j = 0; j < glyphs.size(); j++) { + const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx); + int gl_size = ts->shaped_text_get_glyph_count(ctx); + TEST_FAIL_COND(gl_size == 0, "Shaping failed"); + for (int j = 0; j < gl_size; j++) { if (glyphs[j].count > 0) { if (glyphs[j].start < 7) { TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction."); @@ -160,8 +155,9 @@ TEST_SUITE("[[TextServer]") { } SUBCASE("[TextServer] Text layout: Line breaking") { - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - TextServer *ts = TextServerManager::initialize(i, err); + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); + TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); String test_1 = U"test test test"; // 5^ 10^ @@ -180,12 +176,17 @@ TEST_SUITE("[[TextServer]") { bool ok = ts->shaped_text_add_string(ctx, test_1, font, 16); TEST_FAIL_COND(!ok, "Adding text to the buffer failed."); - Vector<Vector2i> brks = ts->shaped_text_get_line_breaks(ctx, 1); - TEST_FAIL_COND(brks.size() != 3, "Invalid line breaks number."); - if (brks.size() == 3) { - TEST_FAIL_COND(brks[0] != Vector2i(0, 5), "Invalid line break position."); - TEST_FAIL_COND(brks[1] != Vector2i(5, 10), "Invalid line break position."); - TEST_FAIL_COND(brks[2] != Vector2i(10, 14), "Invalid line break position."); + PackedInt32Array brks = ts->shaped_text_get_line_breaks(ctx, 1); + TEST_FAIL_COND(brks.size() != 6, "Invalid line breaks number."); + if (brks.size() == 6) { + TEST_FAIL_COND(brks[0] != 0, "Invalid line break position."); + TEST_FAIL_COND(brks[1] != 5, "Invalid line break position."); + + TEST_FAIL_COND(brks[2] != 5, "Invalid line break position."); + TEST_FAIL_COND(brks[3] != 10, "Invalid line break position."); + + TEST_FAIL_COND(brks[4] != 10, "Invalid line break position."); + TEST_FAIL_COND(brks[5] != 14, "Invalid line break position."); } ts->free(ctx); @@ -198,8 +199,9 @@ TEST_SUITE("[[TextServer]") { } SUBCASE("[TextServer] Text layout: Justification") { - for (int i = 0; i < TextServerManager::get_interface_count(); i++) { - TextServer *ts = TextServerManager::initialize(i, err); + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i); + TEST_FAIL_COND(ts.is_null(), "Invalid TS interface."); RID font1 = ts->create_font(); ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size); @@ -263,7 +265,6 @@ TEST_SUITE("[[TextServer]") { font.clear(); } } - memdelete(tsman); } } }; // namespace TestTextServer diff --git a/tests/test_vector.h b/tests/test_vector.h index 02c56e59f6..bfdf389aa7 100644 --- a/tests/test_vector.h +++ b/tests/test_vector.h @@ -472,6 +472,19 @@ TEST_CASE("[Vector] Sort custom") { CHECK(vector[7] == "World"); } +TEST_CASE("[Vector] Search") { + Vector<int> vector; + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(5); + vector.push_back(8); + CHECK(vector.bsearch(2, true) == 1); + CHECK(vector.bsearch(2, false) == 2); + CHECK(vector.bsearch(5, true) == 3); + CHECK(vector.bsearch(5, false) == 4); +} + TEST_CASE("[Vector] Operators") { Vector<int> vector; vector.push_back(2); diff --git a/thirdparty/README.md b/thirdparty/README.md index 2d24beec15..3d32609088 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -20,13 +20,15 @@ Files extracted from upstream source: ## bullet - Upstream: https://github.com/bulletphysics/bullet3 -- Version: 3.08 (df09fd9ed37e365ceae884ca7f620b61607dae2e, 2020) +- Version: 3.17 (ebe1916b90acae8b13cd8c6b637d8327cdc64e94, 2021) - License: zlib Files extracted from upstream source: -- src/* apart from CMakeLists.txt and premake4.lua files -- LICENSE.txt +- `src/*` apart from CMakeLists.txt and premake4.lua files +- `LICENSE.txt`, and `VERSION` as `VERSION.txt` + +Includes a warning fix which should be upstreamed soon (see patch in `patches`). ## certs @@ -371,7 +373,9 @@ Files extracted from upstream repository: - `LICENSE.md`. An [experimental upstream feature](https://github.com/zeux/meshoptimizer/tree/simplify-attr), -has been backported, see patch in `patches` directory. +has been backported. On top of that, it was modified to report only distance error metrics +instead of a combination of distance and attribute errors. Patches for both changes can be +found in the `patches` directory. ## miniupnpc diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp index c79623bd57..6873a95d90 100644 --- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp +++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp @@ -80,6 +80,7 @@ struct ClipVertex btVector3 v; int id; //b2ContactID id; + //b2ContactID id; }; #define b2Dot(a, b) (a).dot(b) diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h index e085c40892..dbe82fd61f 100644 --- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h +++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -24,6 +24,7 @@ subject to the following restrictions: #define WANTS_DEACTIVATION 3 #define DISABLE_DEACTIVATION 4 #define DISABLE_SIMULATION 5 +#define FIXED_BASE_MULTI_BODY 6 struct btBroadphaseProxy; class btCollisionShape; @@ -304,7 +305,7 @@ public: SIMD_FORCE_INLINE bool isActive() const { - return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION)); + return ((getActivationState() != FIXED_BASE_MULTI_BODY) && (getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION)); } void setRestitution(btScalar rest) diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index 71184f36ac..f74dcabc54 100644 --- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -1037,7 +1037,7 @@ struct btSingleSweepCallback : public btBroadphaseRayCallback m_castShape(castShape) { btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin() - m_convexFromTrans.getOrigin()); - btVector3 rayDir = unnormalizedRayDir.normalized(); + btVector3 rayDir = unnormalizedRayDir.fuzzyZero() ? btVector3(btScalar(0.0), btScalar(0.0), btScalar(0.0)) : unnormalizedRayDir.normalized(); ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; @@ -1294,9 +1294,7 @@ public: btVector3 normalColor(1, 1, 0); m_debugDrawer->drawLine(center, center + normal, normalColor); } - m_debugDrawer->drawLine(wv0, wv1, m_color); - m_debugDrawer->drawLine(wv1, wv2, m_color); - m_debugDrawer->drawLine(wv2, wv0, m_color); + m_debugDrawer->drawTriangle(wv0, wv1, wv2, m_color, 1.0); } }; diff --git a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp index cab6980b65..01bf7f67f5 100644 --- a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp +++ b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp @@ -18,12 +18,57 @@ subject to the following restrictions: #include "LinearMath/btTransformUtil.h" btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const float* heightfieldData, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + /*heightScale=*/1, minHeight, maxHeight, upAxis, PHY_FLOAT, + flipQuadEdges); +} + +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, const double* heightfieldData, + btScalar minHeight, btScalar maxHeight, int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + /*heightScale=*/1, minHeight, maxHeight, upAxis, PHY_DOUBLE, + flipQuadEdges); +} + +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, const short* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + heightScale, minHeight, maxHeight, upAxis, PHY_SHORT, + flipQuadEdges); +} + +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, const unsigned char* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, int upAxis, bool flipQuadEdges) + : m_userValue3(0), m_triangleInfoMap(0) +{ + initialize(heightStickWidth, heightStickLength, heightfieldData, + heightScale, minHeight, maxHeight, upAxis, PHY_UCHAR, + flipQuadEdges); +} + +btHeightfieldTerrainShape::btHeightfieldTerrainShape( int heightStickWidth, int heightStickLength, const void* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, PHY_ScalarType hdt, bool flipQuadEdges) :m_userValue3(0), m_triangleInfoMap(0) { + // legacy constructor: Assumes PHY_FLOAT means btScalar. +#ifdef BT_USE_DOUBLE_PRECISION + if (hdt == PHY_FLOAT) hdt = PHY_DOUBLE; +#endif initialize(heightStickWidth, heightStickLength, heightfieldData, heightScale, minHeight, maxHeight, upAxis, hdt, flipQuadEdges); @@ -33,9 +78,12 @@ btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int h : m_userValue3(0), m_triangleInfoMap(0) { - // legacy constructor: support only float or unsigned char, - // and min height is zero + // legacy constructor: support only btScalar or unsigned char data, + // and min height is zero. PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR; +#ifdef BT_USE_DOUBLE_PRECISION + if (hdt == PHY_FLOAT) hdt = PHY_DOUBLE; +#endif btScalar minHeight = 0.0f; // previously, height = uchar * maxHeight / 65535. @@ -59,7 +107,7 @@ void btHeightfieldTerrainShape::initialize( // btAssert(heightScale) -- do we care? Trust caller here btAssert(minHeight <= maxHeight); // && "bad min/max height"); btAssert(upAxis >= 0 && upAxis < 3); // && "bad upAxis--should be in range [0,2]"); - btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT); // && "Bad height data type enum"); + btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_DOUBLE || hdt != PHY_SHORT); // && "Bad height data type enum"); // initialize member variables m_shapeType = TERRAIN_SHAPE_PROXYTYPE; @@ -152,6 +200,12 @@ btHeightfieldTerrainShape::getRawHeightFieldValue(int x, int y) const break; } + case PHY_DOUBLE: + { + val = m_heightfieldDataDouble[(y * m_heightStickWidth) + x]; + break; + } + case PHY_UCHAR: { unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y * m_heightStickWidth) + x]; @@ -232,6 +286,30 @@ getQuantized( return (int)(x + 0.5); } +// Equivalent to std::minmax({a, b, c}). +// Performs at most 3 comparisons. +static btHeightfieldTerrainShape::Range minmaxRange(btScalar a, btScalar b, btScalar c) +{ + if (a > b) + { + if (b > c) + return btHeightfieldTerrainShape::Range(c, a); + else if (a > c) + return btHeightfieldTerrainShape::Range(b, a); + else + return btHeightfieldTerrainShape::Range(b, c); + } + else + { + if (a > c) + return btHeightfieldTerrainShape::Range(c, b); + else if (b > c) + return btHeightfieldTerrainShape::Range(a, b); + else + return btHeightfieldTerrainShape::Range(a, c); + } +} + /// given input vector, return quantized version /** This routine is basically determining the gridpoint indices for a given @@ -334,7 +412,8 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback } // TODO If m_vboundsGrid is available, use it to determine if we really need to process this area - + + const Range aabbUpRange(aabbMin[m_upAxis], aabbMax[m_upAxis]); for (int j = startJ; j < endJ; j++) { for (int x = startX; x < endX; x++) @@ -349,29 +428,51 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j + x) & 1)) || (m_useZigzagSubdivision && !(j & 1))) { - //first triangle getVertex(x, j, vertices[indices[0]]); getVertex(x, j + 1, vertices[indices[1]]); getVertex(x + 1, j + 1, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x, j); - //second triangle - // getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman - getVertex(x + 1, j + 1, vertices[indices[1]]); + + // Skip triangle processing if the triangle is out-of-AABB. + Range upRange = minmaxRange(vertices[0][m_upAxis], vertices[1][m_upAxis], vertices[2][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x, j); + + // already set: getVertex(x, j, vertices[indices[0]]) + + // equivalent to: getVertex(x + 1, j + 1, vertices[indices[1]]); + vertices[indices[1]] = vertices[indices[2]]; + getVertex(x + 1, j, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x+1, j); + upRange.min = btMin(upRange.min, vertices[indices[2]][m_upAxis]); + upRange.max = btMax(upRange.max, vertices[indices[2]][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x + 1, j); } else { - //first triangle getVertex(x, j, vertices[indices[0]]); getVertex(x, j + 1, vertices[indices[1]]); getVertex(x + 1, j, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x, j); - //second triangle - getVertex(x + 1, j, vertices[indices[0]]); - //getVertex(x,j+1,vertices[1]); + + // Skip triangle processing if the triangle is out-of-AABB. + Range upRange = minmaxRange(vertices[0][m_upAxis], vertices[1][m_upAxis], vertices[2][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x, j); + + // already set: getVertex(x, j + 1, vertices[indices[1]]); + + // equivalent to: getVertex(x + 1, j, vertices[indices[0]]); + vertices[indices[0]] = vertices[indices[2]]; + getVertex(x + 1, j + 1, vertices[indices[2]]); - callback->processTriangle(vertices, 2 * x+1, j); + upRange.min = btMin(upRange.min, vertices[indices[2]][m_upAxis]); + upRange.max = btMax(upRange.max, vertices[indices[2]][m_upAxis]); + + if (upRange.overlaps(aabbUpRange)) + callback->processTriangle(vertices, 2 * x + 1, j); } } } @@ -846,4 +947,4 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize) void btHeightfieldTerrainShape::clearAccelerator() { m_vboundsGrid.clear(); -}
\ No newline at end of file +} diff --git a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h index 2cf3c00721..7e251fa71e 100644 --- a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h +++ b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h @@ -50,17 +50,15 @@ subject to the following restrictions: The heightfield heights are determined from the data type used for the heightfieldData array. - - PHY_UCHAR: height at a point is the uchar value at the + - unsigned char: height at a point is the uchar value at the grid point, multipled by heightScale. uchar isn't recommended because of its inability to deal with negative values, and low resolution (8-bit). - - PHY_SHORT: height at a point is the short int value at that grid + - short: height at a point is the short int value at that grid point, multipled by heightScale. - - PHY_FLOAT: height at a point is the float value at that grid - point. heightScale is ignored when using the float heightfield - data type. + - float or dobule: height at a point is the value at that grid point. Whatever the caller specifies as minHeight and maxHeight will be honored. The class will not inspect the heightfield to discover the actual minimum @@ -75,6 +73,14 @@ btHeightfieldTerrainShape : public btConcaveShape public: struct Range { + Range() {} + Range(btScalar min, btScalar max) : min(min), max(max) {} + + bool overlaps(const Range& other) const + { + return !(min > other.max || max < other.min); + } + btScalar min; btScalar max; }; @@ -95,7 +101,8 @@ protected: union { const unsigned char* m_heightfieldDataUnsignedChar; const short* m_heightfieldDataShort; - const btScalar* m_heightfieldDataFloat; + const float* m_heightfieldDataFloat; + const double* m_heightfieldDataDouble; const void* m_heightfieldDataUnknown; }; @@ -135,11 +142,33 @@ protected: public: BT_DECLARE_ALIGNED_ALLOCATOR(); - /// preferred constructor + /// preferred constructors + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const float* heightfieldData, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const double* heightfieldData, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const short* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, + const unsigned char* heightfieldData, btScalar heightScale, btScalar minHeight, btScalar maxHeight, + int upAxis, bool flipQuadEdges); + + /// legacy constructor /** This constructor supports a range of heightfield data types, and allows for a non-zero minimum height value. heightScale is needed for any integer-based heightfield data types. + + This legacy constructor considers `PHY_FLOAT` to mean `btScalar`. + With `BT_USE_DOUBLE_PRECISION`, it will expect `heightfieldData` + to be double-precision. */ btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, const void* heightfieldData, btScalar heightScale, @@ -150,7 +179,7 @@ public: /// legacy constructor /** The legacy constructor assumes the heightfield has a minimum height - of zero. Only unsigned char or floats are supported. For legacy + of zero. Only unsigned char or btScalar data are supported. For legacy compatibility reasons, heightScale is calculated as maxHeight / 65535 (and is only used when useFloatData = false). */ @@ -218,4 +247,4 @@ public: } }; -#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H
\ No newline at end of file +#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp index 7cb92fa3b4..d7588aedc8 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp @@ -33,8 +33,8 @@ namespace { -const btScalar SLEEP_EPSILON = btScalar(0.05); // this is a squared velocity (m^2 s^-2) -const btScalar SLEEP_TIMEOUT = btScalar(2); // in seconds +const btScalar INITIAL_SLEEP_EPSILON = btScalar(0.05); // this is a squared velocity (m^2 s^-2) +const btScalar INITIAL_SLEEP_TIMEOUT = btScalar(2); // in seconds } // namespace void btMultiBody::spatialTransform(const btMatrix3x3 &rotation_matrix, // rotates vectors in 'from' frame to vectors in 'to' frame @@ -110,6 +110,9 @@ btMultiBody::btMultiBody(int n_links, m_canSleep(canSleep), m_canWakeup(true), m_sleepTimer(0), + m_sleepEpsilon(INITIAL_SLEEP_EPSILON), + m_sleepTimeout(INITIAL_SLEEP_TIMEOUT), + m_userObjectPointer(0), m_userIndex2(-1), m_userIndex(-1), @@ -1411,7 +1414,7 @@ void btMultiBody::solveImatrix(const btSpatialForceVector &rhs, btSpatialMotionV } } -void btMultiBody::mulMatrix(btScalar *pA, btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const +void btMultiBody::mulMatrix(const btScalar *pA, const btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const { for (int row = 0; row < rowsA; row++) { @@ -2104,10 +2107,10 @@ void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep) motion += m_realBuf[i] * m_realBuf[i]; } - if (motion < SLEEP_EPSILON) + if (motion < m_sleepEpsilon) { m_sleepTimer += timestep; - if (m_sleepTimer > SLEEP_TIMEOUT) + if (m_sleepTimer > m_sleepTimeout) { goToSleep(); } diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h index 5a3efc9414..345970d261 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h @@ -545,7 +545,10 @@ public: { m_canWakeup = canWakeup; } - bool isAwake() const { return m_awake; } + bool isAwake() const + { + return m_awake; + } void wakeUp(); void goToSleep(); void checkMotionAndSleepIfRequired(btScalar timestep); @@ -726,6 +729,17 @@ public: bool isLinkAndAllAncestorsKinematic(const int i) const; + void setSleepThreshold(btScalar sleepThreshold) + { + m_sleepEpsilon = sleepThreshold; + } + + void setSleepTimeout(btScalar sleepTimeout) + { + this->m_sleepTimeout = sleepTimeout; + } + + private: btMultiBody(const btMultiBody &); // not implemented void operator=(const btMultiBody &); // not implemented @@ -745,7 +759,7 @@ private: } } - void mulMatrix(btScalar * pA, btScalar * pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const; + void mulMatrix(const btScalar *pA, const btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const; private: btMultiBodyLinkCollider *m_baseCollider; //can be NULL @@ -801,6 +815,8 @@ private: bool m_canSleep; bool m_canWakeup; btScalar m_sleepTimer; + btScalar m_sleepEpsilon; + btScalar m_sleepTimeout; void *m_userObjectPointer; int m_userIndex2; diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp index 1ba5861145..00d5fd5609 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp @@ -61,7 +61,8 @@ btScalar btMultiBodyConstraint::fillMultiBodyConstraint(btMultiBodySolverConstra btScalar lowerLimit, btScalar upperLimit, bool angConstraint, btScalar relaxation, - bool isFriction, btScalar desiredVelocity, btScalar cfmSlip) + bool isFriction, btScalar desiredVelocity, btScalar cfmSlip, + btScalar damping) { solverConstraint.m_multiBodyA = m_bodyA; solverConstraint.m_multiBodyB = m_bodyB; @@ -348,7 +349,7 @@ btScalar btMultiBodyConstraint::fillMultiBodyConstraint(btMultiBodySolverConstra { btScalar positionalError = 0.f; - btScalar velocityError = desiredVelocity - rel_vel; // * damping; + btScalar velocityError = (desiredVelocity - rel_vel) * damping; btScalar erp = infoGlobal.m_erp2; diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.h index 4a6007ee3e..1aaa07b69e 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.h +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraint.h @@ -94,7 +94,7 @@ protected: bool angConstraint = false, btScalar relaxation = 1.f, - bool isFriction = false, btScalar desiredVelocity = 0, btScalar cfmSlip = 0); + bool isFriction = false, btScalar desiredVelocity = 0, btScalar cfmSlip = 0, btScalar damping = 1.0); public: BT_DECLARE_ALIGNED_ALLOCATOR(); diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index fef95f0c4e..e7af332eb3 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -137,7 +137,14 @@ void btMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep) btMultiBodyLinkCollider* col = body->getBaseCollider(); if (col && col->getActivationState() == ACTIVE_TAG) { - col->setActivationState(WANTS_DEACTIVATION); + if (body->hasFixedBase()) + { + col->setActivationState(FIXED_BASE_MULTI_BODY); + } else + { + col->setActivationState(WANTS_DEACTIVATION); + } + col->setDeactivationTime(0.f); } for (int b = 0; b < body->getNumLinks(); b++) diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp index 4372489fa1..fec9b03213 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp @@ -43,6 +43,7 @@ void btMultiBodyJointMotor::finalizeMultiDof() unsigned int offset = 6 + (m_bodyA->getLink(m_linkA).m_dofOffset + linkDoF); // row 0: the lower bound + // row 0: the lower bound jacobianA(0)[offset] = 1; m_numDofsFinalized = m_jacSizeBoth; diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp index 5c20d2a0d4..00a7ef3579 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp @@ -26,10 +26,13 @@ btMultiBodySphericalJointMotor::btMultiBodySphericalJointMotor(btMultiBody* body : btMultiBodyConstraint(body, body, link, body->getLink(link).m_parent, 3, true, MULTIBODY_CONSTRAINT_SPHERICAL_MOTOR), m_desiredVelocity(0, 0, 0), m_desiredPosition(0,0,0,1), - m_kd(1.), - m_kp(0.2), + m_use_multi_dof_params(false), + m_kd(1., 1., 1.), + m_kp(0.2, 0.2, 0.2), m_erp(1), - m_rhsClamp(SIMD_INFINITY) + m_rhsClamp(SIMD_INFINITY), + m_maxAppliedImpulseMultiDof(maxMotorImpulse, maxMotorImpulse, maxMotorImpulse), + m_damping(1.0, 1.0, 1.0) { m_maxAppliedImpulse = maxMotorImpulse; @@ -45,6 +48,7 @@ void btMultiBodySphericalJointMotor::finalizeMultiDof() unsigned int offset = 6 + (m_bodyA->getLink(m_linkA).m_dofOffset + linkDoF); // row 0: the lower bound + // row 0: the lower bound jacobianA(0)[offset] = 1; m_numDofsFinalized = m_jacSizeBoth; @@ -138,7 +142,8 @@ btQuaternion relRot = currentQuat.inverse() * desiredQuat; btScalar currentVelocity = m_bodyA->getJointVelMultiDof(m_linkA)[dof]; btScalar desiredVelocity = this->m_desiredVelocity[row]; - btScalar velocityError = desiredVelocity - currentVelocity; + double kd = m_use_multi_dof_params ? m_kd[row % 3] : m_kd[0]; + btScalar velocityError = (desiredVelocity - currentVelocity) * kd; btMatrix3x3 frameAworld; frameAworld.setIdentity(); @@ -151,12 +156,16 @@ btQuaternion relRot = currentQuat.inverse() * desiredQuat; case btMultibodyLink::eSpherical: { btVector3 constraintNormalAng = frameAworld.getColumn(row % 3); - posError = m_kp*angleDiff[row % 3]; + double kp = m_use_multi_dof_params ? m_kp[row % 3] : m_kp[0]; + posError = kp*angleDiff[row % 3]; + double max_applied_impulse = m_use_multi_dof_params ? m_maxAppliedImpulseMultiDof[row % 3] : m_maxAppliedImpulse; fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, btVector3(0,0,0), dummy, dummy, posError, infoGlobal, - -m_maxAppliedImpulse, m_maxAppliedImpulse, true); + -max_applied_impulse, max_applied_impulse, true, + 1.0, false, 0, 0, + m_damping[row % 3]); constraintRow.m_orgConstraint = this; constraintRow.m_orgDofIndex = row; break; diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.h index 621beab5a4..bdeccc2e24 100644 --- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.h +++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.h @@ -26,10 +26,13 @@ class btMultiBodySphericalJointMotor : public btMultiBodyConstraint protected: btVector3 m_desiredVelocity; btQuaternion m_desiredPosition; - btScalar m_kd; - btScalar m_kp; + bool m_use_multi_dof_params; + btVector3 m_kd; + btVector3 m_kp; btScalar m_erp; btScalar m_rhsClamp; //maximum error + btVector3 m_maxAppliedImpulseMultiDof; + btVector3 m_damping; public: btMultiBodySphericalJointMotor(btMultiBody* body, int link, btScalar maxMotorImpulse); @@ -44,16 +47,32 @@ public: btMultiBodyJacobianData& data, const btContactSolverInfo& infoGlobal); - virtual void setVelocityTarget(const btVector3& velTarget, btScalar kd = 1.f) + virtual void setVelocityTarget(const btVector3& velTarget, btScalar kd = 1.0) + { + m_desiredVelocity = velTarget; + m_kd = btVector3(kd, kd, kd); + m_use_multi_dof_params = false; + } + + virtual void setVelocityTargetMultiDof(const btVector3& velTarget, const btVector3& kd = btVector3(1.0, 1.0, 1.0)) { m_desiredVelocity = velTarget; m_kd = kd; + m_use_multi_dof_params = true; } - virtual void setPositionTarget(const btQuaternion& posTarget, btScalar kp = 1.f) + virtual void setPositionTarget(const btQuaternion& posTarget, btScalar kp =1.f) + { + m_desiredPosition = posTarget; + m_kp = btVector3(kp, kp, kp); + m_use_multi_dof_params = false; + } + + virtual void setPositionTargetMultiDof(const btQuaternion& posTarget, const btVector3& kp = btVector3(1.f, 1.f, 1.f)) { m_desiredPosition = posTarget; m_kp = kp; + m_use_multi_dof_params = true; } virtual void setErp(btScalar erp) @@ -68,6 +87,28 @@ public: { m_rhsClamp = rhsClamp; } + + btScalar getMaxAppliedImpulseMultiDof(int i) const + { + return m_maxAppliedImpulseMultiDof[i]; + } + + void setMaxAppliedImpulseMultiDof(const btVector3& maxImp) + { + m_maxAppliedImpulseMultiDof = maxImp; + m_use_multi_dof_params = true; + } + + btScalar getDamping(int i) const + { + return m_damping[i]; + } + + void setDamping(const btVector3& damping) + { + m_damping = damping; + } + virtual void debugDraw(class btIDebugDraw* drawer) { //todo(erwincoumans) diff --git a/thirdparty/bullet/BulletDynamics/MLCPSolvers/btMLCPSolver.cpp b/thirdparty/bullet/BulletDynamics/MLCPSolvers/btMLCPSolver.cpp index 5d864f2757..ed4e0b686d 100644 --- a/thirdparty/bullet/BulletDynamics/MLCPSolvers/btMLCPSolver.cpp +++ b/thirdparty/bullet/BulletDynamics/MLCPSolvers/btMLCPSolver.cpp @@ -532,7 +532,7 @@ void btMLCPSolver::createMLCP(const btContactSolverInfo& infoGlobal) J_transpose = J.transpose(); btMatrixXu& tmp = m_scratchTmp; - + //Minv.printMatrix("Minv="); { { BT_PROFILE("J*Minv"); @@ -543,7 +543,7 @@ void btMLCPSolver::createMLCP(const btContactSolverInfo& infoGlobal) m_A = tmp * J_transpose; } } - + //J.printMatrix("J"); if (1) { // add cfm to the diagonal of m_A diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp index 4b11fccecb..e81680f019 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp +++ b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp @@ -405,6 +405,10 @@ void btDeformableBodySolver::predictMotion(btScalar solverdt) for (int i = 0; i < m_softBodies.size(); ++i) { btSoftBody* psb = m_softBodies[i]; + /* Clear contacts */ + psb->m_nodeRigidContacts.resize(0); + psb->m_faceRigidContacts.resize(0); + psb->m_faceNodeContacts.resize(0); if (psb->isActive()) { @@ -472,10 +476,6 @@ void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar d { psb->updateFaceTree(true, true); } - /* Clear contacts */ - psb->m_nodeRigidContacts.resize(0); - psb->m_faceRigidContacts.resize(0); - psb->m_faceNodeContacts.resize(0); /* Optimize dbvt's */ // psb->m_ndbvt.optimizeIncremental(1); // psb->m_fdbvt.optimizeIncremental(1); diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h index d218d96214..697408355c 100644 --- a/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h +++ b/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h @@ -29,7 +29,7 @@ class btDeformableMousePickingForce : public btDeformableLagrangianForce public: typedef btAlignedObjectArray<btVector3> TVStack; - btDeformableMousePickingForce(btScalar k, btScalar d, const btSoftBody::Face& face, btVector3 mouse_pos, btScalar maxForce = 0.3) : m_elasticStiffness(k), m_dampingStiffness(d), m_face(face), m_mouse_pos(mouse_pos), m_maxForce(maxForce) + btDeformableMousePickingForce(btScalar k, btScalar d, const btSoftBody::Face& face, const btVector3& mouse_pos, btScalar maxForce = 0.3) : m_elasticStiffness(k), m_dampingStiffness(d), m_face(face), m_mouse_pos(mouse_pos), m_maxForce(maxForce) { } diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.h b/thirdparty/bullet/BulletSoftBody/btSoftBody.h index f578487b8c..dfde8fd1e4 100644 --- a/thirdparty/bullet/BulletSoftBody/btSoftBody.h +++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.h @@ -1317,8 +1317,8 @@ public: } for (int k = 0; k < m_faceNodeContacts.size(); ++k) { - int i = indices[k]; - btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[i]; + int idx = indices[k]; + btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[idx]; btSoftBody::Node* node = c.m_node; btSoftBody::Face* face = c.m_face; const btVector3& w = c.m_bary; diff --git a/thirdparty/bullet/LinearMath/btIDebugDraw.h b/thirdparty/bullet/LinearMath/btIDebugDraw.h index 82ec19a69b..df4db2ff5a 100644 --- a/thirdparty/bullet/LinearMath/btIDebugDraw.h +++ b/thirdparty/bullet/LinearMath/btIDebugDraw.h @@ -4,8 +4,8 @@ Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. @@ -21,7 +21,7 @@ subject to the following restrictions: ///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations. ///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld. -///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum. +///A class that implements the btIDebugDraw interface will need to provide non-empty implementations of the the drawLine and getDebugMode methods at a minimum. ///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1] class btIDebugDraw { diff --git a/thirdparty/bullet/LinearMath/btScalar.h b/thirdparty/bullet/LinearMath/btScalar.h index 0402146af1..b239217bb6 100644 --- a/thirdparty/bullet/LinearMath/btScalar.h +++ b/thirdparty/bullet/LinearMath/btScalar.h @@ -25,7 +25,7 @@ subject to the following restrictions: #include <float.h> /* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/ -#define BT_BULLET_VERSION 308 +#define BT_BULLET_VERSION 317 inline int btGetVersion() { diff --git a/thirdparty/bullet/LinearMath/btSerializer.h b/thirdparty/bullet/LinearMath/btSerializer.h index 4d1c760e24..f18442f23d 100644 --- a/thirdparty/bullet/LinearMath/btSerializer.h +++ b/thirdparty/bullet/LinearMath/btSerializer.h @@ -480,8 +480,8 @@ public: } buffer[9] = '3'; - buffer[10] = '0'; - buffer[11] = '8'; + buffer[10] = '1'; + buffer[11] = '7'; } virtual void startSerialization() @@ -499,7 +499,6 @@ public: writeDNA(); //if we didn't pre-allocate a buffer, we need to create a contiguous buffer now - int mysize = 0; if (!m_totalSize) { if (m_buffer) @@ -511,14 +510,12 @@ public: unsigned char* currentPtr = m_buffer; writeHeader(m_buffer); currentPtr += BT_HEADER_LENGTH; - mysize += BT_HEADER_LENGTH; for (int i = 0; i < m_chunkPtrs.size(); i++) { int curLength = sizeof(btChunk) + m_chunkPtrs[i]->m_length; memcpy(currentPtr, m_chunkPtrs[i], curLength); btAlignedFree(m_chunkPtrs[i]); currentPtr += curLength; - mysize += curLength; } } diff --git a/thirdparty/bullet/VERSION.txt b/thirdparty/bullet/VERSION.txt new file mode 100644 index 0000000000..78c8a7428a --- /dev/null +++ b/thirdparty/bullet/VERSION.txt @@ -0,0 +1 @@ +3.17 diff --git a/thirdparty/bullet/patches/bullet-fix-warnings.patch b/thirdparty/bullet/patches/bullet-fix-warnings.patch new file mode 100644 index 0000000000..69cde1b16e --- /dev/null +++ b/thirdparty/bullet/patches/bullet-fix-warnings.patch @@ -0,0 +1,42 @@ +diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.h b/thirdparty/bullet/BulletSoftBody/btSoftBody.h +index f578487b8c..dfde8fd1e4 100644 +--- a/thirdparty/bullet/BulletSoftBody/btSoftBody.h ++++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.h +@@ -1317,8 +1317,8 @@ public: + } + for (int k = 0; k < m_faceNodeContacts.size(); ++k) + { +- int i = indices[k]; +- btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[i]; ++ int idx = indices[k]; ++ btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[idx]; + btSoftBody::Node* node = c.m_node; + btSoftBody::Face* face = c.m_face; + const btVector3& w = c.m_bary; +diff --git a/thirdparty/bullet/LinearMath/btSerializer.h b/thirdparty/bullet/LinearMath/btSerializer.h +index ce4fc34e20..11592d2ccd 100644 +--- a/thirdparty/bullet/LinearMath/btSerializer.h ++++ b/thirdparty/bullet/LinearMath/btSerializer.h +@@ -499,7 +499,6 @@ public: + writeDNA(); + + //if we didn't pre-allocate a buffer, we need to create a contiguous buffer now +- int mysize = 0; + if (!m_totalSize) + { + if (m_buffer) +@@ -511,14 +510,12 @@ public: + unsigned char* currentPtr = m_buffer; + writeHeader(m_buffer); + currentPtr += BT_HEADER_LENGTH; +- mysize += BT_HEADER_LENGTH; + for (int i = 0; i < m_chunkPtrs.size(); i++) + { + int curLength = sizeof(btChunk) + m_chunkPtrs[i]->m_length; + memcpy(currentPtr, m_chunkPtrs[i], curLength); + btAlignedFree(m_chunkPtrs[i]); + currentPtr += curLength; +- mysize += curLength; + } + } + diff --git a/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch b/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch new file mode 100644 index 0000000000..54132a6c86 --- /dev/null +++ b/thirdparty/meshoptimizer/patches/attribute-aware-simplify-distance-only-metric.patch @@ -0,0 +1,176 @@ +diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp +index 0f10ebef4b..cf5db4e119 100644 +--- a/thirdparty/meshoptimizer/simplifier.cpp ++++ b/thirdparty/meshoptimizer/simplifier.cpp +@@ -20,7 +20,7 @@ + #define TRACESTATS(i) (void)0 + #endif + +-#define ATTRIBUTES 8 ++#define ATTRIBUTES 3 + + // This work is based on: + // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997 +@@ -445,6 +445,7 @@ struct Collapse + float error; + unsigned int errorui; + }; ++ float distance_error; + }; + + static float normalize(Vector3& v) +@@ -525,6 +526,34 @@ static float quadricError(const Quadric& Q, const Vector3& v) + return fabsf(r) * s; + } + ++static float quadricErrorNoAttributes(const Quadric& Q, const Vector3& v) ++{ ++ float rx = Q.b0; ++ float ry = Q.b1; ++ float rz = Q.b2; ++ ++ rx += Q.a10 * v.y; ++ ry += Q.a21 * v.z; ++ rz += Q.a20 * v.x; ++ ++ rx *= 2; ++ ry *= 2; ++ rz *= 2; ++ ++ rx += Q.a00 * v.x; ++ ry += Q.a11 * v.y; ++ rz += Q.a22 * v.z; ++ ++ float r = Q.c; ++ r += rx * v.x; ++ r += ry * v.y; ++ r += rz * v.z; ++ ++ float s = Q.w == 0.f ? 0.f : 1.f / Q.w; ++ ++ return fabsf(r) * s; ++} ++ + static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, float w) + { + float aw = a * w; +@@ -680,7 +709,7 @@ static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3 + } + #endif + +-static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap) ++static void fillFaceQuadrics(Quadric* vertex_quadrics, Quadric* vertex_no_attrib_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap) + { + for (size_t i = 0; i < index_count; i += 3) + { +@@ -690,6 +719,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic + + Quadric Q; + quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f); ++ quadricAdd(vertex_no_attrib_quadrics[remap[i0]], Q); ++ quadricAdd(vertex_no_attrib_quadrics[remap[i1]], Q); ++ quadricAdd(vertex_no_attrib_quadrics[remap[i2]], Q); + + #if ATTRIBUTES + quadricUpdateAttributes(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], Q.w); +@@ -700,7 +732,7 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic + } + } + +-static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap, const unsigned char* vertex_kind, const unsigned int* loop, const unsigned int* loopback) ++static void fillEdgeQuadrics(Quadric* vertex_quadrics, Quadric* vertex_no_attrib_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap, const unsigned char* vertex_kind, const unsigned int* loop, const unsigned int* loopback) + { + for (size_t i = 0; i < index_count; i += 3) + { +@@ -744,6 +776,9 @@ static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indic + + quadricAdd(vertex_quadrics[remap[i0]], Q); + quadricAdd(vertex_quadrics[remap[i1]], Q); ++ ++ quadricAdd(vertex_no_attrib_quadrics[remap[i0]], Q); ++ quadricAdd(vertex_no_attrib_quadrics[remap[i1]], Q); + } + } + } +@@ -848,7 +883,7 @@ static size_t pickEdgeCollapses(Collapse* collapses, const unsigned int* indices + return collapse_count; + } + +-static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const Vector3* vertex_positions, const Quadric* vertex_quadrics, const unsigned int* remap) ++static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const Vector3* vertex_positions, const Quadric* vertex_quadrics, const Quadric* vertex_no_attrib_quadrics, const unsigned int* remap) + { + for (size_t i = 0; i < collapse_count; ++i) + { +@@ -868,10 +903,14 @@ static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const + float ei = quadricError(qi, vertex_positions[i1]); + float ej = quadricError(qj, vertex_positions[j1]); + ++ const Quadric& naqi = vertex_no_attrib_quadrics[remap[i0]]; ++ const Quadric& naqj = vertex_no_attrib_quadrics[remap[j0]]; ++ + // pick edge direction with minimal error + c.v0 = ei <= ej ? i0 : j0; + c.v1 = ei <= ej ? i1 : j1; + c.error = ei <= ej ? ei : ej; ++ c.distance_error = ei <= ej ? quadricErrorNoAttributes(naqi, vertex_positions[i1]) : quadricErrorNoAttributes(naqj, vertex_positions[j1]); + } + } + +@@ -968,7 +1007,7 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse + } + } + +-static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* collapse_locked, Quadric* vertex_quadrics, const Collapse* collapses, size_t collapse_count, const unsigned int* collapse_order, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, const Vector3* vertex_positions, const EdgeAdjacency& adjacency, size_t triangle_collapse_goal, float error_limit, float& result_error) ++static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* collapse_locked, Quadric* vertex_quadrics, Quadric* vertex_no_attrib_quadrics, const Collapse* collapses, size_t collapse_count, const unsigned int* collapse_order, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, const Vector3* vertex_positions, const EdgeAdjacency& adjacency, size_t triangle_collapse_goal, float error_limit, float& result_error) + { + size_t edge_collapses = 0; + size_t triangle_collapses = 0; +@@ -1030,6 +1069,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* + assert(collapse_remap[r1] == r1); + + quadricAdd(vertex_quadrics[r1], vertex_quadrics[r0]); ++ quadricAdd(vertex_no_attrib_quadrics[r1], vertex_no_attrib_quadrics[r0]); + + if (vertex_kind[i0] == Kind_Complex) + { +@@ -1067,7 +1107,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* + triangle_collapses += (vertex_kind[i0] == Kind_Border) ? 1 : 2; + edge_collapses++; + +- result_error = result_error < c.error ? c.error : result_error; ++ result_error = result_error < c.distance_error ? c.distance_error : result_error; + } + + #if TRACE +@@ -1455,9 +1495,11 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned + + Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count); + memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric)); ++ Quadric* vertex_no_attrib_quadrics = allocator.allocate<Quadric>(vertex_count); ++ memset(vertex_no_attrib_quadrics, 0, vertex_count * sizeof(Quadric)); + +- fillFaceQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap); +- fillEdgeQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap, vertex_kind, loop, loopback); ++ fillFaceQuadrics(vertex_quadrics, vertex_no_attrib_quadrics, indices, index_count, vertex_positions, remap); ++ fillEdgeQuadrics(vertex_quadrics, vertex_no_attrib_quadrics, indices, index_count, vertex_positions, remap, vertex_kind, loop, loopback); + + if (result != indices) + memcpy(result, indices, index_count * sizeof(unsigned int)); +@@ -1488,7 +1530,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned + if (edge_collapse_count == 0) + break; + +- rankEdgeCollapses(edge_collapses, edge_collapse_count, vertex_positions, vertex_quadrics, remap); ++ rankEdgeCollapses(edge_collapses, edge_collapse_count, vertex_positions, vertex_quadrics, vertex_no_attrib_quadrics, remap); + + #if TRACE > 1 + dumpEdgeCollapses(edge_collapses, edge_collapse_count, vertex_kind); +@@ -1507,7 +1549,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned + printf("pass %d: ", int(pass_count++)); + #endif + +- size_t collapses = performEdgeCollapses(collapse_remap, collapse_locked, vertex_quadrics, edge_collapses, edge_collapse_count, collapse_order, remap, wedge, vertex_kind, vertex_positions, adjacency, triangle_collapse_goal, error_limit, result_error); ++ size_t collapses = performEdgeCollapses(collapse_remap, collapse_locked, vertex_quadrics, vertex_no_attrib_quadrics, edge_collapses, edge_collapse_count, collapse_order, remap, wedge, vertex_kind, vertex_positions, adjacency, triangle_collapse_goal, error_limit, result_error); + + // no edges can be collapsed any more due to hitting the error limit or triangle collapse limit + if (collapses == 0) diff --git a/thirdparty/meshoptimizer/simplifier.cpp b/thirdparty/meshoptimizer/simplifier.cpp index 0f10ebef4b..cf5db4e119 100644 --- a/thirdparty/meshoptimizer/simplifier.cpp +++ b/thirdparty/meshoptimizer/simplifier.cpp @@ -20,7 +20,7 @@ #define TRACESTATS(i) (void)0 #endif -#define ATTRIBUTES 8 +#define ATTRIBUTES 3 // This work is based on: // Michael Garland and Paul S. Heckbert. Surface simplification using quadric error metrics. 1997 @@ -445,6 +445,7 @@ struct Collapse float error; unsigned int errorui; }; + float distance_error; }; static float normalize(Vector3& v) @@ -525,6 +526,34 @@ static float quadricError(const Quadric& Q, const Vector3& v) return fabsf(r) * s; } +static float quadricErrorNoAttributes(const Quadric& Q, const Vector3& v) +{ + float rx = Q.b0; + float ry = Q.b1; + float rz = Q.b2; + + rx += Q.a10 * v.y; + ry += Q.a21 * v.z; + rz += Q.a20 * v.x; + + rx *= 2; + ry *= 2; + rz *= 2; + + rx += Q.a00 * v.x; + ry += Q.a11 * v.y; + rz += Q.a22 * v.z; + + float r = Q.c; + r += rx * v.x; + r += ry * v.y; + r += rz * v.z; + + float s = Q.w == 0.f ? 0.f : 1.f / Q.w; + + return fabsf(r) * s; +} + static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, float w) { float aw = a * w; @@ -680,7 +709,7 @@ static void quadricUpdateAttributes(Quadric& Q, const Vector3& p0, const Vector3 } #endif -static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap) +static void fillFaceQuadrics(Quadric* vertex_quadrics, Quadric* vertex_no_attrib_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap) { for (size_t i = 0; i < index_count; i += 3) { @@ -690,6 +719,9 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic Quadric Q; quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], 1.f); + quadricAdd(vertex_no_attrib_quadrics[remap[i0]], Q); + quadricAdd(vertex_no_attrib_quadrics[remap[i1]], Q); + quadricAdd(vertex_no_attrib_quadrics[remap[i2]], Q); #if ATTRIBUTES quadricUpdateAttributes(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], Q.w); @@ -700,7 +732,7 @@ static void fillFaceQuadrics(Quadric* vertex_quadrics, const unsigned int* indic } } -static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap, const unsigned char* vertex_kind, const unsigned int* loop, const unsigned int* loopback) +static void fillEdgeQuadrics(Quadric* vertex_quadrics, Quadric* vertex_no_attrib_quadrics, const unsigned int* indices, size_t index_count, const Vector3* vertex_positions, const unsigned int* remap, const unsigned char* vertex_kind, const unsigned int* loop, const unsigned int* loopback) { for (size_t i = 0; i < index_count; i += 3) { @@ -744,6 +776,9 @@ static void fillEdgeQuadrics(Quadric* vertex_quadrics, const unsigned int* indic quadricAdd(vertex_quadrics[remap[i0]], Q); quadricAdd(vertex_quadrics[remap[i1]], Q); + + quadricAdd(vertex_no_attrib_quadrics[remap[i0]], Q); + quadricAdd(vertex_no_attrib_quadrics[remap[i1]], Q); } } } @@ -848,7 +883,7 @@ static size_t pickEdgeCollapses(Collapse* collapses, const unsigned int* indices return collapse_count; } -static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const Vector3* vertex_positions, const Quadric* vertex_quadrics, const unsigned int* remap) +static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const Vector3* vertex_positions, const Quadric* vertex_quadrics, const Quadric* vertex_no_attrib_quadrics, const unsigned int* remap) { for (size_t i = 0; i < collapse_count; ++i) { @@ -868,10 +903,14 @@ static void rankEdgeCollapses(Collapse* collapses, size_t collapse_count, const float ei = quadricError(qi, vertex_positions[i1]); float ej = quadricError(qj, vertex_positions[j1]); + const Quadric& naqi = vertex_no_attrib_quadrics[remap[i0]]; + const Quadric& naqj = vertex_no_attrib_quadrics[remap[j0]]; + // pick edge direction with minimal error c.v0 = ei <= ej ? i0 : j0; c.v1 = ei <= ej ? i1 : j1; c.error = ei <= ej ? ei : ej; + c.distance_error = ei <= ej ? quadricErrorNoAttributes(naqi, vertex_positions[i1]) : quadricErrorNoAttributes(naqj, vertex_positions[j1]); } } @@ -968,7 +1007,7 @@ static void sortEdgeCollapses(unsigned int* sort_order, const Collapse* collapse } } -static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* collapse_locked, Quadric* vertex_quadrics, const Collapse* collapses, size_t collapse_count, const unsigned int* collapse_order, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, const Vector3* vertex_positions, const EdgeAdjacency& adjacency, size_t triangle_collapse_goal, float error_limit, float& result_error) +static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* collapse_locked, Quadric* vertex_quadrics, Quadric* vertex_no_attrib_quadrics, const Collapse* collapses, size_t collapse_count, const unsigned int* collapse_order, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, const Vector3* vertex_positions, const EdgeAdjacency& adjacency, size_t triangle_collapse_goal, float error_limit, float& result_error) { size_t edge_collapses = 0; size_t triangle_collapses = 0; @@ -1030,6 +1069,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* assert(collapse_remap[r1] == r1); quadricAdd(vertex_quadrics[r1], vertex_quadrics[r0]); + quadricAdd(vertex_no_attrib_quadrics[r1], vertex_no_attrib_quadrics[r0]); if (vertex_kind[i0] == Kind_Complex) { @@ -1067,7 +1107,7 @@ static size_t performEdgeCollapses(unsigned int* collapse_remap, unsigned char* triangle_collapses += (vertex_kind[i0] == Kind_Border) ? 1 : 2; edge_collapses++; - result_error = result_error < c.error ? c.error : result_error; + result_error = result_error < c.distance_error ? c.distance_error : result_error; } #if TRACE @@ -1455,9 +1495,11 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count); memset(vertex_quadrics, 0, vertex_count * sizeof(Quadric)); + Quadric* vertex_no_attrib_quadrics = allocator.allocate<Quadric>(vertex_count); + memset(vertex_no_attrib_quadrics, 0, vertex_count * sizeof(Quadric)); - fillFaceQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap); - fillEdgeQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap, vertex_kind, loop, loopback); + fillFaceQuadrics(vertex_quadrics, vertex_no_attrib_quadrics, indices, index_count, vertex_positions, remap); + fillEdgeQuadrics(vertex_quadrics, vertex_no_attrib_quadrics, indices, index_count, vertex_positions, remap, vertex_kind, loop, loopback); if (result != indices) memcpy(result, indices, index_count * sizeof(unsigned int)); @@ -1488,7 +1530,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned if (edge_collapse_count == 0) break; - rankEdgeCollapses(edge_collapses, edge_collapse_count, vertex_positions, vertex_quadrics, remap); + rankEdgeCollapses(edge_collapses, edge_collapse_count, vertex_positions, vertex_quadrics, vertex_no_attrib_quadrics, remap); #if TRACE > 1 dumpEdgeCollapses(edge_collapses, edge_collapse_count, vertex_kind); @@ -1507,7 +1549,7 @@ size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned printf("pass %d: ", int(pass_count++)); #endif - size_t collapses = performEdgeCollapses(collapse_remap, collapse_locked, vertex_quadrics, edge_collapses, edge_collapse_count, collapse_order, remap, wedge, vertex_kind, vertex_positions, adjacency, triangle_collapse_goal, error_limit, result_error); + size_t collapses = performEdgeCollapses(collapse_remap, collapse_locked, vertex_quadrics, vertex_no_attrib_quadrics, edge_collapses, edge_collapse_count, collapse_order, remap, wedge, vertex_kind, vertex_positions, adjacency, triangle_collapse_goal, error_limit, result_error); // no edges can be collapsed any more due to hitting the error limit or triangle collapse limit if (collapses == 0) |