diff options
166 files changed, 1716 insertions, 1739 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 43ba5ef357..2c2a963a26 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -5,7 +5,7 @@ body: - type: markdown attributes: value: | - - Read our [CONTRIBUTING.md guide](CONTRIBUTING.md#reporting-bugs) on reporting bugs. + - Read our [CONTRIBUTING.md guide](https://github.com/godotengine/godot/blob/master/CONTRIBUTING.md#reporting-bugs) on reporting bugs. - Write a descriptive issue title above. - Search [open](https://github.com/godotengine/godot/issues) and [closed](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. - Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html). @@ -32,6 +32,7 @@ Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@ Fabian <supagu@gmail.com> Ferenc Arn <tagcup@yahoo.com> Ferenc Arn <tagcup@yahoo.com> <tagcup@users.noreply.github.com> +foxydevloper <12120644+foxydevloper@users.noreply.github.com> Fredia Huya-Kouadio <fhuyakou@gmail.com> Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@google.com> Geequlim <geequlim@gmail.com> @@ -56,6 +57,7 @@ Indah Sylvia <ISylvox@yahoo.com> J08nY <johny@neuromancer.sk> <jancar.jj@gmail.com> J08nY <johny@neuromancer.sk> <J08nY@users.noreply.github.com> Jakub Grzesik <kubecz3k@gmail.com> +janglee <merupatel123@gmail.com> Jérôme Gully <jerome.gully0@gmail.com> JFonS <joan.fonssanchez@gmail.com> Juan Linietsky <reduzio@gmail.com> @@ -92,6 +94,7 @@ Michael Alexsander <michaelalexsander@protonmail.com> Nathan Franke <natfra@pm.me> <nathanwfranke@gmail.com> Nathan Lovato <nathan@gdquest.com> Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com> +Nicholas Huelin <62965063+SirQuartz@users.noreply.github.com> Nils ANDRÉ-CHANG <nils@nilsand.re> Nils ANDRÉ-CHANG <nils@nilsand.re> <nils.andre.chang@gmail.com> Nuno Donato <nunodonato@gmail.com> <n.donato@estrelasustentavel.pt> diff --git a/AUTHORS.md b/AUTHORS.md index c5a971b345..5147da3700 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -35,6 +35,7 @@ name is available. Andrea Catania (AndreaCatania) Andrii Doroshenko (Xrayez) Andy Moss (MillionOstrich) + Angad Kambli (angad-k) Anish Bhobe (KidRigger) Anton Yabchinskiy (a12n) Anutrix @@ -44,6 +45,7 @@ name is available. Ben Brookshire (sheepandshepherd) Benjamin Larsson (Nallebeorn) Bernard Liebl (poke1024) + Bhuvan Vemula (Bhu1-V) Błażej Szczygieł (zaps166) Bojidar Marinov (bojidar-bg) Bruno Lourenço (MadEqua) @@ -65,6 +67,7 @@ name is available. Dmitry Koteroff (Krakean) Dominik Jasiński (dreamsComeTrue) DualMatrix + Ellen Poe (ellenhp) Emmanuel Barroga (codecustard) Emmanuel Leblond (touilleMan) Eoin O'Neill (Eoin-ONeill-Yokai) @@ -75,7 +78,11 @@ name is available. est31 Fabian Mathews (supagu) Fabio Alessandrelli (Faless) + fabriceci Ferenc Arn (tagcup) + follower + foxydevloper + François Belair (Razoric480) Franklin Sobrinho (TheHX) Fredia Huya-Kouadio (m4gr3d) Geequlim @@ -87,8 +94,11 @@ name is available. Hanif Bin Ariffin (hbina) Haoyu Qiu (timothyqiu) Hein-Pieter van Braam-Stewart (hpvb) + Hendrik Brucker (Geometror) + hilfazer Hiroshi Ogawa (hi-ogawa) homer666 + hoontee Hubert Jarosz (Marqin) Hugo Locurcio (Calinou) Ian Bishop (ianb96) @@ -108,6 +118,7 @@ name is available. Joshua Grams (JoshuaGrams) Juan Linietsky (reduz) Julian Murgia (StraToN) + Julien Nguyen (Blackiris) Justo Delgado (mrcdk) Kelly Thomas (KellyThomas) kleonc @@ -139,6 +150,7 @@ name is available. Matthias Hölzl (hoelzl) Max Hilbrunner (mhilbrunner) merumelu + Meru Patel (Janglee123) Michael Alexsander (YeldhamDev) MichiRecRoom (LikeLakers2) mrezai @@ -146,6 +158,7 @@ name is available. Nathan Franke (nathanfranke) Nathan Lovato (NathanLovato) Nathan Warden (NathanWarden) + Nicholas Huelin (SirQuartz) Nils André-Chang (NilsIrl) Noah Beard (TwistedTwigleg) Nuno Donato (nunodonato) @@ -190,6 +203,7 @@ name is available. Timo (toger5) Tomasz Chabora (KoBeWi) Twarit Waikar (IronicallySerious) + Umang Kalra (theoway) Vinzenz Feenstra (vinzenz) 박한얼 (volzhs) V. Vamsi Krishna (vkbsb) @@ -46,8 +46,8 @@ generous deed immortalized in the next stable release of Godot Engine. anti666 blurp Christian Baune - Christoffer Sundbom Christopher Montesano + Christopher Shifflett Daniel Edwards Darrin Massena David Mydlarz @@ -59,14 +59,13 @@ generous deed immortalized in the next stable release of Godot Engine. GameDev.net Hein-Pieter van Braam Jasper Brooks - Javary Co. Jay Sistar Jeffery Chiu John G Gentzel Jonah Stich Justin Arnold Justo Delgado Baudí - Kamil Brzezinski + Kamil Brzezinskip Marcel Kräml Marek Belski Matthieu Huvé @@ -77,8 +76,8 @@ generous deed immortalized in the next stable release of Godot Engine. Ninja_5tyl3 Patrick Horn Patrick Schmidt - Péter Magyar Rami + Relintai Ronnie Cheng Slobodan Milnovic Stephan Lanfermann @@ -99,9 +98,9 @@ generous deed immortalized in the next stable release of Godot Engine. Asher Glick Barugon Carlo Cabanilla - Chris Goddard Daniel James David Gehrig + David Graham David Snopek Don B Ed Morley @@ -123,7 +122,6 @@ generous deed immortalized in the next stable release of Godot Engine. Mason Bially Matthew Hillier Michael - m kaersten Monster Vial Officine Pixel S.n.c. Petrus Prinsloo @@ -135,7 +133,6 @@ generous deed immortalized in the next stable release of Godot Engine. Sarksus Scott B Sean - segfault-god Sergey Sofox Stephen Molyneaux @@ -150,13 +147,13 @@ generous deed immortalized in the next stable release of Godot Engine. Zaven Muradyan Adam Nakonieczny - Adrian Adamiak Alexander J Maynard Alex de la Mare Alexey Dyadchenko Alex Khayrullin alice gambrell Andrew Cunningham + Andrew Farr Antanas Paskauskas Antoni Batchelli Arch Henderson III @@ -174,11 +171,13 @@ generous deed immortalized in the next stable release of Godot Engine. Christian Leth Jeppesen Cow Craig Ostrin + Craig Scarborough Craig Smith Cristopher CzechBlueBear D dan didenko + Daniel Hernández Alcojor Daniel Tebbutt Darrian Little Dennis Belfrage @@ -219,6 +218,7 @@ generous deed immortalized in the next stable release of Godot Engine. Joel Fivat Johnathan Kupferer John Knight + Jonathan Turner Jose Malheiro Jose Manuel Muñoz Perez Joseph Crane @@ -244,7 +244,6 @@ generous deed immortalized in the next stable release of Godot Engine. Liam Smyth LoparPanda Luca Vazzano - Luc-Frédéric Langis MadScientistCarl Marcus Dobler Marcus Richter @@ -263,6 +262,7 @@ generous deed immortalized in the next stable release of Godot Engine. Michael Policastro MightyPossum MikadoSC + Mike Barbee minz1 MuffinManKen nate etan @@ -327,10 +327,10 @@ generous deed immortalized in the next stable release of Godot Engine. Vincent Cloutier Vlad Ceru Opran VoidPointer - Vramexon Winston Wojciech Chojnacki xzibiting + Yifan Lai Yuancheng Zhang Zie Weaver Zoran Kukulj @@ -338,9 +338,8 @@ generous deed immortalized in the next stable release of Godot Engine. ## Silver donors 1D_Inc - Abraham Haskins + Aaron Oldenburg Actual_Dio - Adam Adam Brunnmeier Adam Carr Adam Long @@ -372,9 +371,9 @@ generous deed immortalized in the next stable release of Godot Engine. Allan Davis Allen Schade Aloehart - Amanda Anders Marstein Kruke Andre Stackhouse + Andrew Groot andrew james morris Andrew Thomas Ano Nim @@ -388,10 +387,10 @@ generous deed immortalized in the next stable release of Godot Engine. Ashley Claymore Astier Mickael Aubrey Falconer - Audun Borgersen aurelien condomines AzulCrescent Balázs Batári + Baptiste Le Bourhis Bartosz Bielecki Benedikt Benoit Jauvin-Girard @@ -405,7 +404,6 @@ generous deed immortalized in the next stable release of Godot Engine. Blair Allen Bobby CC Wong Borkzilla - Boyd Trolinger Bram brian Brian Klein @@ -419,7 +417,6 @@ generous deed immortalized in the next stable release of Godot Engine. Cameron Meyer Carlos Cejudo Carl van der Geest - Cas Brugman Casey Cassidy James Cédric Givord @@ -440,6 +437,7 @@ generous deed immortalized in the next stable release of Godot Engine. Corchari Craig Maloney Craig Post + C. R. Messen damucz Daniel Cheney Daniel Johnson @@ -452,6 +450,7 @@ generous deed immortalized in the next stable release of Godot Engine. deadwithbread Devin Carraway Diego Pereira + Dima Fedotov Dmitry Fisher Dmytro Korchynskyi Dominik Wetzel @@ -468,6 +467,7 @@ generous deed immortalized in the next stable release of Godot Engine. Egon Elbre Elgenzay Elias Nykrem + Emerson MX Ephemeral Eric Stokes Eric Walkingshaw @@ -479,11 +479,11 @@ generous deed immortalized in the next stable release of Godot Engine. fby Fekinox Felix Bohmann - Flaredown Forty Doubleu Francisco Garcia Florez Francois Holland Frank + FrostMarble Game Endeavor Gary Thomas George Marques @@ -494,7 +494,6 @@ generous deed immortalized in the next stable release of Godot Engine. Greyson Richey Grid Grominet - Guillaume Audirac Guillaume Pham Ngoc Guldoman Hal A @@ -516,7 +515,6 @@ generous deed immortalized in the next stable release of Godot Engine. Jako Danar James James A F Manley - James Gary James Guardino James Quincy James Thomas @@ -527,7 +525,6 @@ generous deed immortalized in the next stable release of Godot Engine. Jason Bolton Jason Malcolm-Herzmark Jason Uechi - Jeferson R. P. Belmiro Jeff Hungerford Jeff Messer Jeffrey Berube @@ -542,6 +539,7 @@ generous deed immortalized in the next stable release of Godot Engine. John Szevin Jonah Branch Jonas + Jonas Arndt Jonas Bernemann Jonas Rudlang Jonas Yamazaki @@ -571,6 +569,7 @@ generous deed immortalized in the next stable release of Godot Engine. Justin Spedding Justin W. Flory KaDokta + Karol Porzycki Keedong Park Keinan Powers Keith Bradner @@ -582,6 +581,7 @@ generous deed immortalized in the next stable release of Godot Engine. Kevin van Rooijen Kiri Jolly Kjetil Haugland + Kodera Software Kolandrious Konstantin Goncharov kormai @@ -594,12 +594,10 @@ generous deed immortalized in the next stable release of Godot Engine. Kyle Burnett Kyle Jacobs Kyuppin - Lady Grach Lasse le Dous Laurent CHEA Laurent Tréguier Laxman Pradhan - LE BOURHIS LEMMiNO Leonardo Dimano Lin Chear @@ -625,10 +623,10 @@ generous deed immortalized in the next stable release of Godot Engine. Matt Edwards Matthew Booe Matt Sylvia + Maverick Max Fiedler Maxime Blade Maxwell - MC Melissa Mears Merlyn Morgan-Graham mewin @@ -644,14 +642,12 @@ generous deed immortalized in the next stable release of Godot Engine. Mike Mike Birkhead Mike Copley - Mike Cunningham Mitchell J. Wagner MJacred ModularMind Molinghu Molly Jameson MoltenGears - Morwyn MrAZIE Mrjemandem Nathan Fish @@ -677,9 +673,10 @@ generous deed immortalized in the next stable release of Godot Engine. oceoh Okatima Oleg Reva - Olle Soprani Omar Delarosa + Orfist Oriol Muñoz Princep + oscar1000108 Oscar Domingo Pascal Patrick Brock @@ -706,7 +703,6 @@ generous deed immortalized in the next stable release of Godot Engine. Rammeow RAMupgrade Remi Rampin - Rémi Verschelde Reneator Riccardo Marini Richard Hayes @@ -716,21 +712,25 @@ generous deed immortalized in the next stable release of Godot Engine. Robert Farr (Larington) Rob Ruana Rodrigo Loli + Roger Smith Roland Rząsa Roman Tinkov Ronald Ho Hip (CrimsonZA) Ronan Ross Squires + Roy Scayged Ryan Groom Sam Caulfield Sam Edson Scott Longley Sean Lynch Sebastian Michailidis + segfault-god SeongWan Kim SeungJong k Shaidak Shane + Shane Sicienski Shane Spoor simdee Simon Jonas Larsen @@ -741,6 +741,7 @@ generous deed immortalized in the next stable release of Godot Engine. smbe19 smo1704 Solene Waked + Spencer Everhart Squirrel Stéphane Roussel Steve Cloete @@ -757,7 +758,6 @@ generous deed immortalized in the next stable release of Godot Engine. thomas Thomas Bechtold Thomas Detoy - Thomas Horwath Tianren Qin Till1805 Tim Drumheller @@ -769,6 +769,7 @@ generous deed immortalized in the next stable release of Godot Engine. Toadile Tobias Bradtke Tom Coxon + Tom Webster Torgeir Lilleskog Torsten Crass toupeira @@ -779,7 +780,6 @@ generous deed immortalized in the next stable release of Godot Engine. Troy Bonneau Tryggve Sollid Turgut Temucin - Tyler Compton Tyler Stafos UltyX Uther @@ -802,7 +802,9 @@ generous deed immortalized in the next stable release of Godot Engine. Yan Shi Yegor Smirnov Zak Stephens + Zher Huei Lee 蕭惟允 + 貴宏 小松 郝晨煜 ## Bronze donors diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index a444b2e18e..e0ebd19376 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -74,8 +74,6 @@ static void gdnative_variant_destroy(GDNativeVariantPtr p_self) { // variant type -#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr) - static void gdnative_variant_call(GDNativeVariantPtr p_self, const GDNativeStringNamePtr p_method, const GDNativeVariantPtr *p_args, const GDNativeInt p_argcount, GDNativeVariantPtr r_return, GDNativeCallError *r_error) { Variant *self = (Variant *)p_self; const StringName *method = (const StringName *)p_method; @@ -83,7 +81,7 @@ static void gdnative_variant_call(GDNativeVariantPtr p_self, const GDNativeStrin Variant ret; Callable::CallError error; self->call(*method, args, p_argcount, ret, error); - memnew_placement_custom(r_return, Variant, Variant(ret)); + memnew_placement(r_return, Variant(ret)); if (r_error) { r_error->error = (GDNativeCallErrorType)(error.error); @@ -99,7 +97,7 @@ static void gdnative_variant_call_static(GDNativeVariantType p_type, const GDNat Variant ret; Callable::CallError error; Variant::call_static(type, *method, args, p_argcount, ret, error); - memnew_placement_custom(r_return, Variant, Variant(ret)); + memnew_placement(r_return, Variant(ret)); if (r_error) { r_error->error = (GDNativeCallErrorType)error.error; @@ -164,7 +162,7 @@ static void gdnative_variant_get(const GDNativeVariantPtr p_self, const GDNative const Variant *key = (const Variant *)p_key; bool valid; - memnew_placement_custom(r_ret, Variant, Variant(self->get(*key, &valid))); + memnew_placement(r_ret, Variant(self->get(*key, &valid))); *r_valid = valid; } @@ -173,7 +171,7 @@ static void gdnative_variant_get_named(const GDNativeVariantPtr p_self, const GD const StringName *key = (const StringName *)p_key; bool valid; - memnew_placement_custom(r_ret, Variant, Variant(self->get_named(*key, valid))); + memnew_placement(r_ret, Variant(self->get_named(*key, valid))); *r_valid = valid; } @@ -182,7 +180,7 @@ static void gdnative_variant_get_keyed(const GDNativeVariantPtr p_self, const GD const Variant *key = (const Variant *)p_key; bool valid; - memnew_placement_custom(r_ret, Variant, Variant(self->get_keyed(*key, valid))); + memnew_placement(r_ret, Variant(self->get_keyed(*key, valid))); *r_valid = valid; } @@ -191,7 +189,7 @@ static void gdnative_variant_get_indexed(const GDNativeVariantPtr p_self, GDNati bool valid; bool oob; - memnew_placement_custom(r_ret, Variant, Variant(self->get_indexed(p_index, valid, oob))); + memnew_placement(r_ret, Variant(self->get_indexed(p_index, valid, oob))); *r_valid = valid; *r_oob = oob; } @@ -222,7 +220,7 @@ static void gdnative_variant_iter_get(const GDNativeVariantPtr p_self, GDNativeV Variant *iter = (Variant *)r_iter; bool valid; - memnew_placement_custom(r_ret, Variant, Variant(self->iter_next(*iter, valid))); + memnew_placement(r_ret, Variant(self->iter_next(*iter, valid))); *r_valid = valid; } @@ -254,12 +252,12 @@ static void gdnative_variant_interpolate(const GDNativeVariantPtr p_a, const GDN static void gdnative_variant_duplicate(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep) { const Variant *self = (const Variant *)p_self; - memnew_placement_custom(r_ret, Variant, Variant(self->duplicate(p_deep))); + memnew_placement(r_ret, Variant(self->duplicate(p_deep))); } static void gdnative_variant_stringify(const GDNativeVariantPtr p_self, GDNativeStringPtr r_ret) { const Variant *self = (const Variant *)p_self; - memnew_placement_custom(r_ret, String, String(*self)); + memnew_placement(r_ret, String(*self)); } static GDNativeVariantType gdnative_variant_get_type(const GDNativeVariantPtr p_self) { @@ -288,7 +286,7 @@ static GDNativeBool gdnative_variant_has_key(const GDNativeVariantPtr p_self, co static void gdnative_variant_get_type_name(GDNativeVariantType p_type, GDNativeStringPtr r_ret) { String name = Variant::get_type_name((Variant::Type)p_type); - memnew_placement_custom(r_ret, String, String(name)); + memnew_placement(r_ret, String(name)); } static GDNativeBool gdnative_variant_can_convert(GDNativeVariantType p_from, GDNativeVariantType p_to) { @@ -508,7 +506,7 @@ static GDNativePtrKeyedChecker gdnative_variant_get_ptr_keyed_checker(GDNativeVa return (GDNativePtrKeyedChecker)Variant::get_member_ptr_keyed_checker(Variant::Type(p_type)); } static void gdnative_variant_get_constant_value(GDNativeVariantType p_type, const char *p_constant, GDNativeVariantPtr r_ret) { - memnew_placement_custom(r_ret, Variant, Variant(Variant::get_constant_value(Variant::Type(p_type), p_constant))); + memnew_placement(r_ret, Variant(Variant::get_constant_value(Variant::Type(p_type), p_constant))); } static GDNativePtrUtilityFunction gdnative_variant_get_ptr_utility_function(const char *p_function, GDNativeInt p_hash) { StringName function = p_function; diff --git a/core/input/input.cpp b/core/input/input.cpp index 2da50b7dff..8ba8b892ac 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -460,10 +460,6 @@ Vector3 Input::get_gyroscope() const { return gyroscope; } -void Input::parse_input_event(const Ref<InputEvent> &p_event) { - _parse_input_event_impl(p_event, false); -} - void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) { // Notes on mouse-touch emulation: // - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects @@ -472,8 +468,6 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em // - Emulated touch events are handed right to the main loop (i.e., the SceneTree) because they don't // require additional handling by this class. - _THREAD_SAFE_METHOD_ - Ref<InputEventKey> k = p_event; if (k.is_valid() && !k->is_echo() && k->get_keycode() != 0) { if (k->is_pressed()) { @@ -838,25 +832,37 @@ void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, co set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot); } -void Input::accumulate_input_event(const Ref<InputEvent> &p_event) { +void Input::parse_input_event(const Ref<InputEvent> &p_event) { + _THREAD_SAFE_METHOD_ + ERR_FAIL_COND(p_event.is_null()); - if (!use_accumulated_input) { - parse_input_event(p_event); - return; + if (use_accumulated_input) { + if (buffered_events.is_empty() || !buffered_events.back()->get()->accumulate(p_event)) { + buffered_events.push_back(p_event); + } + } else if (use_input_buffering) { + buffered_events.push_back(p_event); + } else { + _parse_input_event_impl(p_event, false); } - if (!accumulated_events.is_empty() && accumulated_events.back()->get()->accumulate(p_event)) { - return; //event was accumulated, exit +} + +void Input::flush_buffered_events() { + _THREAD_SAFE_METHOD_ + + while (buffered_events.front()) { + _parse_input_event_impl(buffered_events.front()->get(), false); + buffered_events.pop_front(); } +} - accumulated_events.push_back(p_event); +bool Input::is_using_input_buffering() { + return use_input_buffering; } -void Input::flush_accumulated_events() { - while (accumulated_events.front()) { - parse_input_event(accumulated_events.front()->get()); - accumulated_events.pop_front(); - } +void Input::set_use_input_buffering(bool p_enable) { + use_input_buffering = p_enable; } void Input::set_use_accumulated_input(bool p_enable) { @@ -864,7 +870,7 @@ void Input::set_use_accumulated_input(bool p_enable) { } void Input::release_pressed_events() { - flush_accumulated_events(); // this is needed to release actions strengths + flush_buffered_events(); // this is needed to release actions strengths keys_pressed.clear(); joy_buttons_pressed.clear(); diff --git a/core/input/input.h b/core/input/input.h index ee991aa725..6819fc8eb0 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -111,6 +111,7 @@ private: bool emulate_touch_from_mouse = false; bool emulate_mouse_from_touch = false; + bool use_input_buffering = false; bool use_accumulated_input = false; int mouse_from_touch_index = -1; @@ -213,7 +214,7 @@ private: void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated); - List<Ref<InputEvent>> accumulated_events; + List<Ref<InputEvent>> buffered_events; friend class DisplayServer; @@ -323,8 +324,9 @@ public: String get_joy_guid(int p_device) const; void set_fallback_mapping(String p_guid); - void accumulate_input_event(const Ref<InputEvent> &p_event); - void flush_accumulated_events(); + void flush_buffered_events(); + bool is_using_input_buffering(); + void set_use_input_buffering(bool p_enable); void set_use_accumulated_input(bool p_enable); void release_pressed_events(); diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 6e5c1a58ae..16bb92d94b 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -1210,6 +1210,22 @@ String InputEventScreenDrag::to_string() { return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), speed=(%s)", index, String(get_position()), String(get_relative()), String(get_speed())); } +bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) { + Ref<InputEventScreenDrag> drag = p_event; + if (drag.is_null()) + return false; + + if (get_index() != drag->get_index()) { + return false; + } + + set_position(drag->get_position()); + set_speed(drag->get_speed()); + relative += drag->get_relative(); + + return true; +} + void InputEventScreenDrag::_bind_methods() { ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index); ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index); diff --git a/core/input/input_event.h b/core/input/input_event.h index 57b6091123..517d63eb40 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -410,6 +410,8 @@ public: virtual String as_text() const override; virtual String to_string() override; + virtual bool accumulate(const Ref<InputEvent> &p_event) override; + InputEventScreenDrag() {} }; diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index a2894bc1d3..e1a5bfe6f2 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -32,9 +32,8 @@ #define GEOMETRY_2D_H #include "core/math/delaunay_2d.h" -#include "core/math/rect2.h" #include "core/math/triangulate.h" -#include "core/object/object.h" +#include "core/math/vector3i.h" #include "core/templates/vector.h" class Geometry2D { diff --git a/core/os/memory.h b/core/os/memory.h index 9d09626b8c..f67384a17e 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -35,6 +35,7 @@ #include "core/templates/safe_refcount.h" #include <stddef.h> +#include <new> #ifndef PAD_ALIGN #define PAD_ALIGN 16 //must always be greater than this at much @@ -92,15 +93,8 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) { #define memnew(m_class) _post_initialize(new ("") m_class) -_ALWAYS_INLINE_ void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description) { - //void *failptr=0; - //ERR_FAIL_COND_V( check < p_size , failptr); /** bug, or strange compiler, most likely */ - - return p_pointer; -} - #define memnew_allocator(m_class, m_allocator) _post_initialize(new (m_allocator::alloc) m_class) -#define memnew_placement(m_placement, m_class) _post_initialize(new (m_placement, sizeof(m_class), "") m_class) +#define memnew_placement(m_placement, m_class) _post_initialize(new (m_placement) m_class) _ALWAYS_INLINE_ bool predelete_handler(void *) { return true; @@ -140,7 +134,7 @@ void memdelete_allocator(T *p_class) { #define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count) template <typename T> -T *memnew_arr_template(size_t p_elements, const char *p_descr = "") { +T *memnew_arr_template(size_t p_elements) { if (p_elements == 0) { return nullptr; } @@ -158,7 +152,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") { /* call operator new */ for (size_t i = 0; i < p_elements; i++) { - new (&elems[i], sizeof(T), p_descr) T; + new (&elems[i]) T; } } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 7beecdb6b5..2fdf6e84e5 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -54,11 +54,27 @@ #define snprintf _snprintf_s #endif -#define MAX_DECIMALS 32 -#define UPPERCASE(m_c) (((m_c) >= 'a' && (m_c) <= 'z') ? ((m_c) - ('a' - 'A')) : (m_c)) -#define LOWERCASE(m_c) (((m_c) >= 'A' && (m_c) <= 'Z') ? ((m_c) + ('a' - 'A')) : (m_c)) -#define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9') -#define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F')) +static const int MAX_DECIMALS = 32; + +static _FORCE_INLINE_ bool is_digit(char32_t c) { + return (c >= '0' && c <= '9'); +} + +static _FORCE_INLINE_ bool is_hex_digit(char32_t c) { + return (is_digit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); +} + +static _FORCE_INLINE_ bool is_upper_case(char32_t c) { + return (c >= 'A' && c <= 'Z'); +} + +static _FORCE_INLINE_ bool is_lower_case(char32_t c) { + return (c >= 'a' && c <= 'z'); +} + +static _FORCE_INLINE_ char32_t lower_case(char32_t c) { + return (is_upper_case(c) ? (c + ('a' - 'A')) : c); +} const char CharString::_null = 0; const char16_t Char16String::_null = 0; @@ -738,6 +754,7 @@ bool String::operator<=(const String &p_str) const { bool String::operator>(const String &p_str) const { return p_str < *this; } + bool String::operator>=(const String &p_str) const { return !(*this < p_str); } @@ -871,8 +888,8 @@ signed char String::naturalnocasecmp_to(const String &p_str) const { while (*this_str) { if (!*that_str) { return 1; - } else if (IS_DIGIT(*this_str)) { - if (!IS_DIGIT(*that_str)) { + } else if (is_digit(*this_str)) { + if (!is_digit(*that_str)) { return -1; } @@ -881,10 +898,10 @@ signed char String::naturalnocasecmp_to(const String &p_str) const { const char32_t *that_substr = that_str; // Compare lengths of both numerical sequences, ignoring leading zeros - while (IS_DIGIT(*this_str)) { + while (is_digit(*this_str)) { this_str++; } - while (IS_DIGIT(*that_str)) { + while (is_digit(*that_str)) { that_str++; } while (*this_substr == '0') { @@ -912,7 +929,7 @@ signed char String::naturalnocasecmp_to(const String &p_str) const { this_substr++; that_substr++; } - } else if (IS_DIGIT(*that_str)) { + } else if (is_digit(*that_str)) { return 1; } else { if (_find_upper(*this_str) < _find_upper(*that_str)) { //more than @@ -962,26 +979,25 @@ String String::capitalize() const { String String::camelcase_to_underscore(bool lowercase) const { const char32_t *cstr = get_data(); String new_string; - const char A = 'A', Z = 'Z'; - const char a = 'a', z = 'z'; int start_index = 0; for (int i = 1; i < this->size(); i++) { - bool is_upper = cstr[i] >= A && cstr[i] <= Z; - bool is_number = cstr[i] >= '0' && cstr[i] <= '9'; + bool is_upper = is_upper_case(cstr[i]); + bool is_number = is_digit(cstr[i]); + bool are_next_2_lower = false; bool is_next_lower = false; bool is_next_number = false; - bool was_precedent_upper = cstr[i - 1] >= A && cstr[i - 1] <= Z; - bool was_precedent_number = cstr[i - 1] >= '0' && cstr[i - 1] <= '9'; + bool was_precedent_upper = is_upper_case(cstr[i - 1]); + bool was_precedent_number = is_digit(cstr[i - 1]); if (i + 2 < this->size()) { - are_next_2_lower = cstr[i + 1] >= a && cstr[i + 1] <= z && cstr[i + 2] >= a && cstr[i + 2] <= z; + are_next_2_lower = is_lower_case(cstr[i + 1]) && is_lower_case(cstr[i + 2]); } if (i + 1 < this->size()) { - is_next_lower = cstr[i + 1] >= a && cstr[i + 1] <= z; - is_next_number = cstr[i + 1] >= '0' && cstr[i + 1] <= '9'; + is_next_lower = is_lower_case(cstr[i + 1]); + is_next_number = is_digit(cstr[i + 1]); } const bool cond_a = is_upper && !was_precedent_upper && !was_precedent_number; @@ -2198,9 +2214,9 @@ int64_t String::hex_to_int() const { int64_t hex = 0; while (*s) { - char32_t c = LOWERCASE(*s); + char32_t c = lower_case(*s); int64_t n; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { n = c - '0'; } else if (c >= 'a' && c <= 'f') { n = (c - 'a') + 10; @@ -2239,7 +2255,7 @@ int64_t String::bin_to_int() const { int64_t binary = 0; while (*s) { - char32_t c = LOWERCASE(*s); + char32_t c = lower_case(*s); int64_t n; if (c == '0' || c == '1') { n = c - '0'; @@ -2269,7 +2285,7 @@ int64_t String::to_int() const { for (int i = 0; i < to; i++) { char32_t c = operator[](i); - if (c >= '0' && c <= '9') { + if (is_digit(c)) { bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8'))); ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small.")); integer *= 10; @@ -2298,7 +2314,7 @@ int64_t String::to_int(const char *p_str, int p_len) { for (int i = 0; i < to; i++) { char c = p_str[i]; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8'))); ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as integer, provided value is " + (sign == 1 ? "too big." : "too small.")); integer *= 10; @@ -2329,7 +2345,7 @@ int64_t String::to_int(const wchar_t *p_str, int p_len) { for (int i = 0; i < to; i++) { wchar_t c = p_str[i]; - if (c >= '0' && c <= '9') { + if (is_digit(c)) { bool overflow = (integer > INT64_MAX / 10) || (integer == INT64_MAX / 10 && ((sign == 1 && c > '7') || (sign == -1 && c > '8'))); ERR_FAIL_COND_V_MSG(overflow, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as integer, provided value is " + (sign == 1 ? "too big." : "too small.")); integer *= 10; @@ -2449,7 +2465,7 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point decPt = -1; for (mantSize = 0;; mantSize += 1) { c = *p; - if (!IS_DIGIT(c)) { + if (!is_digit(c)) { if ((c != '.') || (decPt >= 0)) { break; } @@ -2524,11 +2540,11 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point } expSign = false; } - if (!IS_DIGIT(char32_t(*p))) { + if (!is_digit(char32_t(*p))) { p = pExp; goto done; } - while (IS_DIGIT(char32_t(*p))) { + while (is_digit(char32_t(*p))) { exp = exp * 10 + (*p - '0'); p += 1; } @@ -2614,7 +2630,7 @@ int64_t String::to_int(const char32_t *p_str, int p_len, bool p_clamp) { char32_t c = *(str++); switch (reading) { case READING_SIGN: { - if (c >= '0' && c <= '9') { + if (is_digit(c)) { reading = READING_INT; // let it fallthrough } else if (c == '-') { @@ -2631,7 +2647,7 @@ int64_t String::to_int(const char32_t *p_str, int p_len, bool p_clamp) { [[fallthrough]]; } case READING_INT: { - if (c >= '0' && c <= '9') { + if (is_digit(c)) { if (integer > INT64_MAX / 10) { String number(""); str = p_str; @@ -3800,12 +3816,12 @@ bool String::is_valid_identifier() const { for (int i = 0; i < len; i++) { if (i == 0) { - if (str[0] >= '0' && str[0] <= '9') { + if (is_digit(str[0])) { return false; // no start with number plz } } - bool valid_char = (str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || str[i] == '_'; + bool valid_char = is_digit(str[i]) || is_lower_case(str[i]) || is_upper_case(str[i]) || str[i] == '_'; if (!valid_char) { return false; @@ -3830,10 +3846,7 @@ String String::uri_encode() const { String res; for (int i = 0; i < temp.length(); ++i) { char ord = temp[i]; - if (ord == '.' || ord == '-' || ord == '_' || ord == '~' || - (ord >= 'a' && ord <= 'z') || - (ord >= 'A' && ord <= 'Z') || - (ord >= '0' && ord <= '9')) { + if (ord == '.' || ord == '-' || ord == '_' || ord == '~' || is_lower_case(ord) || is_upper_case(ord) || is_digit(ord)) { res += ord; } else { char h_Val[3]; @@ -3855,9 +3868,9 @@ String String::uri_decode() const { for (int i = 0; i < src.length(); ++i) { if (src[i] == '%' && i + 2 < src.length()) { char ord1 = src[i + 1]; - if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) { + if (is_digit(ord1) || is_upper_case(ord1)) { char ord2 = src[i + 2]; - if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) { + if (is_digit(ord2) || is_upper_case(ord2)) { char bytes[3] = { (char)ord1, (char)ord2, 0 }; res += (char)strtol(bytes, nullptr, 16); i += 2; @@ -3963,7 +3976,7 @@ static _FORCE_INLINE_ int _xml_unescape(const char32_t *p_src, int p_src_len, ch char32_t ct = p_src[i]; if (ct == ';') { break; - } else if (ct >= '0' && ct <= '9') { + } else if (is_digit(ct)) { ct = ct - '0'; } else if (ct >= 'a' && ct <= 'f') { ct = (ct - 'a') + 10; @@ -4191,7 +4204,7 @@ bool String::is_valid_hex_number(bool p_with_prefix) const { for (int i = from; i < len; i++) { char32_t c = operator[](i); - if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + if (is_hex_digit(c)) { continue; } return false; @@ -4219,7 +4232,7 @@ bool String::is_valid_float() const { bool numbers_found = false; for (int i = from; i < len; i++) { - if (operator[](i) >= '0' && operator[](i) <= '9') { + if (is_digit(operator[](i))) { if (exponent_found) { exponent_values_found = true; } else { diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index c985593473..ba9babe0af 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -232,7 +232,7 @@ uint32_t CowData<T>::_copy_on_write() { uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true); - new (mem_new - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount + new (mem_new - 2) SafeNumeric<uint32_t>(1); //refcount *(mem_new - 1) = current_size; //size T *_data = (T *)(mem_new); @@ -286,14 +286,14 @@ Error CowData<T>::resize(int p_size) { uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true); ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY); *(ptr - 1) = 0; //size, currently none - new (ptr - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount + new (ptr - 2) SafeNumeric<uint32_t>(1); //refcount _ptr = (T *)ptr; } else { uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true); ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY); - new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount + new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); //refcount _ptr = (T *)(_ptrnew); } @@ -323,7 +323,7 @@ Error CowData<T>::resize(int p_size) { if (alloc_size != current_alloc_size) { uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true); ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY); - new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount + new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); //refcount _ptr = (T *)(_ptrnew); } diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml index 4f51adb8fc..0060368207 100644 --- a/doc/classes/DirectionalLight3D.xml +++ b/doc/classes/DirectionalLight3D.xml @@ -36,7 +36,6 @@ <member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5"> The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]. </member> - <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.05" /> <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" override="true" default="1.0" /> <member name="use_in_sky_only" type="bool" setter="set_sky_only" getter="is_sky_only" default="false"> If [code]true[/code], this [DirectionalLight3D] will not be used for anything except sky shaders. Use this for lights that impact your sky shader that you may want to hide from affecting the rest of the scene. For example, you may want to enable this when the sun in your sky shader falls below the horizon. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index f769ace836..0d1fa0e70f 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -717,6 +717,12 @@ Default [InputEventAction] to move up in the UI. [b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are necessary for the internal logic of several [Control]s. The events assigned to the action can however be modified. </member> + <member name="input_devices/buffering/agile_event_flushing" type="bool" setter="" getter="" default="false"> + If [code]true[/code], key/touch/joystick events will be flushed just before every idle and physics frame. + If [code]false[/code], such events will be flushed only once per process frame, between iterations of the engine. + Enabling this can greatly improve the responsiveness to input, specially in devices that need to run multiple physics frames per visible (process) frame, because they can't run at the target frame rate. + [b]Note:[/b] Currently implemented only on Android. + </member> <member name="input_devices/pen_tablet/driver" type="String" setter="" getter=""> Specifies the tablet driver to use. If left empty, the default driver will be used. </member> diff --git a/doc/classes/SpotLight3D.xml b/doc/classes/SpotLight3D.xml index f868503bbd..fde40ba6de 100644 --- a/doc/classes/SpotLight3D.xml +++ b/doc/classes/SpotLight3D.xml @@ -13,8 +13,7 @@ <methods> </methods> <members> - <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.02" /> - <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" override="true" default="1.0" /> + <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.03" /> <member name="spot_angle" type="float" setter="set_param" getter="get_param" default="45.0"> The spotlight's angle in degrees. </member> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 7b5cb2c459..4a62d3ec7b 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -296,19 +296,19 @@ Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum. </constant> <constant name="MSAA_DISABLED" value="0" enum="MSAA"> - Multisample antialiasing mode disabled. This is the default value, and also the fastest setting. + Multisample antialiasing mode disabled. This is the default value, and is also the fastest setting. </constant> <constant name="MSAA_2X" value="1" enum="MSAA"> - Use 2x Multisample Antialiasing. + Use 2× Multisample Antialiasing. This has a moderate performance cost. It helps reduce aliasing noticeably, but 4× MSAA still looks substantially better. </constant> <constant name="MSAA_4X" value="2" enum="MSAA"> - Use 4x Multisample Antialiasing. + Use 4× Multisample Antialiasing. This has a significant performance cost, and is generally a good compromise between performance and quality. </constant> <constant name="MSAA_8X" value="3" enum="MSAA"> - Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware. + Use 8× Multisample Antialiasing. This has a very high performance cost. The difference between 4× and 8× MSAA may not always be visible in real gameplay conditions. Likely unsupported on low-end and older hardware. </constant> <constant name="MSAA_16X" value="4" enum="MSAA"> - Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware. + Use 16× Multisample Antialiasing. This has a very high performance cost. The difference between 8× and 16× MSAA may not always be visible in real gameplay conditions. Likely unsupported on medium and low-end hardware. </constant> <constant name="MSAA_MAX" value="5" enum="MSAA"> Represents the size of the [enum MSAA] enum. diff --git a/doc/classes/VisualShaderNodeTransformMult.xml b/doc/classes/VisualShaderNodeTransformMult.xml deleted file mode 100644 index f26f60a1f3..0000000000 --- a/doc/classes/VisualShaderNodeTransformMult.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeTransformMult" inherits="VisualShaderNode" version="4.0"> - <brief_description> - Multiplies [Transform3D] by [Transform3D] within the visual shader graph. - </brief_description> - <description> - A multiplication operation on two transforms (4x4 matrices), with support for different multiplication operators. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <members> - <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeTransformMult.Operator" default="0"> - The multiplication type to be performed on the transforms. See [enum Operator] for options. - </member> - </members> - <constants> - <constant name="OP_AxB" value="0" enum="Operator"> - Multiplies transform [code]a[/code] by the transform [code]b[/code]. - </constant> - <constant name="OP_BxA" value="1" enum="Operator"> - Multiplies transform [code]b[/code] by the transform [code]a[/code]. - </constant> - <constant name="OP_AxB_COMP" value="2" enum="Operator"> - Performs a component-wise multiplication of transform [code]a[/code] by the transform [code]b[/code]. - </constant> - <constant name="OP_BxA_COMP" value="3" enum="Operator"> - Performs a component-wise multiplication of transform [code]b[/code] by the transform [code]a[/code]. - </constant> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeTransformOp.xml b/doc/classes/VisualShaderNodeTransformOp.xml new file mode 100644 index 0000000000..a628fa3e8d --- /dev/null +++ b/doc/classes/VisualShaderNodeTransformOp.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTransformOp" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A [Transform3D] operator to be used within the visual shader graph. + </brief_description> + <description> + Applies [member operator] to two transform (4x4 matrices) inputs. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeTransformOp.Operator" default="0"> + The type of the operation to be performed on the transforms. See [enum Operator] for options. + </member> + </members> + <constants> + <constant name="OP_AxB" value="0" enum="Operator"> + Multiplies transform [code]a[/code] by the transform [code]b[/code]. + </constant> + <constant name="OP_BxA" value="1" enum="Operator"> + Multiplies transform [code]b[/code] by the transform [code]a[/code]. + </constant> + <constant name="OP_AxB_COMP" value="2" enum="Operator"> + Performs a component-wise multiplication of transform [code]a[/code] by the transform [code]b[/code]. + </constant> + <constant name="OP_BxA_COMP" value="3" enum="Operator"> + Performs a component-wise multiplication of transform [code]b[/code] by the transform [code]a[/code]. + </constant> + <constant name="OP_ADD" value="4" enum="Operator"> + Adds two transforms. + </constant> + <constant name="OP_A_MINUS_B" value="5" enum="Operator"> + Subtracts the transform [code]a[/code] from the transform [code]b[/code]. + </constant> + <constant name="OP_B_MINUS_A" value="6" enum="Operator"> + Subtracts the transform [code]b[/code] from the transform [code]a[/code]. + </constant> + <constant name="OP_A_DIV_B" value="7" enum="Operator"> + Divides the transform [code]a[/code] by the transform [code]b[/code]. + </constant> + <constant name="OP_B_DIV_A" value="8" enum="Operator"> + Divides the transform [code]b[/code] by the transform [code]a[/code]. + </constant> + <constant name="OP_LIMITER" value="9" enum="Operator"> + Represents the size of the [enum Operator] enum. + </constant> + </constants> +</class> diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index 2cb73664f5..296a33d917 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -397,7 +397,7 @@ EditorLog::EditorLog() { show_search_button->set_focus_mode(FOCUS_NONE); show_search_button->set_toggle_mode(true); show_search_button->set_pressed(true); - show_search_button->set_shortcut(ED_SHORTCUT("editor/open_search", TTR("Open the search box."), KEY_MASK_CMD | KEY_F)); + show_search_button->set_shortcut(ED_SHORTCUT("editor/open_search", TTR("Focus Search/Filter Bar"), KEY_MASK_CMD | KEY_F)); show_search_button->set_shortcut_context(this); show_search_button->connect("toggled", callable_mp(this, &EditorLog::_set_search_visible)); hb_tools2->add_child(show_search_button); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 30edbd1e87..19a6d027bc 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -613,8 +613,10 @@ void EditorNode::_notification(int p_what) { _editor_select(EDITOR_3D); } - // Save the project after opening to mark it as last modified. - ProjectSettings::get_singleton()->save(); + // Save the project after opening to mark it as last modified, except in headless mode. + if (DisplayServer::get_singleton()->window_can_draw()) { + ProjectSettings::get_singleton()->save(); + } /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; @@ -6238,9 +6240,9 @@ EditorNode::EditorNode() { gui_base->add_child(warning); warning->connect("custom_action", callable_mp(this, &EditorNode::_copy_warning)); - ED_SHORTCUT("editor/next_tab", TTR("Next tab"), KEY_MASK_CMD + KEY_TAB); - ED_SHORTCUT("editor/prev_tab", TTR("Previous tab"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_TAB); - ED_SHORTCUT("editor/filter_files", TTR("Filter Files..."), KEY_MASK_CMD + KEY_MASK_ALT + KEY_P); + ED_SHORTCUT("editor/next_tab", TTR("Next Scene Tab"), KEY_MASK_CMD + KEY_TAB); + ED_SHORTCUT("editor/prev_tab", TTR("Previous Scene Tab"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_TAB); + ED_SHORTCUT("editor/filter_files", TTR("Focus FileSystem Filter"), KEY_MASK_CMD + KEY_MASK_ALT + KEY_P); command_palette = EditorCommandPalette::get_singleton(); command_palette->set_title(TTR("Command Palette")); @@ -7054,8 +7056,8 @@ EditorNode::EditorNode() { ED_SHORTCUT_AND_COMMAND("editor/editor_assetlib", TTR("Open Asset Library"), KEY_MASK_CTRL | KEY_F4); ED_SHORTCUT("editor/command_palette", TTR("Open Command Palette"), KEY_MASK_CTRL | KEY_MASK_SHIFT | KEY_P); #endif - ED_SHORTCUT_AND_COMMAND("editor/editor_next", TTR("Open the next Editor")); - ED_SHORTCUT_AND_COMMAND("editor/editor_prev", TTR("Open the previous Editor")); + ED_SHORTCUT_AND_COMMAND("editor/editor_next", TTR("Next Editor Tab")); + ED_SHORTCUT_AND_COMMAND("editor/editor_prev", TTR("Next Editor Tab")); screenshot_timer = memnew(Timer); screenshot_timer->set_one_shot(true); diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index 2ac8b8bd7d..d5bb21443c 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -341,10 +341,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const if (compress_mode == COMPRESS_VRAM_COMPRESSED) { mipmaps = true; - } - //optimize - if (compress_mode == COMPRESS_VRAM_COMPRESSED) { //if using video ram, optimize if (channel_pack == 0) { //remove alpha if not needed, so compression is more efficient diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 7fe12089c8..76c056ed33 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -41,6 +41,7 @@ #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" +#include "scene/2d/cpu_particles_2d.h" #include "scene/2d/gpu_particles_2d.h" #include "scene/2d/light_2d.h" #include "scene/2d/polygon_2d.h" @@ -5740,7 +5741,7 @@ void CanvasItemEditorViewport::_on_change_type_confirmed() { } CheckBox *check = Object::cast_to<CheckBox>(button_group->get_pressed_button()); - default_type = check->get_text(); + default_texture_node_type = check->get_text(); _perform_drop_data(); selector->hide(); } @@ -5832,14 +5833,13 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & child->set_name(name); Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(ResourceCache::get(path))); - Size2 texture_size = texture->get_size(); if (parent) { editor_data->get_undo_redo().add_do_method(parent, "add_child", child); editor_data->get_undo_redo().add_do_method(child, "set_owner", editor->get_edited_scene()); editor_data->get_undo_redo().add_do_reference(child); editor_data->get_undo_redo().add_undo_method(parent, "remove_child", child); - } else { // if we haven't parent, lets try to make a child as a parent. + } else { // If no parent is selected, set as root node of the scene. editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child); editor_data->get_undo_redo().add_do_method(child, "set_owner", editor->get_edited_scene()); editor_data->get_undo_redo().add_do_reference(child); @@ -5853,28 +5853,23 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); } - // handle with different property for texture - String property = "texture"; - List<PropertyInfo> props; - child->get_property_list(&props); - for (const PropertyInfo &E : props) { - if (E.name == "config/texture") { // Particles2D - property = "config/texture"; - break; - } else if (E.name == "texture/texture") { // Polygon2D - property = "texture/texture"; - break; - } else if (E.name == "normal") { // TouchScreenButton - property = "normal"; - break; - } + String node_class = child->get_class(); + if (node_class == "Polygon2D") { + editor_data->get_undo_redo().add_do_property(child, "texture/texture", texture); + } else if (node_class == "TouchScreenButton") { + editor_data->get_undo_redo().add_do_property(child, "normal", texture); + } else if (node_class == "TextureButton") { + editor_data->get_undo_redo().add_do_property(child, "texture_button", texture); + } else { + editor_data->get_undo_redo().add_do_property(child, "texture", texture); } - editor_data->get_undo_redo().add_do_property(child, property, texture); // make visible for certain node type - if (default_type == "NinePatchRect") { - editor_data->get_undo_redo().add_do_property(child, "rect/size", texture_size); - } else if (default_type == "Polygon2D") { + if (ClassDB::is_parent_class(node_class, "Control")) { + Size2 texture_size = texture->get_size(); + editor_data->get_undo_redo().add_do_property(child, "rect_size", texture_size); + } else if (node_class == "Polygon2D") { + Size2 texture_size = texture->get_size(); Vector<Vector2> list; list.push_back(Vector2(0, 0)); list.push_back(Vector2(texture_size.width, 0)); @@ -5975,23 +5970,7 @@ void CanvasItemEditorViewport::_perform_drop_data() { } else { Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res)); if (texture != nullptr && texture.is_valid()) { - Node *child; - if (default_type == "Light2D") { - child = memnew(Light2D); - } else if (default_type == "GPUParticles2D") { - child = memnew(GPUParticles2D); - } else if (default_type == "Polygon2D") { - child = memnew(Polygon2D); - } else if (default_type == "TouchScreenButton") { - child = memnew(TouchScreenButton); - } else if (default_type == "TextureRect") { - child = memnew(TextureRect); - } else if (default_type == "NinePatchRect") { - child = memnew(NinePatchRect); - } else { - child = memnew(Sprite2D); // default - } - + Node *child = _make_texture_node_type(default_texture_node_type); _create_nodes(target_node, child, path, drop_pos); } } @@ -6029,13 +6008,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian continue; } memdelete(instantiated_scene); - } else if (type == "Texture2D" || - type == "ImageTexture" || - type == "ViewportTexture" || - type == "CurveTexture" || - type == "GradientTexture" || - type == "StreamTexture2D" || - type == "AtlasTexture") { + } else if (ClassDB::is_parent_class(type, "Texture2D")) { Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res)); if (!texture.is_valid()) { continue; @@ -6052,7 +6025,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian } Transform2D trans = canvas_item_editor->get_canvas_transform(); preview_node->set_position((p_point - trans.get_origin()) / trans.get_scale().x); - label->set_text(vformat(TTR("Adding %s..."), default_type)); + label->set_text(vformat(TTR("Adding %s..."), default_texture_node_type)); } return can_instantiate; } @@ -6068,9 +6041,9 @@ void CanvasItemEditorViewport::_show_resource_type_selector() { for (int i = 0; i < btn_list.size(); i++) { CheckBox *check = Object::cast_to<CheckBox>(btn_list[i]); - check->set_pressed(check->get_text() == default_type); + check->set_pressed(check->get_text() == default_texture_node_type); } - selector->set_title(vformat(TTR("Add %s"), default_type)); + selector->set_title(vformat(TTR("Add %s"), default_texture_node_type)); selector->popup_centered(); } @@ -6126,6 +6099,30 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p } } +Node *CanvasItemEditorViewport::_make_texture_node_type(String texture_node_type) { + Node *node = nullptr; + if (texture_node_type == "Sprite2D") { + node = memnew(Sprite2D); + } else if (texture_node_type == "PointLight2D") { + node = memnew(PointLight2D); + } else if (texture_node_type == "CPUParticles2D") { + node = memnew(CPUParticles2D); + } else if (texture_node_type == "GPUParticles2D") { + node = memnew(GPUParticles2D); + } else if (texture_node_type == "Polygon2D") { + node = memnew(Polygon2D); + } else if (texture_node_type == "TouchScreenButton") { + node = memnew(TouchScreenButton); + } else if (texture_node_type == "TextureRect") { + node = memnew(TextureRect); + } else if (texture_node_type == "TextureButton") { + node = memnew(TextureButton); + } else if (texture_node_type == "NinePatchRect") { + node = memnew(NinePatchRect); + } + return node; +} + void CanvasItemEditorViewport::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -6145,22 +6142,24 @@ void CanvasItemEditorViewport::_bind_methods() { } CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas_item_editor) { - default_type = "Sprite2D"; + default_texture_node_type = "Sprite2D"; // Node2D - types.push_back("Sprite2D"); - types.push_back("Light2D"); - types.push_back("GPUParticles2D"); - types.push_back("Polygon2D"); - types.push_back("TouchScreenButton"); + texture_node_types.push_back("Sprite2D"); + texture_node_types.push_back("PointLight2D"); + texture_node_types.push_back("CPUParticles2D"); + texture_node_types.push_back("GPUParticles2D"); + texture_node_types.push_back("Polygon2D"); + texture_node_types.push_back("TouchScreenButton"); // Control - types.push_back("TextureRect"); - types.push_back("NinePatchRect"); + texture_node_types.push_back("TextureRect"); + texture_node_types.push_back("TextureButton"); + texture_node_types.push_back("NinePatchRect"); target_node = nullptr; editor = p_node; editor_data = editor->get_scene_tree_dock()->get_editor_data(); canvas_item_editor = p_canvas_item_editor; - preview_node = memnew(Node2D); + preview_node = memnew(Control); accept = memnew(AcceptDialog); editor->get_gui_base()->add_child(accept); @@ -6182,10 +6181,10 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte btn_group->set_h_size_flags(0); button_group.instantiate(); - for (int i = 0; i < types.size(); i++) { + for (int i = 0; i < texture_node_types.size(); i++) { CheckBox *check = memnew(CheckBox); btn_group->add_child(check); - check->set_text(types[i]); + check->set_text(texture_node_types[i]); check->connect("button_down", callable_mp(this, &CanvasItemEditorViewport::_on_select_type), varray(check)); check->set_button_group(button_group); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 495cd5f515..bff580315e 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -639,8 +639,10 @@ public: class CanvasItemEditorViewport : public Control { GDCLASS(CanvasItemEditorViewport, Control); - String default_type; - Vector<String> types; + // The type of node that will be created when dropping texture into the viewport. + String default_texture_node_type; + // Node types that are available to select from when dropping texture into viewport. + Vector<String> texture_node_types; Vector<String> selected_files; Node *target_node; @@ -649,7 +651,7 @@ class CanvasItemEditorViewport : public Control { EditorNode *editor; EditorData *editor_data; CanvasItemEditor *canvas_item_editor; - Node2D *preview_node; + Control *preview_node; AcceptDialog *accept; AcceptDialog *selector; Label *selector_label; @@ -662,6 +664,7 @@ class CanvasItemEditorViewport : public Control { void _on_select_type(Object *selected); void _on_change_type_confirmed(); void _on_change_type_closed(); + Node *_make_texture_node_type(String texture_node_type); void _create_preview(const Vector<String> &files) const; void _remove_preview(); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 8f0359bd0f..e9a67491aa 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -4030,7 +4030,7 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant continue; } memdelete(instantiated_scene); - } else if (type == "Mesh" || type == "ArrayMesh" || type == "PrimitiveMesh") { + } else if (ClassDB::is_parent_class(type, "Mesh")) { Ref<Mesh> mesh = ResourceLoader::load(files[i]); if (!mesh.is_valid()) { continue; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 668a15da37..e6762826dd 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -3409,8 +3409,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { ED_SHORTCUT("script_editor/window_sort", TTR("Sort")); ED_SHORTCUT("script_editor/window_move_up", TTR("Move Up"), KEY_MASK_SHIFT | KEY_MASK_ALT | KEY_UP); ED_SHORTCUT("script_editor/window_move_down", TTR("Move Down"), KEY_MASK_SHIFT | KEY_MASK_ALT | KEY_DOWN); - ED_SHORTCUT("script_editor/next_script", TTR("Next script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_PERIOD); // these should be KEY_GREATER and KEY_LESS but those don't work - ED_SHORTCUT("script_editor/prev_script", TTR("Previous script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_COMMA); + ED_SHORTCUT("script_editor/next_script", TTR("Next Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_PERIOD); // these should be KEY_GREATER and KEY_LESS but those don't work + ED_SHORTCUT("script_editor/prev_script", TTR("Previous Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_COMMA); set_process_unhandled_key_input(true); file_menu = memnew(MenuButton); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index d6ac238414..1fbf5eb0e6 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -110,7 +110,6 @@ void VisualShaderGraphPlugin::_bind_methods() { ClassDB::bind_method("set_expression", &VisualShaderGraphPlugin::set_expression); ClassDB::bind_method("update_curve", &VisualShaderGraphPlugin::update_curve); ClassDB::bind_method("update_curve_xyz", &VisualShaderGraphPlugin::update_curve_xyz); - ClassDB::bind_method("update_constant", &VisualShaderGraphPlugin::update_constant); } void VisualShaderGraphPlugin::register_shader(VisualShader *p_shader) { @@ -237,18 +236,6 @@ int VisualShaderGraphPlugin::get_constant_index(float p_constant) const { return 0; } -void VisualShaderGraphPlugin::update_constant(VisualShader::Type p_type, int p_node_id) { - if (p_type != visual_shader->get_shader_type() || !links.has(p_node_id) || !links[p_node_id].const_op) { - return; - } - VisualShaderNodeFloatConstant *float_const = Object::cast_to<VisualShaderNodeFloatConstant>(links[p_node_id].visual_node); - if (!float_const) { - return; - } - links[p_node_id].const_op->select(get_constant_index(float_const->get_constant())); - links[p_node_id].graph_node->set_size(Size2(-1, -1)); -} - void VisualShaderGraphPlugin::set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression) { if (p_type != visual_shader->get_shader_type() || !links.has(p_node_id) || !links[p_node_id].expression_edit) { return; @@ -267,10 +254,6 @@ void VisualShaderGraphPlugin::register_default_input_button(int p_node_id, int p links[p_node_id].input_ports.insert(p_port_id, { p_button }); } -void VisualShaderGraphPlugin::register_constant_option_btn(int p_node_id, OptionButton *p_button) { - links[p_node_id].const_op = p_button; -} - void VisualShaderGraphPlugin::register_expression_edit(int p_node_id, CodeEdit *p_expression_edit) { links[p_node_id].expression_edit = p_expression_edit; } @@ -322,7 +305,7 @@ void VisualShaderGraphPlugin::make_dirty(bool p_enabled) { } void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) { - links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } }); + links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr, { nullptr, nullptr, nullptr } }); } void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) { @@ -498,23 +481,6 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { custom_editor = hbox; } - Ref<VisualShaderNodeFloatConstant> float_const = vsnode; - if (float_const.is_valid()) { - HBoxContainer *hbox = memnew(HBoxContainer); - - hbox->add_child(custom_editor); - OptionButton *btn = memnew(OptionButton); - hbox->add_child(btn); - register_constant_option_btn(p_id, btn); - btn->add_item(""); - for (int i = 0; i < MAX_FLOAT_CONST_DEFS; i++) { - btn->add_item(float_constant_defs[i].name); - } - btn->select(get_constant_index(float_const->get_constant())); - btn->connect("item_selected", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_float_constant_selected), varray(p_id)); - custom_editor = hbox; - } - if (custom_editor && !vsnode->is_use_prop_slots() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { //will be embedded in first port } else if (custom_editor) { @@ -2182,6 +2148,16 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) { } } + // TRANSFORM_OP + { + VisualShaderNodeTransformOp *matOp = Object::cast_to<VisualShaderNodeTransformOp>(p_node); + + if (matOp) { + matOp->set_operator((VisualShaderNodeTransformOp::Operator)p_op_idx); + return; + } + } + // TRANSFORM_FUNC { VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(p_node); @@ -2944,6 +2920,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { selected_constants.clear(); selected_uniforms.clear(); selected_comment = -1; + selected_float_constant = -1; List<int> to_change; for (int i = 0; i < graph->get_child_count(); i++) { @@ -2963,6 +2940,10 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { if (constant_node != nullptr) { selected_constants.insert(id); } + VisualShaderNodeFloatConstant *float_constant_node = Object::cast_to<VisualShaderNodeFloatConstant>(node.ptr()); + if (float_constant_node != nullptr) { + selected_float_constant = id; + } VisualShaderNodeUniform *uniform_node = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); if (uniform_node != nullptr && uniform_node->is_convertible_to_constant()) { selected_uniforms.insert(id); @@ -2973,6 +2954,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { if (to_change.size() > 1) { selected_comment = -1; + selected_float_constant = -1; } if (to_change.is_empty() && copy_nodes_buffer.is_empty()) { @@ -2987,6 +2969,10 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { if (temp != -1) { popup_menu->remove_item(temp); } + temp = popup_menu->get_item_index(NodeMenuOptions::FLOAT_CONSTANTS); + if (temp != -1) { + popup_menu->remove_item(temp); + } temp = popup_menu->get_item_index(NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); if (temp != -1) { popup_menu->remove_item(temp); @@ -3008,14 +2994,23 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { popup_menu->remove_item(temp); } - if (selected_comment != -1) { + if (selected_constants.size() > 0 || selected_uniforms.size() > 0) { popup_menu->add_separator("", NodeMenuOptions::SEPARATOR2); - popup_menu->add_item(TTR("Set Comment Title"), NodeMenuOptions::SET_COMMENT_TITLE); - popup_menu->add_item(TTR("Set Comment Description"), NodeMenuOptions::SET_COMMENT_DESCRIPTION); - } - if (selected_constants.size() > 0 || selected_uniforms.size() > 0) { - popup_menu->add_separator("", NodeMenuOptions::SEPARATOR3); + if (selected_float_constant != -1) { + popup_menu->add_submenu_item(TTR("Float Constants"), "FloatConstants", int(NodeMenuOptions::FLOAT_CONSTANTS)); + + if (!constants_submenu) { + constants_submenu = memnew(PopupMenu); + constants_submenu->set_name("FloatConstants"); + + for (int i = 0; i < MAX_FLOAT_CONST_DEFS; i++) { + constants_submenu->add_item(float_constant_defs[i].name, i); + } + popup_menu->add_child(constants_submenu); + constants_submenu->connect("index_pressed", callable_mp(this, &VisualShaderEditor::_float_constant_selected)); + } + } if (selected_constants.size() > 0) { popup_menu->add_item(TTR("Convert Constant(s) to Uniform(s)"), NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS); @@ -3026,6 +3021,12 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { } } + if (selected_comment != -1) { + popup_menu->add_separator("", NodeMenuOptions::SEPARATOR3); + popup_menu->add_item(TTR("Set Comment Title"), NodeMenuOptions::SET_COMMENT_TITLE); + popup_menu->add_item(TTR("Set Comment Description"), NodeMenuOptions::SET_COMMENT_DESCRIPTION); + } + menu_point = graph->get_local_mouse_position(); Point2 gpos = Input::get_singleton()->get_mouse_position(); popup_menu->set_position(gpos); @@ -3495,27 +3496,20 @@ void VisualShaderEditor::_uniform_select_item(Ref<VisualShaderNodeUniformRef> p_ undo_redo->commit_action(); } -void VisualShaderEditor::_float_constant_selected(int p_index, int p_node) { - if (p_index == 0) { - graph_plugin->update_node_size(p_node); - return; - } - - --p_index; - - ERR_FAIL_INDEX(p_index, MAX_FLOAT_CONST_DEFS); +void VisualShaderEditor::_float_constant_selected(int p_which) { + ERR_FAIL_INDEX(p_which, MAX_FLOAT_CONST_DEFS); VisualShader::Type type = get_current_shader_type(); - Ref<VisualShaderNodeFloatConstant> node = visual_shader->get_node(type, p_node); - if (!node.is_valid()) { - return; + Ref<VisualShaderNodeFloatConstant> node = visual_shader->get_node(type, selected_float_constant); + ERR_FAIL_COND(!node.is_valid()); + + if (Math::is_equal_approx(node->get_constant(), float_constant_defs[p_which].value)) { + return; // same } - undo_redo->create_action(TTR("Set constant")); - undo_redo->add_do_method(node.ptr(), "set_constant", float_constant_defs[p_index].value); + undo_redo->create_action(vformat(TTR("Set Constant: %s"), float_constant_defs[p_which].name)); + undo_redo->add_do_method(node.ptr(), "set_constant", float_constant_defs[p_which].value); undo_redo->add_undo_method(node.ptr(), "set_constant", node->get_constant()); - undo_redo->add_do_method(graph_plugin.ptr(), "update_constant", type, p_node); - undo_redo->add_undo_method(graph_plugin.ptr(), "update_constant", type, p_node); undo_redo->commit_action(); } @@ -4460,6 +4454,7 @@ VisualShaderEditor::VisualShaderEditor() { // TRANSFORM add_options.push_back(AddOption("TransformFunc", "Transform", "Common", "VisualShaderNodeTransformFunc", TTR("Transform function."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("TransformOp", "Transform", "Common", "VisualShaderNodeTransformOp", TTR("Transform operator."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("OuterProduct", "Transform", "Composition", "VisualShaderNodeOuterProduct", TTR("Calculate the outer product of a pair of vectors.\n\nOuterProduct treats the first parameter 'c' as a column vector (matrix with one column) and the second parameter 'r' as a row vector (matrix with one row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix whose number of rows is the number of components in 'c' and whose number of columns is the number of components in 'r'."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("TransformCompose", "Transform", "Composition", "VisualShaderNodeTransformCompose", TTR("Composes transform from four vectors."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); @@ -4470,7 +4465,11 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("TransformMult", "Transform", "Operators", "VisualShaderNodeTransformMult", TTR("Multiplies transform by transform."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Add", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Sums two transforms."), VisualShaderNodeTransformOp::OP_ADD, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Divide", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Divides two transforms."), VisualShaderNodeTransformOp::OP_A_DIV_B, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Multiply", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Multiplies two transforms."), VisualShaderNodeTransformOp::OP_AxB, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("MultiplyComp", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), VisualShaderNodeTransformOp::OP_AxB_COMP, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Subtract", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), VisualShaderNodeTransformOp::OP_A_MINUS_B, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("TransformConstant", "Transform", "Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); @@ -4753,9 +4752,6 @@ public: if (p_property != "constant") { undo_redo->add_do_method(VisualShaderEditor::get_singleton()->get_graph_plugin(), "update_node_deferred", shader_type, node_id); undo_redo->add_undo_method(VisualShaderEditor::get_singleton()->get_graph_plugin(), "update_node_deferred", shader_type, node_id); - } else { - undo_redo->add_do_method(VisualShaderEditor::get_singleton()->get_graph_plugin(), "update_constant", shader_type, node_id); - undo_redo->add_undo_method(VisualShaderEditor::get_singleton()->get_graph_plugin(), "update_constant", shader_type, node_id); } undo_redo->commit_action(); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index f53726edb9..87bab16a45 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -73,7 +73,6 @@ private: Map<int, Port> output_ports; VBoxContainer *preview_box = nullptr; LineEdit *uniform_name = nullptr; - OptionButton *const_op = nullptr; CodeEdit *expression_edit = nullptr; CurveEditor *curve_editors[3] = { nullptr, nullptr, nullptr }; }; @@ -95,7 +94,6 @@ public: void register_output_port(int p_id, int p_port, TextureButton *p_button); void register_uniform_name(int p_id, LineEdit *p_uniform_name); void register_default_input_button(int p_node_id, int p_port_id, Button *p_button); - void register_constant_option_btn(int p_node_id, OptionButton *p_button); void register_expression_edit(int p_node_id, CodeEdit *p_expression_edit); void register_curve_editor(int p_node_id, int p_index, CurveEditor *p_curve_editor); void clear_links(); @@ -118,7 +116,6 @@ public: void set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name); void update_curve(int p_node_id); void update_curve_xyz(int p_node_id); - void update_constant(VisualShader::Type p_type, int p_node_id); void set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression); int get_constant_index(float p_constant) const; void update_node_size(int p_node_id); @@ -164,6 +161,7 @@ class VisualShaderEditor : public VBoxContainer { ConfirmationDialog *members_dialog; PopupMenu *popup_menu; + PopupMenu *constants_submenu = nullptr; MenuButton *tools; PopupPanel *comment_title_change_popup = nullptr; @@ -214,6 +212,7 @@ class VisualShaderEditor : public VBoxContainer { DELETE, DUPLICATE, SEPARATOR2, // ignore + FLOAT_CONSTANTS, CONVERT_CONSTANTS_TO_UNIFORMS, CONVERT_UNIFORMS_TO_CONSTANTS, SEPARATOR3, // ignore @@ -347,6 +346,7 @@ class VisualShaderEditor : public VBoxContainer { Set<int> selected_constants; Set<int> selected_uniforms; int selected_comment = -1; + int selected_float_constant = -1; void _convert_constants_to_uniforms(bool p_vice_versa); void _replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to); @@ -396,7 +396,7 @@ class VisualShaderEditor : public VBoxContainer { void _input_select_item(Ref<VisualShaderNodeInput> input, String name); void _uniform_select_item(Ref<VisualShaderNodeUniformRef> p_uniform, String p_name); - void _float_constant_selected(int p_index, int p_node); + void _float_constant_selected(int p_which); VisualShader::Type get_current_shader_type() const; diff --git a/main/main.cpp b/main/main.cpp index 7351dafa22..6764332f16 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1735,6 +1735,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) { Input *id = Input::get_singleton(); if (id) { + agile_input_event_flushing = GLOBAL_DEF("input_devices/buffering/agile_event_flushing", false); + if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) { bool found_touchscreen = false; @@ -2442,6 +2444,7 @@ uint32_t Main::frames = 0; uint32_t Main::frame = 0; bool Main::force_redraw_requested = false; int Main::iterating = 0; +bool Main::agile_input_event_flushing = false; bool Main::is_iterating() { return iterating > 0; @@ -2491,9 +2494,13 @@ bool Main::iteration() { bool exit = false; - Engine::get_singleton()->_in_physics = true; - for (int iters = 0; iters < advance.physics_steps; ++iters) { + if (Input::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) { + Input::get_singleton()->flush_buffered_events(); + } + + Engine::get_singleton()->_in_physics = true; + uint64_t physics_begin = OS::get_singleton()->get_ticks_usec(); PhysicsServer3D::get_singleton()->sync(); @@ -2522,9 +2529,13 @@ bool Main::iteration() { physics_process_ticks = MAX(physics_process_ticks, OS::get_singleton()->get_ticks_usec() - physics_begin); // keep the largest one for reference physics_process_max = MAX(OS::get_singleton()->get_ticks_usec() - physics_begin, physics_process_max); Engine::get_singleton()->_physics_frames++; + + Engine::get_singleton()->_in_physics = false; } - Engine::get_singleton()->_in_physics = false; + if (Input::get_singleton()->is_using_input_buffering() && agile_input_event_flushing) { + Input::get_singleton()->flush_buffered_events(); + } uint64_t process_begin = OS::get_singleton()->get_ticks_usec(); @@ -2587,6 +2598,11 @@ bool Main::iteration() { iterating--; + // Needed for OSs using input buffering regardless accumulation (like Android) + if (Input::get_singleton()->is_using_input_buffering() && !agile_input_event_flushing) { + Input::get_singleton()->flush_buffered_events(); + } + if (fixed_fps != -1) { return exit; } diff --git a/main/main.h b/main/main.h index 84077137ba..4911ff42b4 100644 --- a/main/main.h +++ b/main/main.h @@ -42,6 +42,7 @@ class Main { static uint32_t frame; static bool force_redraw_requested; static int iterating; + static bool agile_input_event_flushing; public: static bool is_project_manager(); diff --git a/modules/denoise/lightmap_denoiser.cpp b/modules/denoise/lightmap_denoiser.cpp index 003bc832b0..71dcc1d75f 100644 --- a/modules/denoise/lightmap_denoiser.cpp +++ b/modules/denoise/lightmap_denoiser.cpp @@ -31,6 +31,8 @@ #include "lightmap_denoiser.h" #include "denoise_wrapper.h" +#include "core/io/image.h" + LightmapDenoiser *LightmapDenoiserOIDN::create_oidn_denoiser() { return memnew(LightmapDenoiserOIDN); } diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp index 396109e576..f03c94aeb8 100644 --- a/modules/gdnative/gdnative/packed_arrays.cpp +++ b/modules/gdnative/gdnative/packed_arrays.cpp @@ -51,8 +51,6 @@ static_assert(sizeof(godot_packed_color_array) == sizeof(PackedColorArray), "Pac extern "C" { #endif -#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr) - // byte void GDAPI godot_packed_byte_array_new(godot_packed_byte_array *p_self) { diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 1d75ea206c..ec9aaa0a55 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -48,8 +48,6 @@ static_assert(sizeof(godot_variant) == sizeof(Variant), "Variant size mismatch") #pragma GCC optimize("-O0") #endif -#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr) - #if defined(__arm__) && defined(__GNUC__) && !defined(__clang__) && \ (__GNUC__ == 6 || (__GNUC__ == 7 && __GNUC_MINOR__ < 4) || (__GNUC__ == 8 && __GNUC_MINOR__ < 1)) #pragma GCC pop_options @@ -70,131 +68,131 @@ void GDAPI godot_variant_new_nil(godot_variant *r_dest) { void GDAPI godot_variant_new_bool(godot_variant *r_dest, const godot_bool p_b) { Variant *dest = (Variant *)r_dest; - memnew_placement_custom(dest, Variant, Variant(p_b)); + memnew_placement(dest, Variant(p_b)); } void GDAPI godot_variant_new_int(godot_variant *r_dest, const godot_int p_i) { Variant *dest = (Variant *)r_dest; - memnew_placement_custom(dest, Variant, Variant(p_i)); + memnew_placement(dest, Variant(p_i)); } void GDAPI godot_variant_new_float(godot_variant *r_dest, const godot_float p_r) { Variant *dest = (Variant *)r_dest; - memnew_placement_custom(dest, Variant, Variant(p_r)); + memnew_placement(dest, Variant(p_r)); } void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s) { Variant *dest = (Variant *)r_dest; const String *s = (const String *)p_s; - memnew_placement_custom(dest, Variant, Variant(*s)); + memnew_placement(dest, Variant(*s)); } void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s) { Variant *dest = (Variant *)r_dest; const StringName *s = (const StringName *)p_s; - memnew_placement_custom(dest, Variant, Variant(*s)); + memnew_placement(dest, Variant(*s)); } void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2) { Variant *dest = (Variant *)r_dest; const Vector2 *v2 = (const Vector2 *)p_v2; - memnew_placement_custom(dest, Variant, Variant(*v2)); + memnew_placement(dest, Variant(*v2)); } void GDAPI godot_variant_new_vector2i(godot_variant *r_dest, const godot_vector2i *p_v2) { Variant *dest = (Variant *)r_dest; const Vector2i *v2 = (const Vector2i *)p_v2; - memnew_placement_custom(dest, Variant, Variant(*v2)); + memnew_placement(dest, Variant(*v2)); } void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2) { Variant *dest = (Variant *)r_dest; const Rect2 *rect2 = (const Rect2 *)p_rect2; - memnew_placement_custom(dest, Variant, Variant(*rect2)); + memnew_placement(dest, Variant(*rect2)); } void GDAPI godot_variant_new_rect2i(godot_variant *r_dest, const godot_rect2i *p_rect2) { Variant *dest = (Variant *)r_dest; const Rect2i *rect2 = (const Rect2i *)p_rect2; - memnew_placement_custom(dest, Variant, Variant(*rect2)); + memnew_placement(dest, Variant(*rect2)); } void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 *p_v3) { Variant *dest = (Variant *)r_dest; const Vector3 *v3 = (const Vector3 *)p_v3; - memnew_placement_custom(dest, Variant, Variant(*v3)); + memnew_placement(dest, Variant(*v3)); } void GDAPI godot_variant_new_vector3i(godot_variant *r_dest, const godot_vector3i *p_v3) { Variant *dest = (Variant *)r_dest; const Vector3i *v3 = (const Vector3i *)p_v3; - memnew_placement_custom(dest, Variant, Variant(*v3)); + memnew_placement(dest, Variant(*v3)); } void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d) { Variant *dest = (Variant *)r_dest; const Transform2D *t2d = (const Transform2D *)p_t2d; - memnew_placement_custom(dest, Variant, Variant(*t2d)); + memnew_placement(dest, Variant(*t2d)); } void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane) { Variant *dest = (Variant *)r_dest; const Plane *plane = (const Plane *)p_plane; - memnew_placement_custom(dest, Variant, Variant(*plane)); + memnew_placement(dest, Variant(*plane)); } void GDAPI godot_variant_new_quaternion(godot_variant *r_dest, const godot_quaternion *p_quaternion) { Variant *dest = (Variant *)r_dest; const Quaternion *quaternion = (const Quaternion *)p_quaternion; - memnew_placement_custom(dest, Variant, Variant(*quaternion)); + memnew_placement(dest, Variant(*quaternion)); } void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aabb) { Variant *dest = (Variant *)r_dest; const AABB *aabb = (const AABB *)p_aabb; - memnew_placement_custom(dest, Variant, Variant(*aabb)); + memnew_placement(dest, Variant(*aabb)); } void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis) { Variant *dest = (Variant *)r_dest; const Basis *basis = (const Basis *)p_basis; - memnew_placement_custom(dest, Variant, Variant(*basis)); + memnew_placement(dest, Variant(*basis)); } void GDAPI godot_variant_new_transform3d(godot_variant *r_dest, const godot_transform3d *p_trans) { Variant *dest = (Variant *)r_dest; const Transform3D *trans = (const Transform3D *)p_trans; - memnew_placement_custom(dest, Variant, Variant(*trans)); + memnew_placement(dest, Variant(*trans)); } void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color) { Variant *dest = (Variant *)r_dest; const Color *color = (const Color *)p_color; - memnew_placement_custom(dest, Variant, Variant(*color)); + memnew_placement(dest, Variant(*color)); } void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np) { Variant *dest = (Variant *)r_dest; const NodePath *np = (const NodePath *)p_np; - memnew_placement_custom(dest, Variant, Variant(*np)); + memnew_placement(dest, Variant(*np)); } void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid) { Variant *dest = (Variant *)r_dest; const RID *rid = (const RID *)p_rid; - memnew_placement_custom(dest, Variant, Variant(*rid)); + memnew_placement(dest, Variant(*rid)); } void GDAPI godot_variant_new_callable(godot_variant *r_dest, const godot_callable *p_cb) { Variant *dest = (Variant *)r_dest; const Callable *cb = (const Callable *)p_cb; - memnew_placement_custom(dest, Variant, Variant(*cb)); + memnew_placement(dest, Variant(*cb)); } void GDAPI godot_variant_new_signal(godot_variant *r_dest, const godot_signal *p_signal) { Variant *dest = (Variant *)r_dest; const Signal *signal = (const Signal *)p_signal; - memnew_placement_custom(dest, Variant, Variant(*signal)); + memnew_placement(dest, Variant(*signal)); } void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj) { @@ -206,81 +204,81 @@ void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p ref = REF(ref_counted); } if (!ref.is_null()) { - memnew_placement_custom(dest, Variant, Variant(ref)); + memnew_placement(dest, Variant(ref)); } else { #if defined(DEBUG_METHODS_ENABLED) if (ref_counted) { ERR_PRINT("RefCounted object has 0 refcount in godot_variant_new_object - you lost it somewhere."); } #endif - memnew_placement_custom(dest, Variant, Variant(obj)); + memnew_placement(dest, Variant(obj)); } } void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict) { Variant *dest = (Variant *)r_dest; const Dictionary *dict = (const Dictionary *)p_dict; - memnew_placement_custom(dest, Variant, Variant(*dict)); + memnew_placement(dest, Variant(*dict)); } void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr) { Variant *dest = (Variant *)r_dest; const Array *arr = (const Array *)p_arr; - memnew_placement_custom(dest, Variant, Variant(*arr)); + memnew_placement(dest, Variant(*arr)); } void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba) { Variant *dest = (Variant *)r_dest; const PackedByteArray *pba = (const PackedByteArray *)p_pba; - memnew_placement_custom(dest, Variant, Variant(*pba)); + memnew_placement(dest, Variant(*pba)); } void GDAPI godot_variant_new_packed_int32_array(godot_variant *r_dest, const godot_packed_int32_array *p_pia) { Variant *dest = (Variant *)r_dest; const PackedInt32Array *pia = (const PackedInt32Array *)p_pia; - memnew_placement_custom(dest, Variant, Variant(*pia)); + memnew_placement(dest, Variant(*pia)); } void GDAPI godot_variant_new_packed_int64_array(godot_variant *r_dest, const godot_packed_int64_array *p_pia) { Variant *dest = (Variant *)r_dest; const PackedInt64Array *pia = (const PackedInt64Array *)p_pia; - memnew_placement_custom(dest, Variant, Variant(*pia)); + memnew_placement(dest, Variant(*pia)); } void GDAPI godot_variant_new_packed_float32_array(godot_variant *r_dest, const godot_packed_float32_array *p_pra) { Variant *dest = (Variant *)r_dest; const PackedFloat32Array *pra = (const PackedFloat32Array *)p_pra; - memnew_placement_custom(dest, Variant, Variant(*pra)); + memnew_placement(dest, Variant(*pra)); } void GDAPI godot_variant_new_packed_float64_array(godot_variant *r_dest, const godot_packed_float64_array *p_pra) { Variant *dest = (Variant *)r_dest; const PackedFloat64Array *pra = (const PackedFloat64Array *)p_pra; - memnew_placement_custom(dest, Variant, Variant(*pra)); + memnew_placement(dest, Variant(*pra)); } void GDAPI godot_variant_new_packed_string_array(godot_variant *r_dest, const godot_packed_string_array *p_psa) { Variant *dest = (Variant *)r_dest; const PackedStringArray *psa = (const PackedStringArray *)p_psa; - memnew_placement_custom(dest, Variant, Variant(*psa)); + memnew_placement(dest, Variant(*psa)); } void GDAPI godot_variant_new_packed_vector2_array(godot_variant *r_dest, const godot_packed_vector2_array *p_pv2a) { Variant *dest = (Variant *)r_dest; const PackedVector2Array *pv2a = (const PackedVector2Array *)p_pv2a; - memnew_placement_custom(dest, Variant, Variant(*pv2a)); + memnew_placement(dest, Variant(*pv2a)); } void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const godot_packed_vector3_array *p_pv3a) { Variant *dest = (Variant *)r_dest; const PackedVector3Array *pv3a = (const PackedVector3Array *)p_pv3a; - memnew_placement_custom(dest, Variant, Variant(*pv3a)); + memnew_placement(dest, Variant(*pv3a)); } void GDAPI godot_variant_new_packed_color_array(godot_variant *r_dest, const godot_packed_color_array *p_pca) { Variant *dest = (Variant *)r_dest; const PackedColorArray *pca = (const PackedColorArray *)p_pca; - memnew_placement_custom(dest, Variant, Variant(*pca)); + memnew_placement(dest, Variant(*pca)); } godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self) { @@ -568,7 +566,7 @@ void GDAPI godot_variant_call(godot_variant *p_self, const godot_string_name *p_ Variant ret; Callable::CallError error; self->call(*method, args, p_argcount, ret, error); - memnew_placement_custom(r_return, Variant, Variant(ret)); + memnew_placement(r_return, Variant(ret)); if (r_error) { r_error->error = (godot_variant_call_error_error)error.error; @@ -584,7 +582,7 @@ void GDAPI godot_variant_call_with_cstring(godot_variant *p_self, const char *p_ Variant ret; Callable::CallError error; self->call(method, args, p_argcount, ret, error); - memnew_placement_custom(r_return, Variant, Variant(ret)); + memnew_placement(r_return, Variant(ret)); if (r_error) { r_error->error = (godot_variant_call_error_error)error.error; @@ -600,7 +598,7 @@ void GDAPI godot_variant_call_static(godot_variant_type p_type, const godot_stri Variant ret; Callable::CallError error; Variant::call_static(type, *method, args, p_argcount, ret, error); - memnew_placement_custom(r_return, Variant, Variant(ret)); + memnew_placement(r_return, Variant(ret)); if (r_error) { r_error->error = (godot_variant_call_error_error)error.error; @@ -616,7 +614,7 @@ void GDAPI godot_variant_call_static_with_cstring(godot_variant_type p_type, con Variant ret; Callable::CallError error; Variant::call_static(type, method, args, p_argcount, ret, error); - memnew_placement_custom(r_return, Variant, Variant(ret)); + memnew_placement(r_return, Variant(ret)); if (r_error) { r_error->error = (godot_variant_call_error_error)error.error; @@ -679,7 +677,7 @@ godot_variant GDAPI godot_variant_get(const godot_variant *p_self, const godot_v ret = self->get(*key, r_valid); godot_variant result; - memnew_placement_custom(&result, Variant, Variant(ret)); + memnew_placement(&result, Variant(ret)); return result; } @@ -690,7 +688,7 @@ godot_variant GDAPI godot_variant_get_named(const godot_variant *p_self, const g ret = self->get_named(*key, *r_valid); godot_variant result; - memnew_placement_custom(&result, Variant, Variant(ret)); + memnew_placement(&result, Variant(ret)); return result; } @@ -701,7 +699,7 @@ godot_variant GDAPI godot_variant_get_named_with_cstring(const godot_variant *p_ ret = self->get_named(*key, *r_valid); godot_variant result; - memnew_placement_custom(&result, Variant, Variant(ret)); + memnew_placement(&result, Variant(ret)); return result; } @@ -712,7 +710,7 @@ godot_variant GDAPI godot_variant_get_keyed(const godot_variant *p_self, const g ret = self->get_keyed(*key, *r_valid); godot_variant result; - memnew_placement_custom(&result, Variant, Variant(ret)); + memnew_placement(&result, Variant(ret)); return result; } @@ -722,7 +720,7 @@ godot_variant GDAPI godot_variant_get_indexed(const godot_variant *p_self, godot ret = self->get_indexed(p_index, *r_valid, *r_oob); godot_variant result; - memnew_placement_custom(&result, Variant, Variant(ret)); + memnew_placement(&result, Variant(ret)); return result; } @@ -747,7 +745,7 @@ godot_variant GDAPI godot_variant_iter_get(const godot_variant *p_self, godot_va Variant result = self->iter_next(*iter, *r_valid); godot_variant ret; - memnew_placement_custom(&ret, Variant, Variant(result)); + memnew_placement(&ret, Variant(result)); return ret; } @@ -781,7 +779,7 @@ godot_variant GDAPI godot_variant_duplicate(const godot_variant *p_self, godot_b const Variant *self = (const Variant *)p_self; Variant result = self->duplicate(p_deep); godot_variant ret; - memnew_placement_custom(&ret, Variant, Variant(result)); + memnew_placement(&ret, Variant(result)); return ret; } @@ -789,7 +787,7 @@ godot_string GDAPI godot_variant_stringify(const godot_variant *p_self) { const Variant *self = (const Variant *)p_self; String result = *self; godot_string ret; - memnew_placement_custom(&ret, String, String(result)); + memnew_placement(&ret, String(result)); return ret; } @@ -811,7 +809,7 @@ godot_variant_type GDAPI godot_variant_get_operator_return_type(godot_variant_op godot_string GDAPI godot_variant_get_operator_name(godot_variant_operator p_operator) { String op_name = Variant::get_operator_name((Variant::Operator)p_operator); godot_string ret; - memnew_placement_custom(&ret, String, String(op_name)); + memnew_placement(&ret, String(op_name)); return ret; } @@ -916,7 +914,7 @@ void GDAPI godot_variant_get_builtin_method_list(godot_variant_type p_type, godo Variant::get_builtin_method_list((Variant::Type)p_type, &list); int i = 0; for (const StringName &E : list) { - memnew_placement_custom(&r_list[i], StringName, StringName(E)); + memnew_placement(&r_list[i], StringName(E)); } } @@ -971,7 +969,7 @@ void GDAPI godot_variant_get_member_list(godot_variant_type p_type, godot_string Variant::get_member_list((Variant::Type)p_type, &members); int i = 0; for (const StringName &E : members) { - memnew_placement_custom(&r_list[i++], StringName, StringName(E)); + memnew_placement(&r_list[i++], StringName(E)); } } @@ -1076,7 +1074,7 @@ void GDAPI godot_variant_get_constants_list(godot_variant_type p_type, godot_str int i = 0; Variant::get_constants_for_type((Variant::Type)p_type, &constants); for (const StringName &E : constants) { - memnew_placement_custom(&r_list[i++], StringName, StringName(E)); + memnew_placement(&r_list[i++], StringName(E)); } } @@ -1091,14 +1089,14 @@ bool GDAPI godot_variant_has_constant_with_cstring(godot_variant_type p_type, co godot_variant GDAPI godot_variant_get_constant_value(godot_variant_type p_type, const godot_string_name *p_constant) { Variant constant = Variant::get_constant_value((Variant::Type)p_type, *((const StringName *)p_constant)); godot_variant ret; - memnew_placement_custom(&ret, Variant, Variant(constant)); + memnew_placement(&ret, Variant(constant)); return ret; } godot_variant GDAPI godot_variant_get_constant_value_with_cstring(godot_variant_type p_type, const char *p_constant) { Variant constant = Variant::get_constant_value((Variant::Type)p_type, StringName(p_constant)); godot_variant ret; - memnew_placement_custom(&ret, Variant, Variant(constant)); + memnew_placement(&ret, Variant(constant)); return ret; } @@ -1183,14 +1181,14 @@ godot_variant_type GDAPI godot_variant_get_utility_function_argument_type_with_c godot_string GDAPI godot_variant_get_utility_function_argument_name(const godot_string_name *p_function, int p_argument) { String argument_name = Variant::get_utility_function_argument_name(*((const StringName *)p_function), p_argument); godot_string ret; - memnew_placement_custom(&ret, String, String(argument_name)); + memnew_placement(&ret, String(argument_name)); return ret; } godot_string GDAPI godot_variant_get_utility_function_argument_name_with_cstring(const char *p_function, int p_argument) { String argument_name = Variant::get_utility_function_argument_name(StringName(p_function), p_argument); godot_string ret; - memnew_placement_custom(&ret, String, String(argument_name)); + memnew_placement(&ret, String(argument_name)); return ret; } @@ -1228,7 +1226,7 @@ void GDAPI godot_variant_get_utility_function_list(godot_string_name *r_function Variant::get_utility_function_list(&functions); for (const StringName &E : functions) { - memnew_placement_custom(func++, StringName, StringName(E)); + memnew_placement(func++, StringName(E)); } } @@ -1258,7 +1256,7 @@ bool GDAPI godot_variant_has_key(const godot_variant *p_self, const godot_varian godot_string GDAPI godot_variant_get_type_name(godot_variant_type p_type) { String name = Variant::get_type_name((Variant::Type)p_type); godot_string ret; - memnew_placement_custom(&ret, String, String(name)); + memnew_placement(&ret, String(name)); return ret; } diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index c37fbb6bb3..f3b6d74b7d 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -2899,9 +2899,8 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, if (!converted) { undo_redo->add_do_method(script.ptr(), "data_connect", p_from.to_int(), from_port, p_to.to_int(), to_port); undo_redo->add_undo_method(script.ptr(), "data_disconnect", p_from.to_int(), from_port, p_to.to_int(), to_port); - } - // Update nodes in graph - if (!converted) { + + // Update nodes in graph undo_redo->add_do_method(this, "_update_graph", p_from.to_int()); undo_redo->add_do_method(this, "_update_graph", p_to.to_int()); undo_redo->add_undo_method(this, "_update_graph", p_from.to_int()); diff --git a/platform/android/SCsub b/platform/android/SCsub index 56fbd2f7e4..ecc72019e5 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -4,6 +4,7 @@ Import("env") android_files = [ "os_android.cpp", + "android_input_handler.cpp", "file_access_android.cpp", "audio_driver_opensl.cpp", "dir_access_jandroid.cpp", diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp new file mode 100644 index 0000000000..b9004c4989 --- /dev/null +++ b/platform/android/android_input_handler.cpp @@ -0,0 +1,395 @@ +/*************************************************************************/ +/* android_input_handler.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 "android_input_handler.h" + +#include "android_keys_utils.h" +#include "display_server_android.h" + +void AndroidInputHandler::process_joy_event(AndroidInputHandler::JoypadEvent p_event) { + switch (p_event.type) { + case JOY_EVENT_BUTTON: + Input::get_singleton()->joy_button(p_event.device, (JoyButton)p_event.index, p_event.pressed); + break; + case JOY_EVENT_AXIS: + Input::JoyAxisValue value; + value.min = -1; + value.value = p_event.value; + Input::get_singleton()->joy_axis(p_event.device, (JoyAxis)p_event.index, value); + break; + case JOY_EVENT_HAT: + Input::get_singleton()->joy_hat(p_event.device, (HatMask)p_event.hat); + break; + default: + return; + } +} + +void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> ev) { + ev->set_shift_pressed(shift_mem); + ev->set_alt_pressed(alt_mem); + ev->set_meta_pressed(meta_mem); + ev->set_ctrl_pressed(control_mem); +} + +void AndroidInputHandler::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) { + static char32_t prev_wc = 0; + char32_t unicode = p_unicode_char; + if ((p_unicode_char & 0xfffffc00) == 0xd800) { + if (prev_wc != 0) { + ERR_PRINT("invalid utf16 surrogate input"); + } + prev_wc = unicode; + return; // Skip surrogate. + } else if ((unicode & 0xfffffc00) == 0xdc00) { + if (prev_wc == 0) { + ERR_PRINT("invalid utf16 surrogate input"); + return; // Skip invalid surrogate. + } + unicode = (prev_wc << 10UL) + unicode - ((0xd800 << 10UL) + 0xdc00 - 0x10000); + prev_wc = 0; + } else { + prev_wc = 0; + } + + Ref<InputEventKey> ev; + ev.instantiate(); + int val = unicode; + int keycode = android_get_keysym(p_keycode); + int phy_keycode = android_get_keysym(p_scancode); + + if (keycode == KEY_SHIFT) { + shift_mem = p_pressed; + } + if (keycode == KEY_ALT) { + alt_mem = p_pressed; + } + if (keycode == KEY_CTRL) { + control_mem = p_pressed; + } + if (keycode == KEY_META) { + meta_mem = p_pressed; + } + + ev->set_keycode((Key)keycode); + ev->set_physical_keycode((Key)phy_keycode); + ev->set_unicode(val); + ev->set_pressed(p_pressed); + + _set_key_modifier_state(ev); + + if (val == '\n') { + ev->set_keycode(KEY_ENTER); + } else if (val == 61448) { + ev->set_keycode(KEY_BACKSPACE); + ev->set_unicode(KEY_BACKSPACE); + } else if (val == 61453) { + ev->set_keycode(KEY_ENTER); + ev->set_unicode(KEY_ENTER); + } else if (p_keycode == 4) { + if (DisplayServerAndroid *dsa = Object::cast_to<DisplayServerAndroid>(DisplayServer::get_singleton())) { + dsa->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST, true); + } + } + + Input::get_singleton()->parse_input_event(ev); +} + +void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector<AndroidInputHandler::TouchPos> &p_points) { + switch (p_event) { + case AMOTION_EVENT_ACTION_DOWN: { //gesture begin + if (touch.size()) { + //end all if exist + for (int i = 0; i < touch.size(); i++) { + Ref<InputEventScreenTouch> ev; + ev.instantiate(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); + Input::get_singleton()->parse_input_event(ev); + } + } + + touch.resize(p_points.size()); + for (int i = 0; i < p_points.size(); i++) { + touch.write[i].id = p_points[i].id; + touch.write[i].pos = p_points[i].pos; + } + + //send touch + for (int i = 0; i < touch.size(); i++) { + Ref<InputEventScreenTouch> ev; + ev.instantiate(); + ev->set_index(touch[i].id); + ev->set_pressed(true); + ev->set_position(touch[i].pos); + Input::get_singleton()->parse_input_event(ev); + } + + } break; + case AMOTION_EVENT_ACTION_MOVE: { //motion + ERR_FAIL_COND(touch.size() != p_points.size()); + + for (int i = 0; i < touch.size(); i++) { + int idx = -1; + for (int j = 0; j < p_points.size(); j++) { + if (touch[i].id == p_points[j].id) { + idx = j; + break; + } + } + + ERR_CONTINUE(idx == -1); + + if (touch[i].pos == p_points[idx].pos) + continue; //no move unncesearily + + Ref<InputEventScreenDrag> ev; + ev.instantiate(); + ev->set_index(touch[i].id); + ev->set_position(p_points[idx].pos); + ev->set_relative(p_points[idx].pos - touch[i].pos); + Input::get_singleton()->parse_input_event(ev); + touch.write[i].pos = p_points[idx].pos; + } + + } break; + case AMOTION_EVENT_ACTION_CANCEL: + case AMOTION_EVENT_ACTION_UP: { //release + if (touch.size()) { + //end all if exist + for (int i = 0; i < touch.size(); i++) { + Ref<InputEventScreenTouch> ev; + ev.instantiate(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); + Input::get_singleton()->parse_input_event(ev); + } + touch.clear(); + } + } break; + case AMOTION_EVENT_ACTION_POINTER_DOWN: { // add touch + for (int i = 0; i < p_points.size(); i++) { + if (p_points[i].id == p_pointer) { + TouchPos tp = p_points[i]; + touch.push_back(tp); + + Ref<InputEventScreenTouch> ev; + ev.instantiate(); + + ev->set_index(tp.id); + ev->set_pressed(true); + ev->set_position(tp.pos); + Input::get_singleton()->parse_input_event(ev); + + break; + } + } + } break; + case AMOTION_EVENT_ACTION_POINTER_UP: { // remove touch + for (int i = 0; i < touch.size(); i++) { + if (touch[i].id == p_pointer) { + Ref<InputEventScreenTouch> ev; + ev.instantiate(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); + Input::get_singleton()->parse_input_event(ev); + touch.remove(i); + + break; + } + } + } break; + } +} + +void AndroidInputHandler::process_hover(int p_type, Point2 p_pos) { + // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER + switch (p_type) { + case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move + case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter + case AMOTION_EVENT_ACTION_HOVER_EXIT: { // hover exit + Ref<InputEventMouseMotion> ev; + ev.instantiate(); + _set_key_modifier_state(ev); + ev->set_position(p_pos); + ev->set_global_position(p_pos); + ev->set_relative(p_pos - hover_prev_pos); + Input::get_singleton()->parse_input_event(ev); + hover_prev_pos = p_pos; + } break; + } +} + +void AndroidInputHandler::process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) { + MouseButton event_buttons_mask = _android_button_mask_to_godot_button_mask(event_android_buttons_mask); + switch (event_action) { + case AMOTION_EVENT_ACTION_BUTTON_PRESS: + case AMOTION_EVENT_ACTION_BUTTON_RELEASE: { + Ref<InputEventMouseButton> ev; + ev.instantiate(); + _set_key_modifier_state(ev); + if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) { + ev->set_position(event_pos); + ev->set_global_position(event_pos); + } else { + ev->set_position(hover_prev_pos); + ev->set_global_position(hover_prev_pos); + } + ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS); + MouseButton changed_button_mask = MouseButton(buttons_state ^ event_buttons_mask); + + buttons_state = event_buttons_mask; + + ev->set_button_index(_button_index_from_mask(changed_button_mask)); + ev->set_button_mask(event_buttons_mask); + Input::get_singleton()->parse_input_event(ev); + } break; + + case AMOTION_EVENT_ACTION_MOVE: { + Ref<InputEventMouseMotion> ev; + ev.instantiate(); + _set_key_modifier_state(ev); + if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) { + ev->set_position(event_pos); + ev->set_global_position(event_pos); + ev->set_relative(event_pos - hover_prev_pos); + hover_prev_pos = event_pos; + } else { + ev->set_position(hover_prev_pos); + ev->set_global_position(hover_prev_pos); + ev->set_relative(event_pos); + } + ev->set_button_mask(event_buttons_mask); + Input::get_singleton()->parse_input_event(ev); + } break; + case AMOTION_EVENT_ACTION_SCROLL: { + Ref<InputEventMouseButton> ev; + ev.instantiate(); + if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) { + ev->set_position(event_pos); + ev->set_global_position(event_pos); + } else { + ev->set_position(hover_prev_pos); + ev->set_global_position(hover_prev_pos); + } + ev->set_pressed(true); + buttons_state = event_buttons_mask; + if (event_vertical_factor > 0) { + _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_UP, event_vertical_factor); + } else if (event_vertical_factor < 0) { + _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_DOWN, -event_vertical_factor); + } + + if (event_horizontal_factor > 0) { + _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_RIGHT, event_horizontal_factor); + } else if (event_horizontal_factor < 0) { + _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_LEFT, -event_horizontal_factor); + } + } break; + } +} + +void AndroidInputHandler::_wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) { + Ref<InputEventMouseButton> evd = ev->duplicate(); + _set_key_modifier_state(evd); + evd->set_button_index(wheel_button); + evd->set_button_mask(MouseButton(event_buttons_mask ^ (1 << (wheel_button - 1)))); + evd->set_factor(factor); + Input::get_singleton()->parse_input_event(evd); + Ref<InputEventMouseButton> evdd = evd->duplicate(); + evdd->set_pressed(false); + evdd->set_button_mask(event_buttons_mask); + Input::get_singleton()->parse_input_event(evdd); +} + +void AndroidInputHandler::process_double_tap(int event_android_button_mask, Point2 p_pos) { + MouseButton event_button_mask = _android_button_mask_to_godot_button_mask(event_android_button_mask); + Ref<InputEventMouseButton> ev; + ev.instantiate(); + _set_key_modifier_state(ev); + ev->set_position(p_pos); + ev->set_global_position(p_pos); + ev->set_pressed(event_button_mask != 0); + ev->set_button_index(_button_index_from_mask(event_button_mask)); + ev->set_button_mask(event_button_mask); + ev->set_double_click(true); + Input::get_singleton()->parse_input_event(ev); +} + +MouseButton AndroidInputHandler::_button_index_from_mask(MouseButton button_mask) { + switch (button_mask) { + case MOUSE_BUTTON_MASK_LEFT: + return MOUSE_BUTTON_LEFT; + case MOUSE_BUTTON_MASK_RIGHT: + return MOUSE_BUTTON_RIGHT; + case MOUSE_BUTTON_MASK_MIDDLE: + return MOUSE_BUTTON_MIDDLE; + case MOUSE_BUTTON_MASK_XBUTTON1: + return MOUSE_BUTTON_XBUTTON1; + case MOUSE_BUTTON_MASK_XBUTTON2: + return MOUSE_BUTTON_XBUTTON2; + default: + return MOUSE_BUTTON_NONE; + } +} + +MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) { + MouseButton godot_button_mask = MOUSE_BUTTON_NONE; + if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) { + godot_button_mask |= MOUSE_BUTTON_MASK_LEFT; + } + if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) { + godot_button_mask |= MOUSE_BUTTON_MASK_RIGHT; + } + if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) { + godot_button_mask |= MOUSE_BUTTON_MASK_MIDDLE; + } + if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) { + godot_button_mask |= MOUSE_BUTTON_MASK_XBUTTON1; + } + if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) { + godot_button_mask |= MOUSE_BUTTON_MASK_XBUTTON2; + } + + return godot_button_mask; +} + +void AndroidInputHandler::process_scroll(Point2 p_pos) { + Ref<InputEventPanGesture> ev; + ev.instantiate(); + _set_key_modifier_state(ev); + ev->set_position(p_pos); + ev->set_delta(p_pos - scroll_prev_pos); + Input::get_singleton()->parse_input_event(ev); + scroll_prev_pos = p_pos; +} diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h new file mode 100644 index 0000000000..2918ca300b --- /dev/null +++ b/platform/android/android_input_handler.h @@ -0,0 +1,91 @@ +/*************************************************************************/ +/* android_input_handler.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 ANDROID_INPUT_HANDLER_H +#define ANDROID_INPUT_HANDLER_H + +#include "core/input/input.h" + +// This class encapsulates all the handling of input events that come from the Android UI thread. +// Remarks: +// - It's not thread-safe by itself, so its functions must only be called on a single thread, which is the Android UI thread. +// - Its functions must only call thread-safe methods. +class AndroidInputHandler { +public: + struct TouchPos { + int id = 0; + Point2 pos; + }; + + enum { + JOY_EVENT_BUTTON = 0, + JOY_EVENT_AXIS = 1, + JOY_EVENT_HAT = 2 + }; + + struct JoypadEvent { + int device = 0; + int type = 0; + int index = 0; + bool pressed = false; + float value = 0; + int hat = 0; + }; + +private: + bool alt_mem = false; + bool shift_mem = false; + bool control_mem = false; + bool meta_mem = false; + + MouseButton buttons_state = MOUSE_BUTTON_NONE; + + Vector<TouchPos> touch; + Point2 hover_prev_pos; // needed to calculate the relative position on hover events + Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events + + void _set_key_modifier_state(Ref<InputEventWithModifiers> ev); + + static MouseButton _button_index_from_mask(MouseButton button_mask); + static MouseButton _android_button_mask_to_godot_button_mask(int android_button_mask); + + void _wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor); + +public: + void process_touch(int p_event, int p_pointer, const Vector<TouchPos> &p_points); + void process_hover(int p_type, Point2 p_pos); + void process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0); + void process_double_tap(int event_android_button_mask, Point2 p_pos); + void process_scroll(Point2 p_pos); + void process_joy_event(JoypadEvent p_event); + void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed); +}; + +#endif diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index d200d024c5..720752d28f 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -30,7 +30,6 @@ #include "display_server_android.h" -#include "android_keys_utils.h" #include "core/config/project_settings.h" #include "java_godot_io_wrapper.h" #include "java_godot_wrapper.h" @@ -203,17 +202,21 @@ void DisplayServerAndroid::window_set_drop_files_callback(const Callable &p_call // Not supported on Android. } -void DisplayServerAndroid::_window_callback(const Callable &p_callable, const Variant &p_arg) const { +void DisplayServerAndroid::_window_callback(const Callable &p_callable, const Variant &p_arg, bool p_deferred) const { if (!p_callable.is_null()) { const Variant *argp = &p_arg; Variant ret; Callable::CallError ce; - p_callable.call((const Variant **)&argp, 1, ret, ce); + if (p_deferred) { + p_callable.call((const Variant **)&argp, 1, ret, ce); + } else { + p_callable.call_deferred((const Variant **)&argp, 1); + } } } -void DisplayServerAndroid::send_window_event(DisplayServer::WindowEvent p_event) const { - _window_callback(window_event_callback, int(p_event)); +void DisplayServerAndroid::send_window_event(DisplayServer::WindowEvent p_event, bool p_deferred) const { + _window_callback(window_event_callback, int(p_event), p_deferred); } void DisplayServerAndroid::send_input_event(const Ref<InputEvent> &p_event) const { @@ -335,7 +338,7 @@ bool DisplayServerAndroid::can_any_window_draw() const { } void DisplayServerAndroid::process_events() { - Input::get_singleton()->flush_accumulated_events(); + Input::get_singleton()->flush_buffered_events(); } Vector<String> DisplayServerAndroid::get_rendering_drivers_func() { @@ -454,6 +457,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis #endif Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); + Input::get_singleton()->set_use_input_buffering(true); // Needed because events will come directly from the UI thread r_error = OK; } @@ -473,344 +477,6 @@ DisplayServerAndroid::~DisplayServerAndroid() { #endif } -void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p_event) { - switch (p_event.type) { - case JOY_EVENT_BUTTON: - Input::get_singleton()->joy_button(p_event.device, (JoyButton)p_event.index, p_event.pressed); - break; - case JOY_EVENT_AXIS: - Input::JoyAxisValue value; - value.min = -1; - value.value = p_event.value; - Input::get_singleton()->joy_axis(p_event.device, (JoyAxis)p_event.index, value); - break; - case JOY_EVENT_HAT: - Input::get_singleton()->joy_hat(p_event.device, (HatMask)p_event.hat); - break; - default: - return; - } -} - -void DisplayServerAndroid::_set_key_modifier_state(Ref<InputEventWithModifiers> ev) { - ev->set_shift_pressed(shift_mem); - ev->set_alt_pressed(alt_mem); - ev->set_meta_pressed(meta_mem); - ev->set_ctrl_pressed(control_mem); -} - -void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) { - static char32_t prev_wc = 0; - char32_t unicode = p_unicode_char; - if ((p_unicode_char & 0xfffffc00) == 0xd800) { - if (prev_wc != 0) { - ERR_PRINT("invalid utf16 surrogate input"); - } - prev_wc = unicode; - return; // Skip surrogate. - } else if ((unicode & 0xfffffc00) == 0xdc00) { - if (prev_wc == 0) { - ERR_PRINT("invalid utf16 surrogate input"); - return; // Skip invalid surrogate. - } - unicode = (prev_wc << 10UL) + unicode - ((0xd800 << 10UL) + 0xdc00 - 0x10000); - prev_wc = 0; - } else { - prev_wc = 0; - } - - Ref<InputEventKey> ev; - ev.instantiate(); - int val = unicode; - int keycode = android_get_keysym(p_keycode); - int phy_keycode = android_get_keysym(p_scancode); - - if (keycode == KEY_SHIFT) { - shift_mem = p_pressed; - } - if (keycode == KEY_ALT) { - alt_mem = p_pressed; - } - if (keycode == KEY_CTRL) { - control_mem = p_pressed; - } - if (keycode == KEY_META) { - meta_mem = p_pressed; - } - - ev->set_keycode((Key)keycode); - ev->set_physical_keycode((Key)phy_keycode); - ev->set_unicode(val); - ev->set_pressed(p_pressed); - - _set_key_modifier_state(ev); - - if (val == '\n') { - ev->set_keycode(KEY_ENTER); - } else if (val == 61448) { - ev->set_keycode(KEY_BACKSPACE); - ev->set_unicode(KEY_BACKSPACE); - } else if (val == 61453) { - ev->set_keycode(KEY_ENTER); - ev->set_unicode(KEY_ENTER); - } else if (p_keycode == 4) { - OS_Android::get_singleton()->main_loop_request_go_back(); - } - - Input::get_singleton()->accumulate_input_event(ev); -} - -void DisplayServerAndroid::process_touch(int p_event, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) { - switch (p_event) { - case AMOTION_EVENT_ACTION_DOWN: { //gesture begin - if (touch.size()) { - //end all if exist - for (int i = 0; i < touch.size(); i++) { - Ref<InputEventScreenTouch> ev; - ev.instantiate(); - ev->set_index(touch[i].id); - ev->set_pressed(false); - ev->set_position(touch[i].pos); - Input::get_singleton()->accumulate_input_event(ev); - } - } - - touch.resize(p_points.size()); - for (int i = 0; i < p_points.size(); i++) { - touch.write[i].id = p_points[i].id; - touch.write[i].pos = p_points[i].pos; - } - - //send touch - for (int i = 0; i < touch.size(); i++) { - Ref<InputEventScreenTouch> ev; - ev.instantiate(); - ev->set_index(touch[i].id); - ev->set_pressed(true); - ev->set_position(touch[i].pos); - Input::get_singleton()->accumulate_input_event(ev); - } - - } break; - case AMOTION_EVENT_ACTION_MOVE: { //motion - ERR_FAIL_COND(touch.size() != p_points.size()); - - for (int i = 0; i < touch.size(); i++) { - int idx = -1; - for (int j = 0; j < p_points.size(); j++) { - if (touch[i].id == p_points[j].id) { - idx = j; - break; - } - } - - ERR_CONTINUE(idx == -1); - - if (touch[i].pos == p_points[idx].pos) - continue; //no move unncesearily - - Ref<InputEventScreenDrag> ev; - ev.instantiate(); - ev->set_index(touch[i].id); - ev->set_position(p_points[idx].pos); - ev->set_relative(p_points[idx].pos - touch[i].pos); - Input::get_singleton()->accumulate_input_event(ev); - touch.write[i].pos = p_points[idx].pos; - } - - } break; - case AMOTION_EVENT_ACTION_CANCEL: - case AMOTION_EVENT_ACTION_UP: { //release - if (touch.size()) { - //end all if exist - for (int i = 0; i < touch.size(); i++) { - Ref<InputEventScreenTouch> ev; - ev.instantiate(); - ev->set_index(touch[i].id); - ev->set_pressed(false); - ev->set_position(touch[i].pos); - Input::get_singleton()->accumulate_input_event(ev); - } - touch.clear(); - } - } break; - case AMOTION_EVENT_ACTION_POINTER_DOWN: { // add touch - for (int i = 0; i < p_points.size(); i++) { - if (p_points[i].id == p_pointer) { - TouchPos tp = p_points[i]; - touch.push_back(tp); - - Ref<InputEventScreenTouch> ev; - ev.instantiate(); - - ev->set_index(tp.id); - ev->set_pressed(true); - ev->set_position(tp.pos); - Input::get_singleton()->accumulate_input_event(ev); - - break; - } - } - } break; - case AMOTION_EVENT_ACTION_POINTER_UP: { // remove touch - for (int i = 0; i < touch.size(); i++) { - if (touch[i].id == p_pointer) { - Ref<InputEventScreenTouch> ev; - ev.instantiate(); - ev->set_index(touch[i].id); - ev->set_pressed(false); - ev->set_position(touch[i].pos); - Input::get_singleton()->accumulate_input_event(ev); - touch.remove(i); - - break; - } - } - } break; - } -} - -void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) { - // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER - switch (p_type) { - case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move - case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter - case AMOTION_EVENT_ACTION_HOVER_EXIT: { // hover exit - Ref<InputEventMouseMotion> ev; - ev.instantiate(); - _set_key_modifier_state(ev); - ev->set_position(p_pos); - ev->set_global_position(p_pos); - ev->set_relative(p_pos - hover_prev_pos); - Input::get_singleton()->accumulate_input_event(ev); - hover_prev_pos = p_pos; - } break; - } -} - -void DisplayServerAndroid::process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) { - MouseButton event_buttons_mask = _android_button_mask_to_godot_button_mask(event_android_buttons_mask); - switch (event_action) { - case AMOTION_EVENT_ACTION_BUTTON_PRESS: - case AMOTION_EVENT_ACTION_BUTTON_RELEASE: { - Ref<InputEventMouseButton> ev; - ev.instantiate(); - _set_key_modifier_state(ev); - if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) { - ev->set_position(event_pos); - ev->set_global_position(event_pos); - } else { - ev->set_position(hover_prev_pos); - ev->set_global_position(hover_prev_pos); - } - ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS); - MouseButton changed_button_mask = MouseButton(buttons_state ^ event_buttons_mask); - - buttons_state = event_buttons_mask; - - ev->set_button_index(_button_index_from_mask(changed_button_mask)); - ev->set_button_mask(event_buttons_mask); - Input::get_singleton()->accumulate_input_event(ev); - } break; - - case AMOTION_EVENT_ACTION_MOVE: { - Ref<InputEventMouseMotion> ev; - ev.instantiate(); - _set_key_modifier_state(ev); - if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) { - ev->set_position(event_pos); - ev->set_global_position(event_pos); - ev->set_relative(event_pos - hover_prev_pos); - hover_prev_pos = event_pos; - } else { - ev->set_position(hover_prev_pos); - ev->set_global_position(hover_prev_pos); - ev->set_relative(event_pos); - } - ev->set_button_mask(event_buttons_mask); - Input::get_singleton()->accumulate_input_event(ev); - } break; - case AMOTION_EVENT_ACTION_SCROLL: { - Ref<InputEventMouseButton> ev; - ev.instantiate(); - if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) { - ev->set_position(event_pos); - ev->set_global_position(event_pos); - } else { - ev->set_position(hover_prev_pos); - ev->set_global_position(hover_prev_pos); - } - ev->set_pressed(true); - buttons_state = event_buttons_mask; - if (event_vertical_factor > 0) { - _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_UP, event_vertical_factor); - } else if (event_vertical_factor < 0) { - _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_DOWN, -event_vertical_factor); - } - - if (event_horizontal_factor > 0) { - _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_RIGHT, event_horizontal_factor); - } else if (event_horizontal_factor < 0) { - _wheel_button_click(event_buttons_mask, ev, MOUSE_BUTTON_WHEEL_LEFT, -event_horizontal_factor); - } - } break; - } -} - -void DisplayServerAndroid::_wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) { - Ref<InputEventMouseButton> evd = ev->duplicate(); - _set_key_modifier_state(evd); - evd->set_button_index(wheel_button); - evd->set_button_mask(MouseButton(event_buttons_mask ^ (1 << (wheel_button - 1)))); - evd->set_factor(factor); - Input::get_singleton()->accumulate_input_event(evd); - Ref<InputEventMouseButton> evdd = evd->duplicate(); - evdd->set_pressed(false); - evdd->set_button_mask(event_buttons_mask); - Input::get_singleton()->accumulate_input_event(evdd); -} - -void DisplayServerAndroid::process_double_tap(int event_android_button_mask, Point2 p_pos) { - MouseButton event_button_mask = _android_button_mask_to_godot_button_mask(event_android_button_mask); - Ref<InputEventMouseButton> ev; - ev.instantiate(); - _set_key_modifier_state(ev); - ev->set_position(p_pos); - ev->set_global_position(p_pos); - ev->set_pressed(event_button_mask != 0); - ev->set_button_index(_button_index_from_mask(event_button_mask)); - ev->set_button_mask(event_button_mask); - ev->set_double_click(true); - Input::get_singleton()->accumulate_input_event(ev); -} - -MouseButton DisplayServerAndroid::_button_index_from_mask(MouseButton button_mask) { - switch (button_mask) { - case MOUSE_BUTTON_MASK_LEFT: - return MOUSE_BUTTON_LEFT; - case MOUSE_BUTTON_MASK_RIGHT: - return MOUSE_BUTTON_RIGHT; - case MOUSE_BUTTON_MASK_MIDDLE: - return MOUSE_BUTTON_MIDDLE; - case MOUSE_BUTTON_MASK_XBUTTON1: - return MOUSE_BUTTON_XBUTTON1; - case MOUSE_BUTTON_MASK_XBUTTON2: - return MOUSE_BUTTON_XBUTTON2; - default: - return MOUSE_BUTTON_NONE; - } -} - -void DisplayServerAndroid::process_scroll(Point2 p_pos) { - Ref<InputEventPanGesture> ev; - ev.instantiate(); - _set_key_modifier_state(ev); - ev->set_position(p_pos); - ev->set_delta(p_pos - scroll_prev_pos); - Input::get_singleton()->accumulate_input_event(ev); - scroll_prev_pos = p_pos; -} - void DisplayServerAndroid::process_accelerometer(const Vector3 &p_accelerometer) { Input::get_singleton()->set_accelerometer(p_accelerometer); } @@ -852,32 +518,11 @@ DisplayServer::MouseMode DisplayServerAndroid::mouse_get_mode() const { } Point2i DisplayServerAndroid::mouse_get_position() const { - return hover_prev_pos; + return Input::get_singleton()->get_mouse_position(); } MouseButton DisplayServerAndroid::mouse_get_button_state() const { - return buttons_state; -} - -MouseButton DisplayServerAndroid::_android_button_mask_to_godot_button_mask(int android_button_mask) { - MouseButton godot_button_mask = MOUSE_BUTTON_NONE; - if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) { - godot_button_mask |= MOUSE_BUTTON_MASK_LEFT; - } - if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) { - godot_button_mask |= MOUSE_BUTTON_MASK_RIGHT; - } - if (android_button_mask & AMOTION_EVENT_BUTTON_TERTIARY) { - godot_button_mask |= MOUSE_BUTTON_MASK_MIDDLE; - } - if (android_button_mask & AMOTION_EVENT_BUTTON_BACK) { - godot_button_mask |= MOUSE_BUTTON_MASK_XBUTTON1; - } - if (android_button_mask & AMOTION_EVENT_BUTTON_SECONDARY) { - godot_button_mask |= MOUSE_BUTTON_MASK_XBUTTON2; - } - - return godot_button_mask; + return (MouseButton)Input::get_singleton()->get_mouse_button_mask(); } void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape) { diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 9b9f5e99f6..669a1c80e4 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -39,37 +39,8 @@ class RenderingDeviceVulkan; #endif class DisplayServerAndroid : public DisplayServer { -public: - struct TouchPos { - int id = 0; - Point2 pos; - }; - - enum { - JOY_EVENT_BUTTON = 0, - JOY_EVENT_AXIS = 1, - JOY_EVENT_HAT = 2 - }; - - struct JoypadEvent { - int device = 0; - int type = 0; - int index = 0; - bool pressed = false; - float value = 0; - int hat = 0; - }; - -private: String rendering_driver; - bool alt_mem = false; - bool shift_mem = false; - bool control_mem = false; - bool meta_mem = false; - - MouseButton buttons_state = MOUSE_BUTTON_NONE; - // https://developer.android.com/reference/android/view/PointerIcon // mapping between Godot's cursor shape to Android's' int android_cursors[CURSOR_MAX] = { @@ -96,10 +67,6 @@ private: bool keep_screen_on; - Vector<TouchPos> touch; - Point2 hover_prev_pos; // needed to calculate the relative position on hover events - Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events - CursorShape cursor_shape = CursorShape::CURSOR_ARROW; #if defined(VULKAN_ENABLED) @@ -114,18 +81,10 @@ private: Callable input_text_callback; Callable rect_changed_callback; - void _window_callback(const Callable &p_callable, const Variant &p_arg) const; + void _window_callback(const Callable &p_callable, const Variant &p_arg, bool p_deferred = false) const; static void _dispatch_input_events(const Ref<InputEvent> &p_event); - void _set_key_modifier_state(Ref<InputEventWithModifiers> ev); - - static MouseButton _button_index_from_mask(MouseButton button_mask); - - static MouseButton _android_button_mask_to_godot_button_mask(int android_button_mask); - - void _wheel_button_click(MouseButton event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor); - public: static DisplayServerAndroid *get_singleton(); @@ -158,7 +117,7 @@ public: virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; - void send_window_event(WindowEvent p_event) const; + void send_window_event(WindowEvent p_event, bool p_deferred = false) const; void send_input_event(const Ref<InputEvent> &p_event) const; void send_input_text(const String &p_text) const; @@ -210,13 +169,6 @@ public: void process_gravity(const Vector3 &p_gravity); void process_magnetometer(const Vector3 &p_magnetometer); void process_gyroscope(const Vector3 &p_gyroscope); - void process_touch(int p_event, int p_pointer, const Vector<TouchPos> &p_points); - void process_hover(int p_type, Point2 p_pos); - void process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0); - void process_double_tap(int event_android_button_mask, Point2 p_pos); - void process_scroll(Point2 p_pos); - void process_joy_event(JoypadEvent p_event); - void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed); virtual void cursor_set_shape(CursorShape p_shape) override; virtual CursorShape cursor_get_shape() const override; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java index 1d60c21c60..6b248fd034 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -75,7 +75,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener final int x = Math.round(event.getX()); final int y = Math.round(event.getY()); final int buttonMask = event.getButtonState(); - queueEvent(() -> GodotLib.doubleTap(buttonMask, x, y)); + GodotLib.doubleTap(buttonMask, x, y); return true; } @@ -84,7 +84,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener //Log.i("GodotGesture", "onScroll"); final int x = Math.round(distanceX); final int y = Math.round(distanceY); - queueEvent(() -> GodotLib.scroll(x, y)); + GodotLib.scroll(x, y); return true; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index 4dc9157545..fc0b84b392 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -68,10 +68,6 @@ public class GodotInputHandler implements InputDeviceListener { mInputManager.registerInputDeviceListener(this, null); } - private void queueEvent(Runnable task) { - mRenderView.queueOnRenderThread(task); - } - private boolean isKeyEvent_GameDevice(int source) { // Note that keyboards are often (SOURCE_KEYBOARD | SOURCE_DPAD) if (source == (InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD)) @@ -96,13 +92,12 @@ public class GodotInputHandler implements InputDeviceListener { if (mJoystickIds.indexOfKey(deviceId) >= 0) { final int button = getGodotButton(keyCode); final int godotJoyId = mJoystickIds.get(deviceId); - - queueEvent(() -> GodotLib.joybutton(godotJoyId, button, false)); + GodotLib.joybutton(godotJoyId, button, false); } } else { final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); - queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, false)); + GodotLib.key(keyCode, scanCode, chr, false); } return true; @@ -132,13 +127,12 @@ public class GodotInputHandler implements InputDeviceListener { if (mJoystickIds.indexOfKey(deviceId) >= 0) { final int button = getGodotButton(keyCode); final int godotJoyId = mJoystickIds.get(deviceId); - - queueEvent(() -> GodotLib.joybutton(godotJoyId, button, true)); + GodotLib.joybutton(godotJoyId, button, true); } } else { final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); - queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, true)); + GodotLib.key(keyCode, scanCode, chr, true); } return true; @@ -170,18 +164,16 @@ public class GodotInputHandler implements InputDeviceListener { final int action = event.getActionMasked(); final int pointer_idx = event.getPointerId(event.getActionIndex()); - mRenderView.queueOnRenderThread(() -> { - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_MOVE: - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_POINTER_DOWN: { - GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); - } break; - } - }); + switch (action) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_POINTER_DOWN: { + GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); + } break; + } } return true; } @@ -205,7 +197,7 @@ public class GodotInputHandler implements InputDeviceListener { // save value to prevent repeats joystick.axesValues.put(axis, value); final int godotAxisIdx = i; - queueEvent(() -> GodotLib.joyaxis(godotJoyId, godotAxisIdx, value)); + GodotLib.joyaxis(godotJoyId, godotAxisIdx, value); } } @@ -215,7 +207,7 @@ public class GodotInputHandler implements InputDeviceListener { if (joystick.hatX != hatX || joystick.hatY != hatY) { joystick.hatX = hatX; joystick.hatY = hatY; - queueEvent(() -> GodotLib.joyhat(godotJoyId, hatX, hatY)); + GodotLib.joyhat(godotJoyId, hatX, hatY); } } return true; @@ -224,7 +216,7 @@ public class GodotInputHandler implements InputDeviceListener { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); - queueEvent(() -> GodotLib.hover(type, x, y)); + GodotLib.hover(type, x, y); return true; } else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) { @@ -316,7 +308,7 @@ public class GodotInputHandler implements InputDeviceListener { } mJoysticksDevices.put(deviceId, joystick); - queueEvent(() -> GodotLib.joyconnectionchanged(id, true, joystick.name)); + GodotLib.joyconnectionchanged(id, true, joystick.name); } @Override @@ -328,8 +320,7 @@ public class GodotInputHandler implements InputDeviceListener { final int godotJoyId = mJoystickIds.get(deviceId); mJoystickIds.delete(deviceId); mJoysticksDevices.delete(deviceId); - - queueEvent(() -> GodotLib.joyconnectionchanged(godotJoyId, false, "")); + GodotLib.joyconnectionchanged(godotJoyId, false, ""); } @Override @@ -418,7 +409,7 @@ public class GodotInputHandler implements InputDeviceListener { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); - queueEvent(() -> GodotLib.hover(type, x, y)); + GodotLib.hover(type, x, y); return true; } case MotionEvent.ACTION_BUTTON_PRESS: @@ -428,7 +419,7 @@ public class GodotInputHandler implements InputDeviceListener { final float y = event.getY(); final int buttonsMask = event.getButtonState(); final int action = event.getAction(); - queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask)); + GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask); return true; } case MotionEvent.ACTION_SCROLL: { @@ -438,7 +429,7 @@ public class GodotInputHandler implements InputDeviceListener { final int action = event.getAction(); final float verticalFactor = event.getAxisValue(MotionEvent.AXIS_VSCROLL); final float horizontalFactor = event.getAxisValue(MotionEvent.AXIS_HSCROLL); - queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor)); + GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor); } case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: { diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 020870a110..002a75277d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -94,17 +94,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) { //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); - mRenderView.queueOnRenderThread(() -> { - for (int i = 0; i < count; ++i) { - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); - - if (mHasSelection) { - mHasSelection = false; - break; - } + for (int i = 0; i < count; ++i) { + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); + + if (mHasSelection) { + mHasSelection = false; + break; } - }); + } } @Override @@ -115,17 +113,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene for (int i = start; i < start + count; ++i) { newChars[i - start] = pCharSequence.charAt(i); } - mRenderView.queueOnRenderThread(() -> { - for (int i = 0; i < count; ++i) { - int key = newChars[i]; - if ((key == '\n') && !mEdit.isMultiline()) { - // Return keys are handled through action events - continue; - } - GodotLib.key(0, 0, key, true); - GodotLib.key(0, 0, key, false); + for (int i = 0; i < count; ++i) { + int key = newChars[i]; + if ((key == '\n') && !mEdit.isMultiline()) { + // Return keys are handled through action events + continue; } - }); + GodotLib.key(0, 0, key, true); + GodotLib.key(0, 0, key, false); + } } @Override @@ -133,13 +129,11 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene if (mEdit == pTextView && isFullScreenEdit()) { final String characters = pKeyEvent.getCharacters(); - mRenderView.queueOnRenderThread(() -> { - for (int i = 0; i < characters.length(); i++) { - final int ch = characters.codePointAt(i); - GodotLib.key(0, 0, ch, true); - GodotLib.key(0, 0, ch, false); - } - }); + for (int i = 0; i < characters.length(); i++) { + final int ch = characters.codePointAt(i); + GodotLib.key(0, 0, ch, true); + GodotLib.key(0, 0, ch, false); + } } if (pActionID == EditorInfo.IME_ACTION_DONE) { diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index ce7a49e53c..d971727269 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -34,6 +34,7 @@ #include "java_godot_wrapper.h" #include "android/asset_manager_jni.h" +#include "android_input_handler.h" #include "api/java_class_wrapper.h" #include "api/jni_singleton.h" #include "core/config/engine.h" @@ -56,11 +57,12 @@ static JavaClassWrapper *java_class_wrapper = nullptr; static OS_Android *os_android = nullptr; +static AndroidInputHandler *input_handler = nullptr; static GodotJavaWrapper *godot_java = nullptr; static GodotIOJavaWrapper *godot_io_java = nullptr; static bool initialized = false; -static int step = 0; +static SafeNumeric<int> step; // Shared between UI and render threads static Size2 new_size; static Vector3 accelerometer; @@ -111,6 +113,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env if (godot_java) { delete godot_java; } + if (input_handler) { + delete input_handler; + } if (os_android) { delete os_android; } @@ -165,7 +170,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j os_android->set_display_size(Size2i(p_width, p_height)); // No need to reset the surface during startup - if (step > 0) { + if (step.get() > 0) { if (p_surface) { ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface); os_android->set_native_window(native_window); @@ -179,7 +184,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits) { if (os_android) { - if (step == 0) { + if (step.get() == 0) { // During startup os_android->set_context_is_16_bits(!p_32_bits); if (p_surface) { @@ -188,33 +193,36 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en } } else { // Rendering context recreated because it was lost; restart app to let it reload everything + step.set(-1); // Ensure no further steps are attempted and no further events are sent os_android->main_loop_end(); godot_java->restart(env); - step = -1; // Ensure no further steps are attempted } } } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() == 0) return; - os_android->main_loop_request_go_back(); + if (DisplayServerAndroid *dsa = Object::cast_to<DisplayServerAndroid>(DisplayServer::get_singleton())) { + dsa->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST); + } } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz) { - if (step == -1) + if (step.get() == -1) return; - if (step == 0) { + if (step.get() == 0) { // Since Godot is initialized on the UI thread, main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop Main::setup2(Thread::get_caller_id()); - ++step; + input_handler = new AndroidInputHandler(); + step.increment(); return; } - if (step == 1) { + if (step.get() == 1) { if (!Main::start()) { return; // should exit instead and print the error } @@ -222,7 +230,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl godot_java->on_godot_setup_completed(env); os_android->main_loop_begin(); godot_java->on_godot_main_loop_started(env); - ++step; + step.increment(); } DisplayServerAndroid::get_singleton()->process_accelerometer(accelerometer); @@ -236,91 +244,100 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl } void touch_preprocessing(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) { - if (step == 0) + if (step.get() <= 0) return; - Vector<DisplayServerAndroid::TouchPos> points; + Vector<AndroidInputHandler::TouchPos> points; for (int i = 0; i < pointer_count; i++) { jfloat p[3]; env->GetFloatArrayRegion(positions, i * 3, 3, p); - DisplayServerAndroid::TouchPos tp; + AndroidInputHandler::TouchPos tp; tp.pos = Point2(p[1], p[2]); tp.id = (int)p[0]; points.push_back(tp); } if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE || (input_device & AINPUT_SOURCE_MOUSE_RELATIVE) == AINPUT_SOURCE_MOUSE_RELATIVE) { - DisplayServerAndroid::get_singleton()->process_mouse_event(input_device, ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor); + input_handler->process_mouse_event(input_device, ev, buttons_mask, points[0].pos, vertical_factor, horizontal_factor); } else { - DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points); + input_handler->process_touch(ev, pointer, points); } } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3F(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position) { touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask) { touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray position, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor) { touch_preprocessing(env, clazz, input_device, ev, pointer, pointer_count, position, buttons_mask, vertical_factor, horizontal_factor); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_hover(p_type, Point2(p_x, p_y)); + input_handler->process_hover(p_type, Point2(p_x, p_y)); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_double_tap(p_button_mask, Point2(p_x, p_y)); + input_handler->process_double_tap(p_button_mask, Point2(p_x, p_y)); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_scroll(Point2(p_x, p_y)); + input_handler->process_scroll(Point2(p_x, p_y)); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::JoypadEvent jevent; + AndroidInputHandler::JoypadEvent jevent; jevent.device = p_device; - jevent.type = DisplayServerAndroid::JOY_EVENT_BUTTON; + jevent.type = AndroidInputHandler::JOY_EVENT_BUTTON; jevent.index = p_button; jevent.pressed = p_pressed; - DisplayServerAndroid::get_singleton()->process_joy_event(jevent); + input_handler->process_joy_event(jevent); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::JoypadEvent jevent; + AndroidInputHandler::JoypadEvent jevent; jevent.device = p_device; - jevent.type = DisplayServerAndroid::JOY_EVENT_AXIS; + jevent.type = AndroidInputHandler::JOY_EVENT_AXIS; jevent.index = p_axis; jevent.value = p_value; - DisplayServerAndroid::get_singleton()->process_joy_event(jevent); + input_handler->process_joy_event(jevent); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::JoypadEvent jevent; + AndroidInputHandler::JoypadEvent jevent; jevent.device = p_device; - jevent.type = DisplayServerAndroid::JOY_EVENT_HAT; + jevent.type = AndroidInputHandler::JOY_EVENT_HAT; int hat = 0; if (p_hat_x != 0) { if (p_hat_x < 0) @@ -336,9 +353,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j } jevent.hat = hat; - DisplayServerAndroid::get_singleton()->process_joy_event(jevent); + input_handler->process_joy_event(jevent); } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jclass clazz, jint p_device, jboolean p_connected, jstring p_name) { if (os_android) { String name = jstring_to_string(p_name, env); @@ -346,11 +364,12 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } } +// Called on the UI thread JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { - if (step == 0) + if (step.get() <= 0) return; - DisplayServerAndroid::get_singleton()->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed); + input_handler->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) { @@ -370,14 +389,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; os_android->main_loop_focusin(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; os_android->main_loop_focusout(); @@ -456,7 +475,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResu } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; if (os_android->get_main_loop()) { @@ -465,7 +484,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNI } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIEnv *env, jclass clazz) { - if (step == 0) + if (step.get() <= 0) return; if (os_android->get_main_loop()) { diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 792a390e36..c2e12442b3 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -188,10 +188,6 @@ void OS_Android::main_loop_focusin() { audio_driver_android.set_pause(false); } -void OS_Android::main_loop_request_go_back() { - DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST); -} - Error OS_Android::shell_open(String p_uri) { return godot_io_java->open_uri(p_uri); } diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 38f0f3edc7..a5b995a775 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -95,7 +95,6 @@ public: void main_loop_begin(); bool main_loop_iterate(); - void main_loop_request_go_back(); void main_loop_end(); void main_loop_focusout(); void main_loop_focusin(); diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 5b26b23806..a39941339a 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2247,7 +2247,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, k->set_shift_pressed(true); } - Input::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->parse_input_event(k); } memfree(utf8string); return; @@ -2396,7 +2396,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, } } - Input::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->parse_input_event(k); } Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property) const { @@ -2883,13 +2883,13 @@ void DisplayServerX11::process_events() { // in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out xi.mouse_pos_to_filter = pos; } - Input::get_singleton()->accumulate_input_event(st); + Input::get_singleton()->parse_input_event(st); } else { if (!xi.state.has(index)) { // Defensive break; } xi.state.erase(index); - Input::get_singleton()->accumulate_input_event(st); + Input::get_singleton()->parse_input_event(st); } } break; @@ -2906,7 +2906,7 @@ void DisplayServerX11::process_events() { sd->set_index(index); sd->set_position(pos); sd->set_relative(pos - curr_pos_elem->value()); - Input::get_singleton()->accumulate_input_event(sd); + Input::get_singleton()->parse_input_event(sd); curr_pos_elem->value() = pos; } @@ -3058,7 +3058,7 @@ void DisplayServerX11::process_events() { st->set_index(E->key()); st->set_window_id(window_id); st->set_position(E->get()); - Input::get_singleton()->accumulate_input_event(st); + Input::get_singleton()->parse_input_event(st); } xi.state.clear(); #endif @@ -3156,7 +3156,7 @@ void DisplayServerX11::process_events() { mb->set_window_id(window_id_other); mb->set_position(Vector2(x, y)); mb->set_global_position(mb->get_position()); - Input::get_singleton()->accumulate_input_event(mb); + Input::get_singleton()->parse_input_event(mb); } break; } @@ -3164,7 +3164,7 @@ void DisplayServerX11::process_events() { } } - Input::get_singleton()->accumulate_input_event(mb); + Input::get_singleton()->parse_input_event(mb); } break; case MotionNotify: { @@ -3280,7 +3280,7 @@ void DisplayServerX11::process_events() { // this is so that the relative motion doesn't get messed up // after we regain focus. if (focused) { - Input::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->parse_input_event(mm); } else { // Propagate the event to the focused window, // because it's received only on the topmost window. @@ -3300,7 +3300,7 @@ void DisplayServerX11::process_events() { mm->set_position(pos_focused); mm->set_global_position(pos_focused); mm->set_speed(Input::get_singleton()->get_last_mouse_speed()); - Input::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->parse_input_event(mm); break; } @@ -3433,7 +3433,7 @@ void DisplayServerX11::process_events() { */ } - Input::get_singleton()->flush_accumulated_events(); + Input::get_singleton()->flush_buffered_events(); } void DisplayServerX11::release_rendering_thread() { diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index cc8400980a..43b7d7c1e0 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -690,7 +690,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M mb->set_double_click([event clickCount] == 2); } - Input::get_singleton()->accumulate_input_event(mb); + Input::get_singleton()->parse_input_event(mb); } - (void)mouseDown:(NSEvent *)event { @@ -799,7 +799,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M _get_key_modifier_state([event modifierFlags], mm); Input::get_singleton()->set_mouse_position(wd.mouse_pos); - Input::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->parse_input_event(mm); } - (void)rightMouseDown:(NSEvent *)event { @@ -875,7 +875,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M ev->set_position(_get_mouse_pos(wd, [event locationInWindow])); ev->set_factor([event magnification] + 1.0); - Input::get_singleton()->accumulate_input_event(ev); + Input::get_singleton()->parse_input_event(ev); } - (void)viewDidChangeBackingProperties { @@ -1357,7 +1357,7 @@ inline void sendScrollEvent(DisplayServer::WindowID window_id, MouseButton butto DS_OSX->last_button_state |= (MouseButton)mask; sc->set_button_mask(DS_OSX->last_button_state); - Input::get_singleton()->accumulate_input_event(sc); + Input::get_singleton()->parse_input_event(sc); sc.instantiate(); sc->set_window_id(window_id); @@ -1369,7 +1369,7 @@ inline void sendScrollEvent(DisplayServer::WindowID window_id, MouseButton butto DS_OSX->last_button_state &= (MouseButton)~mask; sc->set_button_mask(DS_OSX->last_button_state); - Input::get_singleton()->accumulate_input_event(sc); + Input::get_singleton()->parse_input_event(sc); } inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy, int modifierFlags) { @@ -1384,7 +1384,7 @@ inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy pg->set_position(wd.mouse_pos); pg->set_delta(Vector2(-dx, -dy)); - Input::get_singleton()->accumulate_input_event(pg); + Input::get_singleton()->parse_input_event(pg); } - (void)scrollWheel:(NSEvent *)event { @@ -3198,7 +3198,7 @@ String DisplayServerOSX::keyboard_get_layout_name(int p_index) const { void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; - Input::get_singleton()->accumulate_input_event(ev); + Input::get_singleton()->parse_input_event(ev); } void DisplayServerOSX::_release_pressed_events() { @@ -3253,7 +3253,7 @@ void DisplayServerOSX::_send_event(NSEvent *p_event) { k->set_physical_keycode(KEY_PERIOD); k->set_echo([p_event isARepeat]); - Input::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->parse_input_event(k); } } } @@ -3331,7 +3331,7 @@ void DisplayServerOSX::process_events() { if (!drop_events) { _process_key_events(); - Input::get_singleton()->flush_accumulated_events(); + Input::get_singleton()->flush_buffered_events(); } for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp index 53ae1ea6fe..5b959d6da4 100644 --- a/platform/osx/export/export_plugin.cpp +++ b/platform/osx/export/export_plugin.cpp @@ -193,16 +193,16 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ }; static const MacOSIconInfo icon_infos[] = { - { "ic10", "", true, 1024 }, //1024x1024 32-bit PNG and 512x512@2x 32-bit "retina" PNG + { "ic10", "", true, 1024 }, //1024×1024 32-bit PNG and 512×512@2x 32-bit "retina" PNG { "ic09", "", true, 512 }, //512×512 32-bit PNG - { "ic14", "", true, 512 }, //256x256@2x 32-bit "retina" PNG + { "ic14", "", true, 512 }, //256×256@2x 32-bit "retina" PNG { "ic08", "", true, 256 }, //256×256 32-bit PNG - { "ic13", "", true, 256 }, //128x128@2x 32-bit "retina" PNG - { "ic07", "", true, 128 }, //128x128 32-bit PNG - { "ic12", "", true, 64 }, //32x32@2x 32-bit "retina" PNG - { "ic11", "", true, 32 }, //16x16@2x 32-bit "retina" PNG - { "il32", "l8mk", false, 32 }, //32x32 24-bit RLE + 8-bit uncompressed mask - { "is32", "s8mk", false, 16 } //16x16 24-bit RLE + 8-bit uncompressed mask + { "ic13", "", true, 256 }, //128×128@2x 32-bit "retina" PNG + { "ic07", "", true, 128 }, //128×128 32-bit PNG + { "ic12", "", true, 64 }, //32×32@2× 32-bit "retina" PNG + { "ic11", "", true, 32 }, //16×16@2× 32-bit "retina" PNG + { "il32", "l8mk", false, 32 }, //32×32 24-bit RLE + 8-bit uncompressed mask + { "is32", "s8mk", false, 16 } //16×16 24-bit RLE + 8-bit uncompressed mask }; for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) { diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 42a517879b..b6489e7a95 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1527,7 +1527,7 @@ void DisplayServerWindows::process_events() { if (!drop_events) { _process_key_events(); - Input::get_singleton()->flush_accumulated_events(); + Input::get_singleton()->flush_buffered_events(); } } @@ -1738,7 +1738,7 @@ void DisplayServerWindows::_touch_event(WindowID p_window, bool p_pressed, float event->set_pressed(p_pressed); event->set_position(Vector2(p_x, p_y)); - Input::get_singleton()->accumulate_input_event(event); + Input::get_singleton()->parse_input_event(event); } void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y, int idx) { @@ -1757,7 +1757,7 @@ void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y, event->set_position(Vector2(p_x, p_y)); event->set_relative(Vector2(p_x, p_y) - curr->get()); - Input::get_singleton()->accumulate_input_event(event); + Input::get_singleton()->parse_input_event(event); curr->get() = Vector2(p_x, p_y); } @@ -2022,7 +2022,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } if (windows[window_id].window_has_focus && mm->get_relative() != Vector2()) - Input::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->parse_input_event(mm); } delete[] lpb; } break; @@ -2111,7 +2111,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA old_x = mm->get_position().x; old_y = mm->get_position().y; if (windows[window_id].window_has_focus) - Input::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->parse_input_event(mm); } return 0; } @@ -2258,7 +2258,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA old_x = mm->get_position().x; old_y = mm->get_position().y; if (windows[window_id].window_has_focus) { - Input::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->parse_input_event(mm); } return 0; //Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event @@ -2364,7 +2364,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA old_x = mm->get_position().x; old_y = mm->get_position().y; if (windows[window_id].window_has_focus) - Input::get_singleton()->accumulate_input_event(mm); + Input::get_singleton()->parse_input_event(mm); } break; case WM_LBUTTONDOWN: @@ -2533,7 +2533,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb->set_global_position(mb->get_position()); - Input::get_singleton()->accumulate_input_event(mb); + Input::get_singleton()->parse_input_event(mb); if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) { //send release for mouse wheel Ref<InputEventMouseButton> mbd = mb->duplicate(); @@ -2541,7 +2541,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA last_button_state &= (MouseButton) ~(1 << (mbd->get_button_index() - 1)); mbd->set_button_mask(last_button_state); mbd->set_pressed(false); - Input::get_singleton()->accumulate_input_event(mbd); + Input::get_singleton()->parse_input_event(mbd); } } break; @@ -2866,7 +2866,7 @@ void DisplayServerWindows::_process_key_events() { if (k->get_unicode() < 32) k->set_unicode(0); - Input::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->parse_input_event(k); } //do nothing @@ -2924,7 +2924,7 @@ void DisplayServerWindows::_process_key_events() { k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30)))); - Input::get_singleton()->accumulate_input_event(k); + Input::get_singleton()->parse_input_event(k); } break; } diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index 026f0a85a6..96a3134691 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -30,7 +30,6 @@ #include "animated_sprite_2d.h" -#include "core/os/os.h" #include "scene/main/viewport.h" #include "scene/scene_string_names.h" diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index 0769b19b50..ac4b20a6d9 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -33,7 +33,6 @@ #include "scene/2d/node_2d.h" #include "scene/resources/sprite_frames.h" -#include "scene/resources/texture.h" class AnimatedSprite2D : public Node2D { GDCLASS(AnimatedSprite2D, Node2D); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index cf84767151..d78b9847e6 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -32,7 +32,6 @@ #include "scene/scene_string_names.h" #include "servers/audio_server.h" -#include "servers/physics_server_2d.h" void Area2D::set_space_override_mode(SpaceOverride p_mode) { space_override = p_mode; diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 4b96689613..e0b994f27d 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -30,7 +30,6 @@ #include "audio_stream_player_2d.h" -#include "core/config/engine.h" #include "scene/2d/area_2d.h" #include "scene/main/window.h" diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 21f524c703..cf05a49b00 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -31,7 +31,6 @@ #ifndef AUDIO_STREAM_PLAYER_2D_H #define AUDIO_STREAM_PLAYER_2D_H -#include "core/templates/safe_refcount.h" #include "scene/2d/node_2d.h" #include "servers/audio/audio_stream.h" #include "servers/audio_server.h" diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 2219437c14..ac75d81272 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -30,10 +30,7 @@ #include "camera_2d.h" -#include "core/config/engine.h" -#include "core/math/math_funcs.h" -#include "scene/scene_string_names.h" -#include "servers/rendering_server.h" +#include "scene/main/window.h" void Camera2D::_update_scroll() { if (!is_inside_tree()) { diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 95b49cf076..d697515547 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -32,7 +32,6 @@ #define CAMERA_2D_H #include "scene/2d/node_2d.h" -#include "scene/main/window.h" class Camera2D : public Node2D { GDCLASS(Camera2D, Node2D); diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 2a2fde80e2..8c8a292ad7 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -31,7 +31,6 @@ #include "collision_polygon_2d.h" #include "collision_object_2d.h" -#include "core/config/engine.h" #include "core/math/geometry_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index 95dd8c9e21..6b32923010 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -32,7 +32,6 @@ #define COLLISION_POLYGON_2D_H #include "scene/2d/node_2d.h" -#include "scene/resources/shape_2d.h" class CollisionObject2D; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 60780f1cc3..d52795f0d5 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -31,14 +31,8 @@ #include "collision_shape_2d.h" #include "collision_object_2d.h" -#include "core/config/engine.h" -#include "scene/resources/capsule_shape_2d.h" -#include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" -#include "scene/resources/line_shape_2d.h" -#include "scene/resources/rectangle_shape_2d.h" -#include "scene/resources/segment_shape_2d.h" void CollisionShape2D::_shape_changed() { update(); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index ced1c5cb81..559bd2fd16 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -32,9 +32,7 @@ #include "core/core_string_names.h" #include "scene/2d/gpu_particles_2d.h" -#include "scene/main/canvas_item.h" #include "scene/resources/particles_material.h" -#include "servers/rendering_server.h" void CPUParticles2D::set_emitting(bool p_emitting) { if (emitting == p_emitting) { diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 1a1f35fca5..0f8950375f 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -31,9 +31,7 @@ #ifndef CPU_PARTICLES_2D_H #define CPU_PARTICLES_2D_H -#include "core/templates/rid.h" #include "scene/2d/node_2d.h" -#include "scene/resources/texture.h" class CPUParticles2D : public Node2D { private: diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 58525c6954..47bf1bc77c 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -30,9 +30,7 @@ #include "gpu_particles_2d.h" -#include "core/os/os.h" #include "scene/resources/particles_material.h" -#include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED #include "core/config/engine.h" diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index 67a87f2339..d7eee461b4 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -31,9 +31,7 @@ #ifndef PARTICLES_2D_H #define PARTICLES_2D_H -#include "core/templates/rid.h" #include "scene/2d/node_2d.h" -#include "scene/resources/texture.h" class GPUParticles2D : public Node2D { private: diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index dbba6917b5..eabbf313d0 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -30,10 +30,8 @@ #include "joints_2d.h" -#include "core/config/engine.h" #include "physics_body_2d.h" #include "scene/scene_string_names.h" -#include "servers/physics_server_2d.h" void Joint2D::_disconnect_signals() { Node *node_a = get_node_or_null(a); diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index ce57895341..1853b3428c 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -30,9 +30,6 @@ #include "light_2d.h" -#include "core/config/engine.h" -#include "servers/rendering_server.h" - void Light2D::_update_light_visibility() { if (!is_inside_tree()) { return; diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index 654e61422b..16c88d00e9 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -31,10 +31,7 @@ #ifndef LINE_BUILDER_H #define LINE_BUILDER_H -#include "core/math/color.h" -#include "core/math/vector2.h" #include "line_2d.h" -#include "scene/resources/gradient.h" class LineBuilder { public: diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index e9a95b680c..927f6c1c42 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -30,7 +30,6 @@ #include "navigation_agent_2d.h" -#include "core/config/engine.h" #include "core/math/geometry_2d.h" #include "servers/navigation_server_2d.h" diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 234cad333f..052cd78a56 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -31,7 +31,6 @@ #ifndef NAVIGATION_AGENT_2D_H #define NAVIGATION_AGENT_2D_H -#include "core/templates/vector.h" #include "scene/main/node.h" class Node2D; diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index a06f7a9fd0..c99b9777cd 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -31,7 +31,6 @@ #include "navigation_obstacle_2d.h" #include "scene/2d/collision_shape_2d.h" -#include "scene/2d/physics_body_2d.h" #include "servers/navigation_server_2d.h" void NavigationObstacle2D::_bind_methods() { diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 58b20ccad0..72ea6541e3 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -30,7 +30,6 @@ #include "navigation_region_2d.h" -#include "core/config/engine.h" #include "core/core_string_names.h" #include "core/math/geometry_2d.h" #include "core/os/mutex.h" diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index a744ef40f6..6a8788ee6e 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -30,11 +30,6 @@ #include "node_2d.h" -#include "core/object/message_queue.h" -#include "scene/gui/control.h" -#include "scene/main/window.h" -#include "servers/rendering_server.h" - #ifdef TOOLS_ENABLED Dictionary Node2D::_edit_get_state() const { Dictionary state; diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 27134dab29..3745c5b587 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -31,8 +31,6 @@ #ifndef PARALLAX_BACKGROUND_H #define PARALLAX_BACKGROUND_H -#include "scene/2d/camera_2d.h" -#include "scene/2d/node_2d.h" #include "scene/main/canvas_layer.h" class ParallaxBackground : public CanvasLayer { diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 228020d383..1fe6a4a4b8 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -30,7 +30,6 @@ #include "parallax_layer.h" -#include "core/config/engine.h" #include "parallax_background.h" void ParallaxLayer::set_motion_scale(const Size2 &p_scale) { diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 9912612c4f..ed30e871d7 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -30,9 +30,7 @@ #include "path_2d.h" -#include "core/config/engine.h" #include "core/math/geometry_2d.h" -#include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED #include "editor/editor_scale.h" diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index fa19d5c2cf..d52c293763 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -30,12 +30,7 @@ #include "physics_body_2d.h" -#include "core/config/engine.h" #include "core/core_string_names.h" -#include "core/math/math_funcs.h" -#include "core/object/class_db.h" -#include "core/templates/list.h" -#include "core/templates/rid.h" #include "scene/scene_string_names.h" void PhysicsBody2D::_bind_methods() { diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 1019f85c8a..4f053ff8b0 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -30,9 +30,6 @@ #include "position_2d.h" -#include "core/config/engine.h" -#include "scene/resources/texture.h" - const real_t DEFAULT_GIZMO_EXTENTS = 10.0; void Position2D::_draw_cross() { diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 546536f546..3ac2128c2e 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -31,9 +31,6 @@ #include "ray_cast_2d.h" #include "collision_object_2d.h" -#include "core/config/engine.h" -#include "physics_body_2d.h" -#include "servers/physics_server_2d.h" void RayCast2D::set_target_position(const Vector2 &p_point) { target_position = p_point; diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index e7cef965fe..fe3e867424 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -29,7 +29,6 @@ /*************************************************************************/ #include "remote_transform_2d.h" -#include "scene/scene_string_names.h" void RemoteTransform2D::_update_cache() { cache = ObjectID(); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 85d632af00..3d44c629d3 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -30,8 +30,6 @@ #include "skeleton_2d.h" -#include "scene/resources/skeleton_modification_2d.h" - #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" #include "editor/plugins/canvas_item_editor_plugin.h" diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp index 40e0f4523f..5761f19a53 100644 --- a/scene/2d/sprite_2d.cpp +++ b/scene/2d/sprite_2d.cpp @@ -31,7 +31,6 @@ #include "sprite_2d.h" #include "core/core_string_names.h" -#include "core/os/os.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index e2a415e5aa..74eb3f2fc2 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -31,8 +31,6 @@ #include "tile_map.h" #include "core/io/marshalls.h" -#include "core/math/geometry_2d.h" -#include "core/os/os.h" #include "servers/navigation_server_2d.h" diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index dce18f7682..4e2d76a7b7 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -31,8 +31,6 @@ #ifndef TILE_MAP_H #define TILE_MAP_H -#include "core/templates/self_list.h" -#include "core/templates/vset.h" #include "scene/2d/node_2d.h" #include "scene/gui/control.h" #include "scene/resources/tile_set.h" diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 7c345ad377..00e4e1dc62 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -30,11 +30,8 @@ #include "touch_screen_button.h" -#include "core/input/input.h" -#include "core/input/input_map.h" -#include "core/os/os.h" #include "scene/main/window.h" -# + void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp index 25237edacf..eb4bedb6a3 100644 --- a/scene/2d/visible_on_screen_notifier_2d.cpp +++ b/scene/2d/visible_on_screen_notifier_2d.cpp @@ -30,12 +30,6 @@ #include "visible_on_screen_notifier_2d.h" -#include "core/config/engine.h" -#include "gpu_particles_2d.h" -#include "scene/2d/animated_sprite_2d.h" -#include "scene/2d/physics_body_2d.h" -#include "scene/animation/animation_player.h" -#include "scene/main/window.h" #include "scene/scene_string_names.h" #ifdef TOOLS_ENABLED diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index cd64a813dd..2e917c4a42 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -32,7 +32,6 @@ #include "scene/scene_string_names.h" #include "servers/audio_server.h" -#include "servers/physics_server_3d.h" void Area3D::set_space_override_mode(SpaceOverride p_mode) { space_override = p_mode; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 6318aad08e..711e7fbd5a 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -30,11 +30,10 @@ #include "audio_stream_player_3d.h" -#include "core/config/engine.h" #include "scene/3d/area_3d.h" #include "scene/3d/camera_3d.h" #include "scene/3d/listener_3d.h" -#include "scene/main/window.h" +#include "scene/main/viewport.h" // Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004) // Speaker-Placement Correction Amplitude Panning (SPCAP) diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index 8aec493602..f86e19403c 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -31,12 +31,10 @@ #ifndef AUDIO_STREAM_PLAYER_3D_H #define AUDIO_STREAM_PLAYER_3D_H -#include "core/templates/safe_refcount.h" #include "scene/3d/node_3d.h" #include "scene/3d/velocity_tracker_3d.h" #include "servers/audio/audio_filter_sw.h" #include "servers/audio/audio_stream.h" -#include "servers/audio_server.h" class Camera3D; class AudioStreamPlayer3D : public Node3D { diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 9dc1df202c..3ada9072c2 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -31,10 +31,8 @@ #include "camera_3d.h" #include "collision_object_3d.h" -#include "core/config/engine.h" #include "core/math/camera_matrix.h" -#include "scene/resources/material.h" -#include "scene/resources/surface_tool.h" +#include "scene/main/viewport.h" void Camera3D::_update_audio_listener_state() { } diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index b7bf5566e7..3b704944b0 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -33,9 +33,6 @@ #include "scene/3d/node_3d.h" #include "scene/3d/velocity_tracker_3d.h" -#include "scene/main/window.h" -#include "scene/resources/camera_effects.h" -#include "scene/resources/environment.h" class Camera3D : public Node3D { GDCLASS(Camera3D, Node3D); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 75bb2995d3..36d9bfba82 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -30,7 +30,6 @@ #include "collision_object_3d.h" -#include "core/config/engine.h" #include "scene/scene_string_names.h" void CollisionObject3D::_notification(int p_what) { diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 2e74d84465..c066960eb4 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -32,8 +32,6 @@ #define COLLISION_OBJECT_3D_H #include "scene/3d/node_3d.h" -#include "scene/resources/shape_3d.h" -#include "servers/physics_server_3d.h" class CollisionObject3D : public Node3D { GDCLASS(CollisionObject3D, Node3D); diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index 42645f47d4..d5835586f9 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -32,7 +32,6 @@ #include "collision_object_3d.h" #include "core/math/geometry_2d.h" -#include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" void CollisionPolygon3D::_build_polygon() { diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 36d4c8f4f0..d4668a24f2 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -30,12 +30,10 @@ #include "collision_shape_3d.h" -#include "core/math/quick_hull.h" #include "mesh_instance_3d.h" #include "physics_body_3d.h" #include "scene/resources/concave_polygon_shape_3d.h" #include "scene/resources/convex_polygon_shape_3d.h" -#include "servers/rendering_server.h" void CollisionShape3D::make_convex_from_siblings() { Node *p = get_parent(); diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index f69c1e38eb..cb7fe21eae 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -33,6 +33,7 @@ #include "scene/3d/node_3d.h" #include "scene/resources/shape_3d.h" + class CollisionObject3D; class CollisionShape3D : public Node3D { GDCLASS(CollisionShape3D, Node3D); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 5a358e1917..e2095940ff 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -32,8 +32,8 @@ #include "scene/3d/camera_3d.h" #include "scene/3d/gpu_particles_3d.h" +#include "scene/main/viewport.h" #include "scene/resources/particles_material.h" -#include "servers/rendering_server.h" AABB CPUParticles3D::get_aabb() const { return AABB(); diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index bb6699ddc7..5b60322f05 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -31,8 +31,6 @@ #ifndef CPU_PARTICLES_H #define CPU_PARTICLES_H -#include "core/templates/rid.h" -#include "core/templates/safe_refcount.h" #include "scene/3d/visual_instance_3d.h" class CPUParticles3D : public GeometryInstance3D { diff --git a/scene/3d/decal.h b/scene/3d/decal.h index 041c8f97b2..e9bda3276d 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -32,8 +32,6 @@ #define DECAL_H #include "scene/3d/visual_instance_3d.h" -#include "scene/resources/texture.h" -#include "servers/rendering_server.h" class Decal : public VisualInstance3D { GDCLASS(Decal, VisualInstance3D); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 7a6410ec51..d56228df66 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -30,11 +30,8 @@ #include "gpu_particles_3d.h" -#include "core/os/os.h" #include "scene/resources/particles_material.h" -#include "servers/rendering_server.h" - AABB GPUParticles3D::get_aabb() const { return AABB(); } @@ -487,6 +484,7 @@ void GPUParticles3D::set_skin(const Ref<Skin> &p_skin) { skin = p_skin; _skinning_changed(); } + Ref<Skin> GPUParticles3D::get_skin() const { return skin; } diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index 31f33fde59..5e96f660da 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -31,9 +31,7 @@ #ifndef PARTICLES_H #define PARTICLES_H -#include "core/templates/rid.h" #include "scene/3d/visual_instance_3d.h" -#include "scene/resources/material.h" #include "scene/resources/skin.h" class GPUParticles3D : public GeometryInstance3D { diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 8b214a9cfb..a34a30913e 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -30,7 +30,6 @@ #include "gpu_particles_collision_3d.h" -#include "core/templates/thread_work_pool.h" #include "mesh_instance_3d.h" #include "scene/3d/camera_3d.h" #include "scene/main/viewport.h" diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index f96edd4bfc..fbf68ed6df 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -32,9 +32,7 @@ #define GPU_PARTICLES_COLLISION_3D_H #include "core/templates/local_vector.h" -#include "core/templates/rid.h" #include "scene/3d/visual_instance_3d.h" -#include "scene/resources/material.h" class GPUParticlesCollision3D : public VisualInstance3D { GDCLASS(GPUParticlesCollision3D, VisualInstance3D); diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 40f33dfa72..508f8a70df 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -30,10 +30,6 @@ #include "light_3d.h" -#include "core/config/engine.h" -#include "core/config/project_settings.h" -#include "scene/resources/surface_tool.h" - bool Light3D::_can_gizmo_scale() const { return false; } @@ -216,6 +212,10 @@ void Light3D::_validate_property(PropertyInfo &property) const { property.usage = PROPERTY_USAGE_NONE; } + if (get_light_type() == RS::LIGHT_SPOT && property.name == "shadow_normal_bias") { + property.usage = PROPERTY_USAGE_NONE; + } + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") { property.usage = PROPERTY_USAGE_NONE; } @@ -344,7 +344,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_SHADOW_FADE_START, 0.8); set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0); set_param(PARAM_SHADOW_BLUR, 1.0); - set_param(PARAM_SHADOW_BIAS, 0.02); + set_param(PARAM_SHADOW_BIAS, 0.03); set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 0.1); @@ -426,7 +426,8 @@ DirectionalLight3D::DirectionalLight3D() : set_param(PARAM_SHADOW_FADE_START, 0.8); // Increase the default shadow bias to better suit most scenes. // Leave normal bias untouched as it doesn't benefit DirectionalLight3D as much as OmniLight3D. - set_param(PARAM_SHADOW_BIAS, 0.05); + set_param(PARAM_SHADOW_BIAS, 0.1); + set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); blend_splits = false; } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 51ed2fcf50..ecea60339f 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -32,8 +32,6 @@ #define LIGHT_3D_H #include "scene/3d/visual_instance_3d.h" -#include "scene/resources/texture.h" -#include "servers/rendering_server.h" class Light3D : public VisualInstance3D { GDCLASS(Light3D, VisualInstance3D); diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 0085c8933d..7dd083e314 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -31,14 +31,9 @@ #include "lightmap_gi.h" #include "core/io/config_file.h" -#include "core/io/dir_access.h" -#include "core/io/file_access.h" -#include "core/io/resource_saver.h" -#include "core/math/camera_matrix.h" #include "core/math/delaunay_3d.h" -#include "core/os/os.h" -#include "core/templates/sort_array.h" #include "lightmap_probe.h" +#include "scene/3d/mesh_instance_3d.h" void LightmapGIData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance) { User user; diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h index 8a54512383..e73350fd64 100644 --- a/scene/3d/lightmap_gi.h +++ b/scene/3d/lightmap_gi.h @@ -34,10 +34,7 @@ #include "core/templates/local_vector.h" #include "scene/3d/light_3d.h" #include "scene/3d/lightmapper.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/multimesh_instance_3d.h" #include "scene/3d/visual_instance_3d.h" -#include "scene/resources/sky.h" class LightmapGIData : public Resource { GDCLASS(LightmapGIData, Resource); diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h index 3a6a88d435..d028628901 100644 --- a/scene/3d/lightmapper.h +++ b/scene/3d/lightmapper.h @@ -31,8 +31,9 @@ #ifndef LIGHTMAPPER_H #define LIGHTMAPPER_H -#include "scene/resources/mesh.h" -#include "servers/rendering/rendering_device.h" +#include "core/object/ref_counted.h" + +class Image; #if !defined(__aligned) diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp index 43d6f262d8..1c52933ee5 100644 --- a/scene/3d/listener_3d.cpp +++ b/scene/3d/listener_3d.cpp @@ -30,7 +30,7 @@ #include "listener_3d.h" -#include "scene/resources/mesh.h" +#include "scene/main/viewport.h" void Listener3D::_update_audio_listener_state() { } diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h index bcc66f167c..25eacf5135 100644 --- a/scene/3d/listener_3d.h +++ b/scene/3d/listener_3d.h @@ -32,7 +32,6 @@ #define LISTENER_3D_H #include "scene/3d/node_3d.h" -#include "scene/main/window.h" class Listener3D : public Node3D { GDCLASS(Listener3D, Node3D); diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 9ca1d55d0b..de6925244a 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -33,8 +33,6 @@ #include "collision_shape_3d.h" #include "core/core_string_names.h" #include "physics_body_3d.h" -#include "scene/resources/material.h" -#include "skeleton_3d.h" bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) { //this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else. diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index e2d20d0a90..beb7f6cf95 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -31,10 +31,10 @@ #ifndef MESH_INSTANCE_H #define MESH_INSTANCE_H -#include "scene/3d/skeleton_3d.h" #include "scene/3d/visual_instance_3d.h" -#include "scene/resources/mesh.h" -#include "scene/resources/skin.h" + +class Skin; +class SkinReference; class MeshInstance3D : public GeometryInstance3D { GDCLASS(MeshInstance3D, GeometryInstance3D); diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index f890ceeb95..c2d5c757db 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -30,7 +30,6 @@ #include "navigation_agent_3d.h" -#include "core/config/engine.h" #include "servers/navigation_server_3d.h" void NavigationAgent3D::_bind_methods() { diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index 56da2d1acf..bebfdc5f7e 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -31,7 +31,6 @@ #ifndef NAVIGATION_AGENT_H #define NAVIGATION_AGENT_H -#include "core/templates/vector.h" #include "scene/main/node.h" class Node3D; diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index 2f78f624a4..ab0b158303 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -32,7 +32,6 @@ #define NAVIGATION_OBSTACLE_H #include "scene/3d/node_3d.h" -#include "scene/main/node.h" class NavigationObstacle3D : public Node { GDCLASS(NavigationObstacle3D, Node); diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 2976dad39d..8a51a259f7 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -30,7 +30,6 @@ #include "navigation_region_3d.h" -#include "core/os/thread.h" #include "mesh_instance_3d.h" #include "servers/navigation_server_3d.h" diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index c2045215b1..ec7761ef93 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -32,7 +32,6 @@ #define NAVIGATION_REGION_H #include "scene/3d/node_3d.h" -#include "scene/resources/mesh.h" #include "scene/resources/navigation_mesh.h" class NavigationRegion3D : public Node3D { diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 8f186199db..12470939f5 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -30,11 +30,9 @@ #include "node_3d.h" -#include "core/config/engine.h" #include "core/object/message_queue.h" #include "scene/3d/visual_instance_3d.h" -#include "scene/main/scene_tree.h" -#include "scene/main/window.h" +#include "scene/main/viewport.h" #include "scene/scene_string_names.h" /* diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index da54452abb..0fd0c4e205 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -32,7 +32,6 @@ #define NODE_3D_H #include "scene/main/node.h" -#include "scene/main/scene_tree.h" class Node3DGizmo : public RefCounted { GDCLASS(Node3DGizmo, RefCounted); diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 6818acf69d..9ea37e4bfa 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -30,9 +30,6 @@ #include "path_3d.h" -#include "core/config/engine.h" -#include "scene/scene_string_names.h" - void Path3D::_notification(int p_what) { } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index e1e6153bfb..12c91271d4 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -30,14 +30,8 @@ #include "physics_body_3d.h" -#include "core/config/engine.h" #include "core/core_string_names.h" -#include "core/object/class_db.h" -#include "core/templates/list.h" -#include "core/templates/rid.h" -#include "scene/3d/collision_shape_3d.h" #include "scene/scene_string_names.h" -#include "servers/navigation_server_3d.h" #ifdef TOOLS_ENABLED #include "editor/plugins/node_3d_editor_plugin.h" diff --git a/scene/3d/position_3d.cpp b/scene/3d/position_3d.cpp index b231ba0df7..9747465103 100644 --- a/scene/3d/position_3d.cpp +++ b/scene/3d/position_3d.cpp @@ -29,7 +29,6 @@ /*************************************************************************/ #include "position_3d.h" -#include "scene/resources/mesh.h" Position3D::Position3D() { } diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index e757d6d3f4..fd4c6e7416 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -31,9 +31,7 @@ #include "ray_cast_3d.h" #include "collision_object_3d.h" -#include "core/config/engine.h" #include "mesh_instance_3d.h" -#include "servers/physics_server_3d.h" void RayCast3D::set_target_position(const Vector3 &p_point) { target_position = p_point; diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index 4bf20c89c5..d1b9b12f65 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -32,9 +32,6 @@ #define REFLECTIONPROBE_H #include "scene/3d/visual_instance_3d.h" -#include "scene/resources/sky.h" -#include "scene/resources/texture.h" -#include "servers/rendering_server.h" class ReflectionProbe : public VisualInstance3D { GDCLASS(ReflectionProbe, VisualInstance3D); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 86e2af7df5..c996735761 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -30,12 +30,8 @@ #include "skeleton_3d.h" -#include "core/config/engine.h" -#include "core/config/project_settings.h" #include "core/object/message_queue.h" -#include "core/variant/type_info.h" #include "scene/3d/physics_body_3d.h" -#include "scene/resources/surface_tool.h" #include "scene/scene_string_names.h" void SkinReference::_skin_changed() { diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 3fdf5321a5..bccad97d5f 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -31,7 +31,6 @@ #ifndef SKELETON_3D_H #define SKELETON_3D_H -#include "core/templates/rid.h" #include "scene/3d/node_3d.h" #include "scene/resources/skin.h" diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 81dfe675c3..4cf08e7c99 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -33,11 +33,6 @@ #ifndef _3D_DISABLED -/** - * @author AndreaCatania - */ - -#include "core/math/transform_3d.h" #include "scene/3d/skeleton_3d.h" class FabrikInverseKinematic { diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 3dbeac5e97..28ff3e9412 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -30,13 +30,7 @@ #include "soft_body_3d.h" -#include "core/object/class_db.h" -#include "core/os/os.h" -#include "core/templates/list.h" -#include "core/templates/rid.h" -#include "scene/3d/collision_object_3d.h" #include "scene/3d/physics_body_3d.h" -#include "scene/3d/skeleton_3d.h" SoftBodyRenderingServerHandler::SoftBodyRenderingServerHandler() {} diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 5e9265b4c3..4748a9d889 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -30,11 +30,6 @@ #include "spring_arm_3d.h" -#include "core/config/engine.h" -#include "scene/3d/collision_object_3d.h" -#include "scene/resources/sphere_shape_3d.h" -#include "servers/physics_server_3d.h" - void SpringArm3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index d35b9ffe1b..90c2a309e1 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -31,8 +31,8 @@ #ifndef SPRITE_3D_H #define SPRITE_3D_H -#include "scene/2d/animated_sprite_2d.h" #include "scene/3d/visual_instance_3d.h" +#include "scene/resources/sprite_frames.h" class SpriteBase3D : public GeometryInstance3D { GDCLASS(SpriteBase3D, GeometryInstance3D); diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp index 8f4fecb348..200664a41b 100644 --- a/scene/3d/velocity_tracker_3d.cpp +++ b/scene/3d/velocity_tracker_3d.cpp @@ -29,7 +29,6 @@ /*************************************************************************/ #include "velocity_tracker_3d.h" -#include "core/config/engine.h" void VelocityTracker3D::set_track_physics_step(bool p_track_physics_step) { physics_step = p_track_physics_step; diff --git a/scene/3d/visible_on_screen_notifier_3d.cpp b/scene/3d/visible_on_screen_notifier_3d.cpp index 6a80aa3f45..3d0bc3df9c 100644 --- a/scene/3d/visible_on_screen_notifier_3d.cpp +++ b/scene/3d/visible_on_screen_notifier_3d.cpp @@ -30,10 +30,6 @@ #include "visible_on_screen_notifier_3d.h" -#include "core/config/engine.h" -#include "scene/3d/camera_3d.h" -#include "scene/3d/physics_body_3d.h" -#include "scene/animation/animation_player.h" #include "scene/scene_string_names.h" void VisibleOnScreenNotifier3D::_visibility_enter() { diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index b437379b2a..73c2887983 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -31,8 +31,6 @@ #include "visual_instance_3d.h" #include "scene/scene_string_names.h" -#include "servers/rendering_server.h" -#include "skeleton_3d.h" AABB VisualInstance3D::get_transformed_aabb() const { return get_global_transform().xform(get_aabb()); @@ -416,7 +414,7 @@ void GeometryInstance3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_occlusion_culling"), "set_ignore_occlusion_culling", "is_ignoring_occlusion_culling"); ADD_GROUP("Global Illumination", "gi_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Baked,Dynamic"), "set_gi_mode", "get_gi_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, "1x,2x,4x,8x"), "set_lightmap_scale", "get_lightmap_scale"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×")), "set_lightmap_scale", "get_lightmap_scale"); ADD_GROUP("Visibility Range", "visibility_range_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_begin", "get_visibility_range_begin"); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index aa64195c2b..8d24e13d47 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -31,10 +31,7 @@ #ifndef VISUAL_INSTANCE_H #define VISUAL_INSTANCE_H -#include "core/math/face3.h" -#include "core/templates/rid.h" #include "scene/3d/node_3d.h" -#include "scene/resources/material.h" class VisualInstance3D : public Node3D { GDCLASS(VisualInstance3D, Node3D); diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp index 5cf7522667..d3d12d94e9 100644 --- a/scene/3d/voxel_gi.cpp +++ b/scene/3d/voxel_gi.cpp @@ -30,9 +30,8 @@ #include "voxel_gi.h" -#include "core/os/os.h" - #include "mesh_instance_3d.h" +#include "multimesh_instance_3d.h" #include "voxelizer.h" void VoxelGIData::_set_data(const Dictionary &p_data) { diff --git a/scene/3d/voxel_gi.h b/scene/3d/voxel_gi.h index 434d209421..5d0dda1ba3 100644 --- a/scene/3d/voxel_gi.h +++ b/scene/3d/voxel_gi.h @@ -31,7 +31,6 @@ #ifndef VOXEL_GI_H #define VOXEL_GI_H -#include "multimesh_instance_3d.h" #include "scene/3d/visual_instance_3d.h" class VoxelGIData : public Resource { diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 6124326d2d..2d32379d69 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -29,11 +29,6 @@ /*************************************************************************/ #include "voxelizer.h" -#include "core/math/geometry_3d.h" -#include "core/os/os.h" -#include "core/os/threaded_array_processor.h" - -#include <stdlib.h> static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv, const Vector3 *p_normal, Vector2 &r_uv, Vector3 &r_normal) { if (p_pos.is_equal_approx(p_vtx[0])) { diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index e500d2d4c3..09c126bc4e 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -31,8 +31,6 @@ #ifndef VOXEL_LIGHT_BAKER_H #define VOXEL_LIGHT_BAKER_H -#include "core/math/vector3i.h" -#include "scene/3d/mesh_instance_3d.h" #include "scene/resources/multimesh.h" class Voxelizer { diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 352bef072f..26fa43b969 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -30,6 +30,7 @@ #include "world_environment.h" +#include "scene/3d/node_3d.h" #include "scene/main/window.h" void WorldEnvironment::_notification(int p_what) { diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index 9e85982381..310d1e96a5 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -31,7 +31,7 @@ #ifndef SCENARIO_FX_H #define SCENARIO_FX_H -#include "scene/3d/node_3d.h" +#include "scene/main/node.h" #include "scene/resources/camera_effects.h" #include "scene/resources/environment.h" diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index e620f33478..ebfb58e9fe 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -30,9 +30,8 @@ #include "xr_nodes.h" -#include "core/input/input.h" +#include "scene/main/viewport.h" #include "servers/xr/xr_interface.h" -#include "servers/xr_server.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h index 312287a93b..6e54ff83d7 100644 --- a/scene/3d/xr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -32,8 +32,6 @@ #define XR_NODES_H #include "scene/3d/camera_3d.h" -#include "scene/3d/node_3d.h" -#include "scene/resources/mesh.h" #include "servers/xr/xr_positional_tracker.h" /** diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 0355405d7c..c7090e7231 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -35,6 +35,8 @@ #include "core/templates/local_vector.h" +class Panel; + class Popup : public Window { GDCLASS(Popup, Window); diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 0a76351885..f2415eaf71 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -30,289 +30,17 @@ #include "canvas_item.h" -#include "core/input/input.h" #include "core/object/message_queue.h" #include "scene/2d/canvas_group.h" #include "scene/main/canvas_layer.h" -#include "scene/main/viewport.h" #include "scene/main/window.h" +#include "scene/resources/canvas_item_material.h" #include "scene/resources/font.h" +#include "scene/resources/multimesh.h" #include "scene/resources/style_box.h" -#include "scene/resources/texture.h" +#include "scene/resources/world_2d.h" #include "scene/scene_string_names.h" -#include "servers/rendering_server.h" -Mutex CanvasItemMaterial::material_mutex; -SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = nullptr; -Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map; -CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = nullptr; - -void CanvasItemMaterial::init_shaders() { - dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); - - shader_names = memnew(ShaderNames); - - shader_names->particles_anim_h_frames = "particles_anim_h_frames"; - shader_names->particles_anim_v_frames = "particles_anim_v_frames"; - shader_names->particles_anim_loop = "particles_anim_loop"; -} - -void CanvasItemMaterial::finish_shaders() { - memdelete(dirty_materials); - memdelete(shader_names); - dirty_materials = nullptr; -} - -void CanvasItemMaterial::_update_shader() { - dirty_materials->remove(&element); - - MaterialKey mk = _compute_key(); - if (mk.key == current_key.key) { - return; //no update required in the end - } - - if (shader_map.has(current_key)) { - shader_map[current_key].users--; - if (shader_map[current_key].users == 0) { - //deallocate shader, as it's no longer in use - RS::get_singleton()->free(shader_map[current_key].shader); - shader_map.erase(current_key); - } - } - - current_key = mk; - - if (shader_map.has(mk)) { - RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader); - shader_map[mk].users++; - return; - } - - //must create a shader! - - String code = "shader_type canvas_item;\nrender_mode "; - switch (blend_mode) { - case BLEND_MODE_MIX: - code += "blend_mix"; - break; - case BLEND_MODE_ADD: - code += "blend_add"; - break; - case BLEND_MODE_SUB: - code += "blend_sub"; - break; - case BLEND_MODE_MUL: - code += "blend_mul"; - break; - case BLEND_MODE_PREMULT_ALPHA: - code += "blend_premul_alpha"; - break; - case BLEND_MODE_DISABLED: - code += "blend_disabled"; - break; - } - - switch (light_mode) { - case LIGHT_MODE_NORMAL: - break; - case LIGHT_MODE_UNSHADED: - code += ",unshaded"; - break; - case LIGHT_MODE_LIGHT_ONLY: - code += ",light_only"; - break; - } - - code += ";\n"; - - if (particles_animation) { - code += "uniform int particles_anim_h_frames;\n"; - code += "uniform int particles_anim_v_frames;\n"; - code += "uniform bool particles_anim_loop;\n\n"; - - code += "void vertex() {\n"; - code += " float h_frames = float(particles_anim_h_frames);\n"; - code += " float v_frames = float(particles_anim_v_frames);\n"; - code += " VERTEX.xy /= vec2(h_frames, v_frames);\n"; - code += " float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; - code += " float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; - code += " if (!particles_anim_loop) {\n"; - code += " particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; - code += " } else {\n"; - code += " particle_frame = mod(particle_frame, particle_total_frames);\n"; - code += " }"; - code += " UV /= vec2(h_frames, v_frames);\n"; - code += " UV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; - code += "}\n"; - } - - ShaderData shader_data; - shader_data.shader = RS::get_singleton()->shader_create(); - shader_data.users = 1; - - RS::get_singleton()->shader_set_code(shader_data.shader, code); - - shader_map[mk] = shader_data; - - RS::get_singleton()->material_set_shader(_get_material(), shader_data.shader); -} - -void CanvasItemMaterial::flush_changes() { - MutexLock lock(material_mutex); - - while (dirty_materials->first()) { - dirty_materials->first()->self()->_update_shader(); - } -} - -void CanvasItemMaterial::_queue_shader_change() { - MutexLock lock(material_mutex); - - if (!element.in_list()) { - dirty_materials->add(&element); - } -} - -bool CanvasItemMaterial::_is_shader_dirty() const { - MutexLock lock(material_mutex); - - return element.in_list(); -} - -void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) { - blend_mode = p_blend_mode; - _queue_shader_change(); -} - -CanvasItemMaterial::BlendMode CanvasItemMaterial::get_blend_mode() const { - return blend_mode; -} - -void CanvasItemMaterial::set_light_mode(LightMode p_light_mode) { - light_mode = p_light_mode; - _queue_shader_change(); -} - -CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const { - return light_mode; -} - -void CanvasItemMaterial::set_particles_animation(bool p_particles_anim) { - particles_animation = p_particles_anim; - _queue_shader_change(); - notify_property_list_changed(); -} - -bool CanvasItemMaterial::get_particles_animation() const { - return particles_animation; -} - -void CanvasItemMaterial::set_particles_anim_h_frames(int p_frames) { - particles_anim_h_frames = p_frames; - RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames); -} - -int CanvasItemMaterial::get_particles_anim_h_frames() const { - return particles_anim_h_frames; -} - -void CanvasItemMaterial::set_particles_anim_v_frames(int p_frames) { - particles_anim_v_frames = p_frames; - RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames); -} - -int CanvasItemMaterial::get_particles_anim_v_frames() const { - return particles_anim_v_frames; -} - -void CanvasItemMaterial::set_particles_anim_loop(bool p_loop) { - particles_anim_loop = p_loop; - RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop); -} - -bool CanvasItemMaterial::get_particles_anim_loop() const { - return particles_anim_loop; -} - -void CanvasItemMaterial::_validate_property(PropertyInfo &property) const { - if (property.name.begins_with("particles_anim_") && !particles_animation) { - property.usage = PROPERTY_USAGE_NONE; - } -} - -RID CanvasItemMaterial::get_shader_rid() const { - ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); - return shader_map[current_key].shader; -} - -Shader::Mode CanvasItemMaterial::get_shader_mode() const { - return Shader::MODE_CANVAS_ITEM; -} - -void CanvasItemMaterial::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &CanvasItemMaterial::set_blend_mode); - ClassDB::bind_method(D_METHOD("get_blend_mode"), &CanvasItemMaterial::get_blend_mode); - - ClassDB::bind_method(D_METHOD("set_light_mode", "light_mode"), &CanvasItemMaterial::set_light_mode); - ClassDB::bind_method(D_METHOD("get_light_mode"), &CanvasItemMaterial::get_light_mode); - - ClassDB::bind_method(D_METHOD("set_particles_animation", "particles_anim"), &CanvasItemMaterial::set_particles_animation); - ClassDB::bind_method(D_METHOD("get_particles_animation"), &CanvasItemMaterial::get_particles_animation); - - ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &CanvasItemMaterial::set_particles_anim_h_frames); - ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &CanvasItemMaterial::get_particles_anim_h_frames); - - ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &CanvasItemMaterial::set_particles_anim_v_frames); - ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &CanvasItemMaterial::get_particles_anim_v_frames); - - ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &CanvasItemMaterial::set_particles_anim_loop); - ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &CanvasItemMaterial::get_particles_anim_loop); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply,Premultiplied Alpha"), "set_blend_mode", "get_blend_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mode", PROPERTY_HINT_ENUM, "Normal,Unshaded,Light Only"), "set_light_mode", "get_light_mode"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_animation"), "set_particles_animation", "get_particles_animation"); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop"); - - BIND_ENUM_CONSTANT(BLEND_MODE_MIX); - BIND_ENUM_CONSTANT(BLEND_MODE_ADD); - BIND_ENUM_CONSTANT(BLEND_MODE_SUB); - BIND_ENUM_CONSTANT(BLEND_MODE_MUL); - BIND_ENUM_CONSTANT(BLEND_MODE_PREMULT_ALPHA); - - BIND_ENUM_CONSTANT(LIGHT_MODE_NORMAL); - BIND_ENUM_CONSTANT(LIGHT_MODE_UNSHADED); - BIND_ENUM_CONSTANT(LIGHT_MODE_LIGHT_ONLY); -} - -CanvasItemMaterial::CanvasItemMaterial() : - element(this) { - set_particles_anim_h_frames(1); - set_particles_anim_v_frames(1); - set_particles_anim_loop(false); - - current_key.invalid_key = 1; - _queue_shader_change(); -} - -CanvasItemMaterial::~CanvasItemMaterial() { - MutexLock lock(material_mutex); - - if (shader_map.has(current_key)) { - shader_map[current_key].users--; - if (shader_map[current_key].users == 0) { - //deallocate shader, as it's no longer in use - RS::get_singleton()->free(shader_map[current_key].shader); - shader_map.erase(current_key); - } - - RS::get_singleton()->material_set_shader(_get_material(), RID()); - } -} - -/////////////////////////////////////////////////////////////////// #ifdef TOOLS_ENABLED bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { if (_edit_use_rect()) { diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index f264764870..dc7ad2bf5d 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -33,132 +33,15 @@ #include "scene/main/node.h" #include "scene/main/scene_tree.h" -#include "scene/resources/material.h" -#include "scene/resources/multimesh.h" -#include "scene/resources/shader.h" -#include "scene/resources/texture.h" +#include "scene/resources/canvas_item_material.h" #include "servers/text_server.h" class CanvasLayer; -class Viewport; class Font; - +class MultiMesh; class StyleBox; - -class CanvasItemMaterial : public Material { - GDCLASS(CanvasItemMaterial, Material); - -public: - enum BlendMode { - BLEND_MODE_MIX, - BLEND_MODE_ADD, - BLEND_MODE_SUB, - BLEND_MODE_MUL, - BLEND_MODE_PREMULT_ALPHA, - BLEND_MODE_DISABLED - }; - - enum LightMode { - LIGHT_MODE_NORMAL, - LIGHT_MODE_UNSHADED, - LIGHT_MODE_LIGHT_ONLY - }; - -private: - union MaterialKey { - struct { - uint32_t blend_mode : 4; - uint32_t light_mode : 4; - uint32_t particles_animation : 1; - uint32_t invalid_key : 1; - }; - - uint32_t key = 0; - - bool operator<(const MaterialKey &p_key) const { - return key < p_key.key; - } - }; - - struct ShaderNames { - StringName particles_anim_h_frames; - StringName particles_anim_v_frames; - StringName particles_anim_loop; - }; - - static ShaderNames *shader_names; - - struct ShaderData { - RID shader; - int users = 0; - }; - - static Map<MaterialKey, ShaderData> shader_map; - - MaterialKey current_key; - - _FORCE_INLINE_ MaterialKey _compute_key() const { - MaterialKey mk; - mk.key = 0; - mk.blend_mode = blend_mode; - mk.light_mode = light_mode; - mk.particles_animation = particles_animation; - return mk; - } - - static Mutex material_mutex; - static SelfList<CanvasItemMaterial>::List *dirty_materials; - SelfList<CanvasItemMaterial> element; - - void _update_shader(); - _FORCE_INLINE_ void _queue_shader_change(); - _FORCE_INLINE_ bool _is_shader_dirty() const; - - BlendMode blend_mode = BLEND_MODE_MIX; - LightMode light_mode = LIGHT_MODE_NORMAL; - bool particles_animation = false; - - // Initialized in the constructor. - int particles_anim_h_frames; - int particles_anim_v_frames; - bool particles_anim_loop; - -protected: - static void _bind_methods(); - void _validate_property(PropertyInfo &property) const override; - -public: - void set_blend_mode(BlendMode p_blend_mode); - BlendMode get_blend_mode() const; - - void set_light_mode(LightMode p_light_mode); - LightMode get_light_mode() const; - - void set_particles_animation(bool p_particles_anim); - bool get_particles_animation() const; - - void set_particles_anim_h_frames(int p_frames); - int get_particles_anim_h_frames() const; - void set_particles_anim_v_frames(int p_frames); - int get_particles_anim_v_frames() const; - - void set_particles_anim_loop(bool p_loop); - bool get_particles_anim_loop() const; - - static void init_shaders(); - static void finish_shaders(); - static void flush_changes(); - - virtual RID get_shader_rid() const override; - - virtual Shader::Mode get_shader_mode() const override; - - CanvasItemMaterial(); - virtual ~CanvasItemMaterial(); -}; - -VARIANT_ENUM_CAST(CanvasItemMaterial::BlendMode) -VARIANT_ENUM_CAST(CanvasItemMaterial::LightMode) +class Window; +class World2D; class CanvasItem : public Node { GDCLASS(CanvasItem, Node); diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index 5de1ebf18d..9d8e0c203d 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -32,7 +32,6 @@ #define CANVAS_LAYER_H #include "scene/main/node.h" -#include "scene/resources/world_2d.h" class Viewport; class CanvasLayer : public Node { diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 2c6cefa771..f24d880045 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -30,7 +30,7 @@ #include "http_request.h" #include "core/io/compression.h" -#include "core/string/ustring.h" +#include "scene/main/timer.h" void HTTPRequest::_redirect_request(const String &p_new_url) { } diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 22e822253f..673cf3a740 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -31,12 +31,12 @@ #ifndef HTTPREQUEST_H #define HTTPREQUEST_H -#include "core/io/file_access.h" #include "core/io/http_client.h" #include "core/os/thread.h" #include "core/templates/safe_refcount.h" -#include "node.h" -#include "scene/main/timer.h" +#include "scene/main/node.h" + +class Timer; class HTTPRequest : public Node { GDCLASS(HTTPRequest, Node); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 420516cbcd..a76b6c91ee 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1346,7 +1346,7 @@ SceneTree::SceneTree() { current_scene = nullptr; const int msaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/msaa", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Fast),4× (Average),8× (Slow),16× (Slower)"))); root->set_msaa(Viewport::MSAA(msaa_mode)); const int ssaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/screen_space_aa", 0); diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index d22a6b2875..9477e300d1 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -30,8 +30,7 @@ #include "shader_globals_override.h" -#include "core/core_string_names.h" -#include "scene/main/window.h" +#include "scene/3d/node_3d.h" #include "scene/scene_string_names.h" StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const { diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h index 2d9c3c76bd..ab4b9de727 100644 --- a/scene/main/shader_globals_override.h +++ b/scene/main/shader_globals_override.h @@ -31,7 +31,7 @@ #ifndef SHADER_GLOBALS_OVERRIDE_H #define SHADER_GLOBALS_OVERRIDE_H -#include "scene/3d/node_3d.h" +#include "scene/main/node.h" class ShaderGlobalsOverride : public Node { GDCLASS(ShaderGlobalsOverride, Node); diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index b5a2a30b3b..9e462eb1c8 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -30,8 +30,6 @@ #include "timer.h" -#include "core/config/engine.h" - void Timer::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 908950a714..b85f1cc0b8 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -30,33 +30,25 @@ #include "viewport.h" -#include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" -#include "core/input/input.h" -#include "core/os/os.h" #include "core/string/translation.h" - +#include "core/templates/pair.h" #include "scene/2d/camera_2d.h" #include "scene/2d/collision_object_2d.h" #include "scene/3d/camera_3d.h" #include "scene/3d/collision_object_3d.h" #include "scene/3d/listener_3d.h" -#include "scene/3d/node_3d.h" #include "scene/3d/world_environment.h" #include "scene/gui/control.h" #include "scene/gui/label.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/panel.h" -#include "scene/gui/panel_container.h" -#include "scene/gui/popup_menu.h" +#include "scene/gui/popup.h" #include "scene/main/canvas_layer.h" -#include "scene/main/timer.h" #include "scene/main/window.h" #include "scene/resources/mesh.h" +#include "scene/resources/text_line.h" +#include "scene/resources/world_2d.h" #include "scene/scene_string_names.h" -#include "servers/display_server.h" -#include "servers/physics_server_2d.h" void ViewportTexture::setup_local_to_scene() { if (vp) { @@ -3601,7 +3593,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled"); ADD_GROUP("Rendering", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"), "set_msaa", "get_msaa"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Fast),4× (Average),8× (Slow),16× (Slower)")), "set_msaa", "get_msaa"); ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 7a25f5aa00..87cfef2e05 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -31,26 +31,23 @@ #ifndef VIEWPORT_H #define VIEWPORT_H -#include "core/math/transform_2d.h" -#include "core/templates/pair.h" #include "scene/main/node.h" #include "scene/resources/texture.h" -#include "scene/resources/world_2d.h" -#include "servers/display_server.h" -#include "servers/rendering_server.h" class Camera3D; -class Camera2D; +class CollisionObject3D; class Listener3D; -class Control; +class World3D; + +class Camera2D; class CanvasItem; class CanvasLayer; -class Panel; +class Control; class Label; -class Timer; -class Viewport; -class CollisionObject3D; class SceneTreeTimer; +class Viewport; +class Window; +class World2D; class ViewportTexture : public Texture2D { GDCLASS(ViewportTexture, Texture2D); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 1f1da7cefb..6995c77b8e 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -31,10 +31,8 @@ #include "window.h" #include "core/debugger/engine_debugger.h" -#include "core/os/keyboard.h" #include "core/string/translation.h" #include "scene/gui/control.h" -#include "scene/resources/font.h" #include "scene/scene_string_names.h" void Window::set_title(const String &p_title) { diff --git a/scene/main/window.h b/scene/main/window.h index 7013694a06..4f31d9cd1f 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -32,10 +32,12 @@ #define WINDOW_H #include "scene/main/viewport.h" -#include "scene/resources/theme.h" -#include "servers/display_server.h" class Control; +class Font; +class StyleBox; +class Theme; + class Window : public Viewport { GDCLASS(Window, Viewport) public: diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 04a533bedb..0c83c57de6 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -557,7 +557,7 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeIntOp); GDREGISTER_CLASS(VisualShaderNodeVectorOp); GDREGISTER_CLASS(VisualShaderNodeColorOp); - GDREGISTER_CLASS(VisualShaderNodeTransformMult); + GDREGISTER_CLASS(VisualShaderNodeTransformOp); GDREGISTER_CLASS(VisualShaderNodeTransformVecMult); GDREGISTER_CLASS(VisualShaderNodeFloatFunc); GDREGISTER_CLASS(VisualShaderNodeIntFunc); @@ -983,6 +983,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarSmoothStep", "VisualShaderNodeSmoothStep"); ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarStep", "VisualShaderNodeStep"); ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp"); ClassDB::add_compatibility_class("World", "World3D"); ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); ClassDB::add_compatibility_class("Light2D", "PointLight2D"); diff --git a/scene/resources/canvas_item_material.cpp b/scene/resources/canvas_item_material.cpp new file mode 100644 index 0000000000..7ba57a6532 --- /dev/null +++ b/scene/resources/canvas_item_material.cpp @@ -0,0 +1,301 @@ +/*************************************************************************/ +/* canvas_item_material.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 "canvas_item_material.h" + +Mutex CanvasItemMaterial::material_mutex; +SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = nullptr; +Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map; +CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = nullptr; + +void CanvasItemMaterial::init_shaders() { + dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); + + shader_names = memnew(ShaderNames); + + shader_names->particles_anim_h_frames = "particles_anim_h_frames"; + shader_names->particles_anim_v_frames = "particles_anim_v_frames"; + shader_names->particles_anim_loop = "particles_anim_loop"; +} + +void CanvasItemMaterial::finish_shaders() { + memdelete(dirty_materials); + memdelete(shader_names); + dirty_materials = nullptr; +} + +void CanvasItemMaterial::_update_shader() { + dirty_materials->remove(&element); + + MaterialKey mk = _compute_key(); + if (mk.key == current_key.key) { + return; //no update required in the end + } + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users == 0) { + //deallocate shader, as it's no longer in use + RS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + } + + current_key = mk; + + if (shader_map.has(mk)) { + RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader); + shader_map[mk].users++; + return; + } + + //must create a shader! + + String code = "shader_type canvas_item;\nrender_mode "; + switch (blend_mode) { + case BLEND_MODE_MIX: + code += "blend_mix"; + break; + case BLEND_MODE_ADD: + code += "blend_add"; + break; + case BLEND_MODE_SUB: + code += "blend_sub"; + break; + case BLEND_MODE_MUL: + code += "blend_mul"; + break; + case BLEND_MODE_PREMULT_ALPHA: + code += "blend_premul_alpha"; + break; + case BLEND_MODE_DISABLED: + code += "blend_disabled"; + break; + } + + switch (light_mode) { + case LIGHT_MODE_NORMAL: + break; + case LIGHT_MODE_UNSHADED: + code += ",unshaded"; + break; + case LIGHT_MODE_LIGHT_ONLY: + code += ",light_only"; + break; + } + + code += ";\n"; + + if (particles_animation) { + code += "uniform int particles_anim_h_frames;\n"; + code += "uniform int particles_anim_v_frames;\n"; + code += "uniform bool particles_anim_loop;\n\n"; + + code += "void vertex() {\n"; + code += " float h_frames = float(particles_anim_h_frames);\n"; + code += " float v_frames = float(particles_anim_v_frames);\n"; + code += " VERTEX.xy /= vec2(h_frames, v_frames);\n"; + code += " float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; + code += " float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; + code += " if (!particles_anim_loop) {\n"; + code += " particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);\n"; + code += " } else {\n"; + code += " particle_frame = mod(particle_frame, particle_total_frames);\n"; + code += " }"; + code += " UV /= vec2(h_frames, v_frames);\n"; + code += " UV += vec2(mod(particle_frame, h_frames) / h_frames, floor(particle_frame / h_frames) / v_frames);\n"; + code += "}\n"; + } + + ShaderData shader_data; + shader_data.shader = RS::get_singleton()->shader_create(); + shader_data.users = 1; + + RS::get_singleton()->shader_set_code(shader_data.shader, code); + + shader_map[mk] = shader_data; + + RS::get_singleton()->material_set_shader(_get_material(), shader_data.shader); +} + +void CanvasItemMaterial::flush_changes() { + MutexLock lock(material_mutex); + + while (dirty_materials->first()) { + dirty_materials->first()->self()->_update_shader(); + } +} + +void CanvasItemMaterial::_queue_shader_change() { + MutexLock lock(material_mutex); + + if (!element.in_list()) { + dirty_materials->add(&element); + } +} + +bool CanvasItemMaterial::_is_shader_dirty() const { + MutexLock lock(material_mutex); + + return element.in_list(); +} + +void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) { + blend_mode = p_blend_mode; + _queue_shader_change(); +} + +CanvasItemMaterial::BlendMode CanvasItemMaterial::get_blend_mode() const { + return blend_mode; +} + +void CanvasItemMaterial::set_light_mode(LightMode p_light_mode) { + light_mode = p_light_mode; + _queue_shader_change(); +} + +CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const { + return light_mode; +} + +void CanvasItemMaterial::set_particles_animation(bool p_particles_anim) { + particles_animation = p_particles_anim; + _queue_shader_change(); + notify_property_list_changed(); +} + +bool CanvasItemMaterial::get_particles_animation() const { + return particles_animation; +} + +void CanvasItemMaterial::set_particles_anim_h_frames(int p_frames) { + particles_anim_h_frames = p_frames; + RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames); +} + +int CanvasItemMaterial::get_particles_anim_h_frames() const { + return particles_anim_h_frames; +} + +void CanvasItemMaterial::set_particles_anim_v_frames(int p_frames) { + particles_anim_v_frames = p_frames; + RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames); +} + +int CanvasItemMaterial::get_particles_anim_v_frames() const { + return particles_anim_v_frames; +} + +void CanvasItemMaterial::set_particles_anim_loop(bool p_loop) { + particles_anim_loop = p_loop; + RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop); +} + +bool CanvasItemMaterial::get_particles_anim_loop() const { + return particles_anim_loop; +} + +void CanvasItemMaterial::_validate_property(PropertyInfo &property) const { + if (property.name.begins_with("particles_anim_") && !particles_animation) { + property.usage = PROPERTY_USAGE_NONE; + } +} + +RID CanvasItemMaterial::get_shader_rid() const { + ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); + return shader_map[current_key].shader; +} + +Shader::Mode CanvasItemMaterial::get_shader_mode() const { + return Shader::MODE_CANVAS_ITEM; +} + +void CanvasItemMaterial::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &CanvasItemMaterial::set_blend_mode); + ClassDB::bind_method(D_METHOD("get_blend_mode"), &CanvasItemMaterial::get_blend_mode); + + ClassDB::bind_method(D_METHOD("set_light_mode", "light_mode"), &CanvasItemMaterial::set_light_mode); + ClassDB::bind_method(D_METHOD("get_light_mode"), &CanvasItemMaterial::get_light_mode); + + ClassDB::bind_method(D_METHOD("set_particles_animation", "particles_anim"), &CanvasItemMaterial::set_particles_animation); + ClassDB::bind_method(D_METHOD("get_particles_animation"), &CanvasItemMaterial::get_particles_animation); + + ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &CanvasItemMaterial::set_particles_anim_h_frames); + ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &CanvasItemMaterial::get_particles_anim_h_frames); + + ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &CanvasItemMaterial::set_particles_anim_v_frames); + ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &CanvasItemMaterial::get_particles_anim_v_frames); + + ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &CanvasItemMaterial::set_particles_anim_loop); + ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &CanvasItemMaterial::get_particles_anim_loop); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply,Premultiplied Alpha"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mode", PROPERTY_HINT_ENUM, "Normal,Unshaded,Light Only"), "set_light_mode", "get_light_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_animation"), "set_particles_animation", "get_particles_animation"); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop"); + + BIND_ENUM_CONSTANT(BLEND_MODE_MIX); + BIND_ENUM_CONSTANT(BLEND_MODE_ADD); + BIND_ENUM_CONSTANT(BLEND_MODE_SUB); + BIND_ENUM_CONSTANT(BLEND_MODE_MUL); + BIND_ENUM_CONSTANT(BLEND_MODE_PREMULT_ALPHA); + + BIND_ENUM_CONSTANT(LIGHT_MODE_NORMAL); + BIND_ENUM_CONSTANT(LIGHT_MODE_UNSHADED); + BIND_ENUM_CONSTANT(LIGHT_MODE_LIGHT_ONLY); +} + +CanvasItemMaterial::CanvasItemMaterial() : + element(this) { + set_particles_anim_h_frames(1); + set_particles_anim_v_frames(1); + set_particles_anim_loop(false); + + current_key.invalid_key = 1; + _queue_shader_change(); +} + +CanvasItemMaterial::~CanvasItemMaterial() { + MutexLock lock(material_mutex); + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users == 0) { + //deallocate shader, as it's no longer in use + RS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + + RS::get_singleton()->material_set_shader(_get_material(), RID()); + } +} diff --git a/scene/resources/canvas_item_material.h b/scene/resources/canvas_item_material.h new file mode 100644 index 0000000000..0a813e0ae5 --- /dev/null +++ b/scene/resources/canvas_item_material.h @@ -0,0 +1,151 @@ +/*************************************************************************/ +/* canvas_item_material.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 CANVAS_ITEM_MATERIAL_H +#define CANVAS_ITEM_MATERIAL_H + +#include "scene/resources/material.h" + +class CanvasItemMaterial : public Material { + GDCLASS(CanvasItemMaterial, Material); + +public: + enum BlendMode { + BLEND_MODE_MIX, + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MUL, + BLEND_MODE_PREMULT_ALPHA, + BLEND_MODE_DISABLED + }; + + enum LightMode { + LIGHT_MODE_NORMAL, + LIGHT_MODE_UNSHADED, + LIGHT_MODE_LIGHT_ONLY + }; + +private: + union MaterialKey { + struct { + uint32_t blend_mode : 4; + uint32_t light_mode : 4; + uint32_t particles_animation : 1; + uint32_t invalid_key : 1; + }; + + uint32_t key = 0; + + bool operator<(const MaterialKey &p_key) const { + return key < p_key.key; + } + }; + + struct ShaderNames { + StringName particles_anim_h_frames; + StringName particles_anim_v_frames; + StringName particles_anim_loop; + }; + + static ShaderNames *shader_names; + + struct ShaderData { + RID shader; + int users = 0; + }; + + static Map<MaterialKey, ShaderData> shader_map; + + MaterialKey current_key; + + _FORCE_INLINE_ MaterialKey _compute_key() const { + MaterialKey mk; + mk.key = 0; + mk.blend_mode = blend_mode; + mk.light_mode = light_mode; + mk.particles_animation = particles_animation; + return mk; + } + + static Mutex material_mutex; + static SelfList<CanvasItemMaterial>::List *dirty_materials; + SelfList<CanvasItemMaterial> element; + + void _update_shader(); + _FORCE_INLINE_ void _queue_shader_change(); + _FORCE_INLINE_ bool _is_shader_dirty() const; + + BlendMode blend_mode = BLEND_MODE_MIX; + LightMode light_mode = LIGHT_MODE_NORMAL; + bool particles_animation = false; + + // Initialized in the constructor. + int particles_anim_h_frames; + int particles_anim_v_frames; + bool particles_anim_loop; + +protected: + static void _bind_methods(); + void _validate_property(PropertyInfo &property) const override; + +public: + void set_blend_mode(BlendMode p_blend_mode); + BlendMode get_blend_mode() const; + + void set_light_mode(LightMode p_light_mode); + LightMode get_light_mode() const; + + void set_particles_animation(bool p_particles_anim); + bool get_particles_animation() const; + + void set_particles_anim_h_frames(int p_frames); + int get_particles_anim_h_frames() const; + void set_particles_anim_v_frames(int p_frames); + int get_particles_anim_v_frames() const; + + void set_particles_anim_loop(bool p_loop); + bool get_particles_anim_loop() const; + + static void init_shaders(); + static void finish_shaders(); + static void flush_changes(); + + virtual RID get_shader_rid() const override; + + virtual Shader::Mode get_shader_mode() const override; + + CanvasItemMaterial(); + virtual ~CanvasItemMaterial(); +}; + +VARIANT_ENUM_CAST(CanvasItemMaterial::BlendMode) +VARIANT_ENUM_CAST(CanvasItemMaterial::LightMode) + +#endif // CANVAS_ITEM_MATERIAL_H diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 2ea55843ad..4ad5f2a506 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2587,7 +2587,10 @@ RID CameraTexture::get_rid() const { if (feed.is_valid()) { return feed->get_texture(which_feed); } else { - return RID(); + if (_texture.is_null()) { + _texture = RenderingServer::get_singleton()->texture_2d_placeholder_create(); + } + return _texture; } } @@ -2643,5 +2646,7 @@ bool CameraTexture::get_camera_active() const { CameraTexture::CameraTexture() {} CameraTexture::~CameraTexture() { - // nothing to do here yet + if (_texture.is_valid()) { + RenderingServer::get_singleton()->free(_texture); + } } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 98aa61138d..2e97c2deb1 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -812,6 +812,7 @@ class CameraTexture : public Texture2D { GDCLASS(CameraTexture, Texture2D); private: + mutable RID _texture; int camera_feed_id = 0; CameraServer::FeedImage which_feed = CameraServer::FEED_RGBA_IMAGE; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index afe0bdfd5c..a8ec78f63e 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -38,7 +38,7 @@ VisualShaderNodeConstant::VisualShaderNodeConstant() { ////////////// Scalar(Float) String VisualShaderNodeFloatConstant::get_caption() const { - return "ScalarFloat"; + return "FloatConstant"; } int VisualShaderNodeFloatConstant::get_input_port_count() const { @@ -97,7 +97,7 @@ VisualShaderNodeFloatConstant::VisualShaderNodeFloatConstant() { ////////////// Scalar(Int) String VisualShaderNodeIntConstant::get_caption() const { - return "ScalarInt"; + return "IntConstant"; } int VisualShaderNodeIntConstant::get_input_port_count() const { @@ -156,7 +156,7 @@ VisualShaderNodeIntConstant::VisualShaderNodeIntConstant() { ////////////// Boolean String VisualShaderNodeBooleanConstant::get_caption() const { - return "Boolean"; + return "BooleanConstant"; } int VisualShaderNodeBooleanConstant::get_input_port_count() const { @@ -215,7 +215,7 @@ VisualShaderNodeBooleanConstant::VisualShaderNodeBooleanConstant() { ////////////// Color String VisualShaderNodeColorConstant::get_caption() const { - return "Color"; + return "ColorConstant"; } int VisualShaderNodeColorConstant::get_input_port_count() const { @@ -285,7 +285,7 @@ VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() { ////////////// Vector String VisualShaderNodeVec3Constant::get_caption() const { - return "Vector"; + return "VectorConstant"; } int VisualShaderNodeVec3Constant::get_input_port_count() const { @@ -344,7 +344,7 @@ VisualShaderNodeVec3Constant::VisualShaderNodeVec3Constant() { ////////////// Transform3D String VisualShaderNodeTransformConstant::get_caption() const { - return "Transform3D"; + return "TransformConstant"; } int VisualShaderNodeTransformConstant::get_input_port_count() const { @@ -1915,76 +1915,96 @@ VisualShaderNodeColorOp::VisualShaderNodeColorOp() { set_input_port_default_value(1, Vector3()); } -////////////// Transform Mult +////////////// Transform Op -String VisualShaderNodeTransformMult::get_caption() const { - return "TransformMult"; +String VisualShaderNodeTransformOp::get_caption() const { + return "TransformOp"; } -int VisualShaderNodeTransformMult::get_input_port_count() const { +int VisualShaderNodeTransformOp::get_input_port_count() const { return 2; } -VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_input_port_type(int p_port) const { +VisualShaderNodeTransformOp::PortType VisualShaderNodeTransformOp::get_input_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } -String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const { +String VisualShaderNodeTransformOp::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } -int VisualShaderNodeTransformMult::get_output_port_count() const { +int VisualShaderNodeTransformOp::get_output_port_count() const { return 1; } -VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_output_port_type(int p_port) const { +VisualShaderNodeTransformOp::PortType VisualShaderNodeTransformOp::get_output_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } -String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const { +String VisualShaderNodeTransformOp::get_output_port_name(int p_port) const { return "mult"; //no output port means the editor will be used as port } -String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - if (op == OP_AxB) { - return " " + p_output_vars[0] + " = " + p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; - } else if (op == OP_BxA) { - return " " + p_output_vars[0] + " = " + p_input_vars[1] + " * " + p_input_vars[0] + ";\n"; - } else if (op == OP_AxB_COMP) { - return " " + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; - } else { - return " " + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[1] + ", " + p_input_vars[0] + ");\n"; +String VisualShaderNodeTransformOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + switch (op) { + case OP_AxB: + return " " + p_output_vars[0] + " = " + p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; + case OP_BxA: + return " " + p_output_vars[0] + " = " + p_input_vars[1] + " * " + p_input_vars[0] + ";\n"; + case OP_AxB_COMP: + return " " + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; + case OP_BxA_COMP: + return " " + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[1] + ", " + p_input_vars[0] + ");\n"; + case OP_ADD: + return " " + p_output_vars[0] + " = " + p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; + case OP_A_MINUS_B: + return " " + p_output_vars[0] + " = " + p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; + case OP_B_MINUS_A: + return " " + p_output_vars[0] + " = " + p_input_vars[1] + " - " + p_input_vars[0] + ";\n"; + case OP_A_DIV_B: + return " " + p_output_vars[0] + " = " + p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; + case OP_B_DIV_A: + return " " + p_output_vars[0] + " = " + p_input_vars[1] + " / " + p_input_vars[0] + ";\n"; + default: + return ""; } } -void VisualShaderNodeTransformMult::set_operator(Operator p_op) { +void VisualShaderNodeTransformOp::set_operator(Operator p_op) { + ERR_FAIL_INDEX(int(p_op), int(OP_LIMITER)); op = p_op; emit_changed(); } -VisualShaderNodeTransformMult::Operator VisualShaderNodeTransformMult::get_operator() const { +VisualShaderNodeTransformOp::Operator VisualShaderNodeTransformOp::get_operator() const { return op; } -Vector<StringName> VisualShaderNodeTransformMult::get_editable_properties() const { +Vector<StringName> VisualShaderNodeTransformOp::get_editable_properties() const { Vector<StringName> props; props.push_back("operator"); return props; } -void VisualShaderNodeTransformMult::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformMult::set_operator); - ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformMult::get_operator); +void VisualShaderNodeTransformOp::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformOp::set_operator); + ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A,A x B(per component),B x A(per component)"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "A x B,B x A,A x B(per component),B x A(per component),A + B,A - B,B - A,A / B,B / A"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_AxB); BIND_ENUM_CONSTANT(OP_BxA); BIND_ENUM_CONSTANT(OP_AxB_COMP); BIND_ENUM_CONSTANT(OP_BxA_COMP); + BIND_ENUM_CONSTANT(OP_ADD); + BIND_ENUM_CONSTANT(OP_A_MINUS_B); + BIND_ENUM_CONSTANT(OP_B_MINUS_A); + BIND_ENUM_CONSTANT(OP_A_DIV_B); + BIND_ENUM_CONSTANT(OP_B_DIV_A); + BIND_ENUM_CONSTANT(OP_LIMITER); } -VisualShaderNodeTransformMult::VisualShaderNodeTransformMult() { +VisualShaderNodeTransformOp::VisualShaderNodeTransformOp() { set_input_port_default_value(0, Transform3D()); set_input_port_default_value(1, Transform3D()); } diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 33a45a4384..99617b46a3 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -696,19 +696,25 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeColorOp::Operator) -/////////////////////////////////////// -/// TRANSFORM-TRANSFORM MULTIPLICATION -/////////////////////////////////////// +//////////////////////////////// +/// TRANSFORM-TRANSFORM OPERATOR +//////////////////////////////// -class VisualShaderNodeTransformMult : public VisualShaderNode { - GDCLASS(VisualShaderNodeTransformMult, VisualShaderNode); +class VisualShaderNodeTransformOp : public VisualShaderNode { + GDCLASS(VisualShaderNodeTransformOp, VisualShaderNode); public: enum Operator { OP_AxB, OP_BxA, OP_AxB_COMP, - OP_BxA_COMP + OP_BxA_COMP, + OP_ADD, + OP_A_MINUS_B, + OP_B_MINUS_A, + OP_A_DIV_B, + OP_B_DIV_A, + OP_LIMITER, }; protected: @@ -734,10 +740,10 @@ public: virtual Vector<StringName> get_editable_properties() const override; - VisualShaderNodeTransformMult(); + VisualShaderNodeTransformOp(); }; -VARIANT_ENUM_CAST(VisualShaderNodeTransformMult::Operator) +VARIANT_ENUM_CAST(VisualShaderNodeTransformOp::Operator) /////////////////////////////////////// /// TRANSFORM-VECTOR MULTIPLICATION diff --git a/servers/camera/camera_feed.cpp b/servers/camera/camera_feed.cpp index 13afc803e4..9f8e8a8106 100644 --- a/servers/camera/camera_feed.cpp +++ b/servers/camera/camera_feed.cpp @@ -138,11 +138,15 @@ RID CameraFeed::get_texture(CameraServer::FeedImage p_which) { CameraFeed::CameraFeed() { // initialize our feed id = CameraServer::get_singleton()->get_free_id(); + base_width = 0; + base_height = 0; name = "???"; active = false; datatype = CameraFeed::FEED_RGB; position = CameraFeed::FEED_UNSPECIFIED; transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); + texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); + texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); } CameraFeed::CameraFeed(String p_name, FeedPosition p_position) { @@ -155,16 +159,14 @@ CameraFeed::CameraFeed(String p_name, FeedPosition p_position) { datatype = CameraFeed::FEED_NOIMAGE; position = p_position; transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); + texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); + texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_placeholder_create(); } CameraFeed::~CameraFeed() { // Free our textures - if (texture[CameraServer::FEED_Y_IMAGE].is_valid()) { - RenderingServer::get_singleton()->free(texture[CameraServer::FEED_Y_IMAGE]); - } - if (texture[CameraServer::FEED_CBCR_IMAGE].is_valid()) { - RenderingServer::get_singleton()->free(texture[CameraServer::FEED_CBCR_IMAGE]); - } + RenderingServer::get_singleton()->free(texture[CameraServer::FEED_Y_IMAGE]); + RenderingServer::get_singleton()->free(texture[CameraServer::FEED_CBCR_IMAGE]); } void CameraFeed::set_RGB_img(const Ref<Image> &p_rgb_img) { @@ -177,12 +179,9 @@ void CameraFeed::set_RGB_img(const Ref<Image> &p_rgb_img) { // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... base_width = new_width; base_height = new_height; - if (texture[CameraServer::FEED_RGBA_IMAGE].is_null()) { - texture[CameraServer::FEED_RGBA_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img); - } else { - RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img); - RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); - } + + RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_rgb_img); + RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); } else { RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_rgb_img); } @@ -201,12 +200,9 @@ void CameraFeed::set_YCbCr_img(const Ref<Image> &p_ycbcr_img) { // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... base_width = new_width; base_height = new_height; - if (texture[CameraServer::FEED_RGBA_IMAGE].is_null()) { - texture[CameraServer::FEED_RGBA_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img); - } else { - RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img); - RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); - } + + RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_ycbcr_img); + RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_RGBA_IMAGE], new_texture); } else { RenderingServer::get_singleton()->texture_2d_update(texture[CameraServer::FEED_RGBA_IMAGE], p_ycbcr_img); } @@ -230,16 +226,11 @@ void CameraFeed::set_YCbCr_imgs(const Ref<Image> &p_y_img, const Ref<Image> &p_c // We're assuming here that our camera image doesn't change around formats etc, allocate the whole lot... base_width = new_y_width; base_height = new_y_height; - if (texture[CameraServer::FEED_Y_IMAGE].is_null()) { - texture[CameraServer::FEED_Y_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_y_img); - } else { + { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_y_img); RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_Y_IMAGE], new_texture); } - - if (texture[CameraServer::FEED_CBCR_IMAGE].is_null()) { - texture[CameraServer::FEED_CBCR_IMAGE] = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img); - } else { + { RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_cbcr_img); RenderingServer::get_singleton()->texture_replace(texture[CameraServer::FEED_CBCR_IMAGE], new_texture); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index fd797b1cab..057d108578 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -2777,7 +2777,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; float bias_scale = li->shadow_transform[j].bias_scale; - light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale; + light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale; light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size; light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale; light_data.shadow_z_range[j] = li->shadow_transform[j].farplane; @@ -2948,14 +2948,10 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.shadow_enabled = true; if (type == RS::LIGHT_SPOT) { - light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0); - float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0; - shadow_texel_size *= light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); - - light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size; + light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0); } else { //omni - light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0; + light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0; float shadow_texel_size = light_instance_get_shadow_texel_size(li->self, p_shadow_atlas); light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 5920444f7a..4a41c66ef3 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -410,14 +410,8 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { vec4 v = vec4(vertex, 1.0); vec4 splane = (omni_lights.data[idx].shadow_matrix * v); - float shadow_len = length(splane.xyz); //need to remember shadow len from here - { - vec3 nofs = normal_interp * omni_lights.data[idx].shadow_normal_bias / omni_lights.data[idx].inv_radius; - nofs *= (1.0 - max(0.0, dot(normalize(light_rel_vec), normalize(normal_interp)))); - v.xyz += nofs; - splane = (omni_lights.data[idx].shadow_matrix * v); - } + float shadow_len = length(splane.xyz); //need to remember shadow len from here float shadow; @@ -526,7 +520,8 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) { splane.xy /= splane.z; splane.xy = splane.xy * 0.5 + 0.5; - splane.z = (shadow_len - omni_lights.data[idx].shadow_bias) * omni_lights.data[idx].inv_radius; + splane.z = shadow_len * omni_lights.data[idx].inv_radius; + splane.z -= omni_lights.data[idx].shadow_bias; splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; splane.w = 1.0; //needed? i think it should be 1 already shadow = sample_pcf_shadow(shadow_atlas, omni_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane); @@ -702,27 +697,17 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { //there is a shadowmap vec4 v = vec4(vertex, 1.0); - v.xyz -= spot_dir * spot_lights.data[idx].shadow_bias; - - float z_norm = dot(spot_dir, -light_rel_vec) * spot_lights.data[idx].inv_radius; - - float depth_bias_scale = 1.0 / (max(0.0001, z_norm)); //the closer to the light origin, the more you have to offset to reach 1px in the map - vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * spot_lights.data[idx].shadow_normal_bias * depth_bias_scale; - normal_bias -= spot_dir * dot(spot_dir, normal_bias); //only XY, no Z - v.xyz += normal_bias; - - //adjust with bias - z_norm = dot(spot_dir, v.xyz - spot_lights.data[idx].position) * spot_lights.data[idx].inv_radius; - float shadow; vec4 splane = (spot_lights.data[idx].shadow_matrix * v); splane /= splane.w; + splane.z -= spot_lights.data[idx].shadow_bias; if (sc_use_light_soft_shadows && spot_lights.data[idx].soft_shadow_size > 0.0) { //soft shadow //find blocker + float z_norm = dot(spot_dir, -light_rel_vec) * spot_lights.data[idx].inv_radius; vec2 shadow_uv = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 6357a6f4c2..4a4976718c 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1955,10 +1955,6 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base); - real_t first_radius = 0.0; - - real_t min_distance_bias_scale = distances[1]; - cull.shadow_count = p_shadow_index + 1; cull.shadows[p_shadow_index].cascade_count = splits; cull.shadows[p_shadow_index].light_instance = light->instance; @@ -2006,8 +2002,8 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in real_t z_min_cam = 0.f; //real_t z_max_cam = 0.f; - real_t bias_scale = 1.0; - real_t aspect_bias_scale = 1.0; + //real_t bias_scale = 1.0; + //real_t aspect_bias_scale = 1.0; //used for culling @@ -2061,12 +2057,6 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in radius *= texture_size / (texture_size - 2.0); //add a texel by each side - if (i == 0) { - first_radius = radius; - } else { - bias_scale = radius / first_radius; - } - z_min_cam = z_vec.dot(center) - radius; { @@ -2110,64 +2100,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in // a pre pass will need to be needed to determine the actual z-near to be used - if (pancake_size > 0) { - z_max = z_vec.dot(center) + radius + pancake_size; - } - - if (aspect != 1.0) { - // if the aspect is different, then the radius will become larger. - // if this happens, then bias needs to be adjusted too, as depth will increase - // to do this, compare the depth of one that would have resulted from a square frustum - - CameraMatrix camera_matrix_square; - if (p_cam_orthogonal) { - Vector2 vp_he = camera_matrix.get_viewport_half_extents(); - if (p_cam_vaspect) { - camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); - } else { - camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); - } - } else { - Vector2 vp_he = camera_matrix.get_viewport_half_extents(); - if (p_cam_vaspect) { - camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); - } else { - camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); - } - } - - Vector3 endpoints_square[8]; // frustum plane endpoints - res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square); - ERR_CONTINUE(!res); - Vector3 center_square; - - for (int j = 0; j < 8; j++) { - center_square += endpoints_square[j]; - } - - center_square /= 8.0; - - real_t radius_square = 0; - - for (int j = 0; j < 8; j++) { - real_t d = center_square.distance_to(endpoints_square[j]); - if (d > radius_square) { - radius_square = d; - } - } - - radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side - - float z_max_square = z_vec.dot(center_square) + radius_square + pancake_size; - - real_t z_min_cam_square = z_vec.dot(center_square) - radius_square; - - aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square); - - // this is not entirely perfect, because the cull-adjusted z-max may be different - // but at least it's warranted that it results in a greater bias, so no acne should be present either way. - // pancaking also helps with this. - } + z_max = z_vec.dot(center) + radius + pancake_size; { CameraMatrix ortho_camera; @@ -2188,7 +2121,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in cull.shadows[p_shadow_index].cascades[i].zfar = z_max - z_min_cam; cull.shadows[p_shadow_index].cascades[i].split = distances[i + 1]; cull.shadows[p_shadow_index].cascades[i].shadow_texel_size = radius * 2.0 / texture_size; - cull.shadows[p_shadow_index].cascades[i].bias_scale = bias_scale * aspect_bias_scale * min_distance_bias_scale; + cull.shadows[p_shadow_index].cascades[i].bias_scale = (z_max - z_min_cam); cull.shadows[p_shadow_index].cascades[i].range_begin = z_max; cull.shadows[p_shadow_index].cascades[i].uv_scale = uv_scale; } diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 6c4fb31efd..222ea9e622 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2828,7 +2828,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF_RST("rendering/textures/default_filters/use_nearest_mipmap_filter", false); GLOBAL_DEF_RST("rendering/textures/default_filters/anisotropic_filtering_level", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/default_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/textures/default_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Faster),4x (Fast),8x (Average),16x (Slow)")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/default_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/textures/default_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Faster),4× (Fast),8× (Average),16× (Slow)"))); GLOBAL_DEF("rendering/camera/depth_of_field/depth_of_field_bokeh_shape", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/camera/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/camera/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slowest)")); |